- 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 工具分层)
9.5 KiB
摘除 STF 迁移计划
状态:历史迁移记录(2026-08)。 本文档为当时摘除 STF 的计划与进度,不代表现状。 截至 dev HEAD,代码已不再依赖 STF(
core/stf_client.py等已删,config.pySTF 键标注废弃)。 "当前实现"以 doc/ARCHITECTURE.md / doc/DEVELOPMENT.md 为准; 220 侧 STF 容器是否已docker stop见下文"待人工确认",需人工核实。
背景:全舰队设备为 Tailscale IP:5555 直连(adb key 沿用 STF 的),单实例部署。 STF 当前仅提供:occupy/release 互斥、present+ready 健康信号、设备池清单(与 220 的 connect_devices.sh 双维护)、remoteConnect 桥接(IP:port 已禁用)、网页看屏。 任务本体跑 uiautomator2(atx-agent),与 STF agent(jp.co.cyberagent.stf)无关。
摘除收益:告别 agent 安装死锁(MIUI 弹窗)、STF 容器重启风险、occupy 冲突悬空; 调度直接基于 adb 真实现状。风险点:多实例互斥(当前单实例无此需求,见阶段 3)。
已确认的决策(2026-08-17)
- 设备清单放本地 SQLite(data/users.db 新增 devices 表),220 的 connect_devices.sh 退役(其"每 5 分钟补连"职责由平台定时器 + SSH 兜底接管,或直接依赖 adb 重试)
- USB 有线设备保留支持——当前舰队 0 台 USB(全 IP:5555),但能力要保留。
实施中发现 220 的 adb 容器是 host 网络模式、5037 已监听所有网卡(含 Tailscale
100.100.10.1),无需改动 220 任何配置。平台用
adb -H 100.100.10.1 -P 5037和adbutils.AdbClient(host=..., port=5037)(u2 底层)驱动远端 USB 设备; 本机 USB 设备照旧走本地 adb。已验证(阶段 2 完成) - 网页远程看屏——原计划 ws-scrcpy 不在 npm 分发(仅 GitHub,国内下载不可靠), 改自建:MJPEG 流(u2/atx-agent minicap 截图,~5fps,实测 0.19s/帧)+ u2 触控 (tap/swipe/key/text),管理页新子分栏,零新依赖(阶段 2 完成)
迁移难度与程度评估(2026-08-17)
代码量
| 项 | 量级 |
|---|---|
删除 core/stf_client.py 及引用 |
~250 行 |
新增 core/device_pool.py(清单+在线状态) |
~150 行 |
| 新增 devices 表 CRUD(复用现有 SQLite 基建) | ~120 行 |
修改 task_manager(resolve_serials/调度) |
~120 行 |
重写 device_worker.STFDevice(去 occupy/release) |
~80 行 |
修改 web_server 约 8 处调用点 |
~60 行 |
改造 stf_device_mgmt(SSH 脚本 → SQLite 管理) |
~100 行 |
| 前端 6 个文件文案/组件 | ~80 行 |
净效果:-600 行 / +400 行 / 改 ~300 行,集中在 task_manager 与 device_worker 两个核心文件。
分项难度(单人)
| 模块 | 难度 | 估算 | 关键点 |
|---|---|---|---|
| 设备池 SQLite + device_pool | 低 | 0.5-1 天 | 表结构 + CRUD + 管理页改数据源 |
| 调度替换 | 中 | 1-2 天 | 内存锁已有(_running[serial]),换数据源 + 对照验证 |
| web_server 调用点 | 低 | 0.5 天 | 8 处机械替换 |
| USB 支持 | 中 | 1 天 | 220 容器发端口 + adb_helper 支持 -H/-P + u2 远程 server;需一台真机验证 |
| 网页看屏(ws-scrcpy) | 中 | 0.5-1 天 | 独立 Node 服务 + 内嵌页 + 认证联动 |
| 界面清理 | 低 | 0.5 天 | 文案/按钮/列 |
| 回归验证 | 中 | 1 天 | 调度/抢占/重试/离线跳过/亮屏/剪贴板/终端/看屏 |
总计约 4-6 人日,分 4 个 commit 阶段,每阶段可独立回滚。
风险
- 中:USB 真机方案当前无设备可验,落地时需借一台 USB 设备
- 低:离线跳过判定语义变化(STF 状态 → adb 状态),个别边界行为可能微变,需对照
- 低:唯一动 220 的地方 = adb 容器发布 5037 端口(一次性)
- 低:ws-scrcpy 是新增 Node 依赖,需评估其维护性与内存占用(可先试用再定)
实施顺序(调整后)
- 阶段 0:SQLite 设备表 +
core/device_pool.py(纯新增,STF 照常跑) - 阶段 1:调度/生命周期替换(STF 保留运行对照验证)
- 阶段 2:USB 远程 adb server 打通 + ws-scrcpy 看屏部署
- 阶段 3:界面清理 + 220 停 STF 容器(
docker stop不删,可回滚)
阶段 0:新建设备池模块(纯新增,不改行为)
新建 core/device_pool.py + devices 表(data/users.db):
- devices 表:serial(主键)、name、enabled、note、created_at;管理页增删改
list_configured()— 读 SQLite devices 表(取代 SSH 读 220 脚本)list_online()— 本机adb devices中 state=device 的设备(实时)is_online(serial)— 在 list_online 中;可选adb -s get-state兜底(带超时)list_ready()— list_configured 与 list_online 的交集(取代 STF list_free_devices)- 全模块不 connect/不 kill-server/disconnect,遵守既有红线
- 迁移脚本:现有 8 台设备从 STF 池导入 devices 表
产出:core/device_pool.py + doc/ARCHITECTURE.md 设备章节初稿 + 数据迁移脚本。
阶段 1:替换调度与生命周期(STF 保留运行,可对照验证)
| 位置 | 现状 | 改为 |
|---|---|---|
task_manager.resolve_serials (145-183) |
stf.list_free_devices() / list_all_devices() |
device_pool.list_ready();preempt 模式 = 全部 list_online |
resolve_serials skip_offline 过滤 (166-183) |
STF present/ready 判定 | device_pool.is_online();跳过原因文案"离线/未连接" |
device_worker.STFDevice.acquire (45-70) |
stf.occupy() + 直连/桥接 |
去掉 occupy(互斥由 _running[serial] 负责);USB 桥接保留到阶段 2(避免迁移期 USB 断档,阶段 2 换成 220 adb server);保留 adb_connect 重试 + 2s 等待 |
STFDevice.release (78-93) |
stf.release() |
置空(仅保留 USB 隧道断开) |
STFDevice._pick_free (72-76) |
list_free_devices |
device_pool.list_ready() |
_ForegroundScanner (234-386) |
list_all_devices / list_my_devices / remote_connect |
device_pool.list_online();桥接分支删除 |
web_server.api_device_screen_all (646) |
STF present 列表 | device_pool.list_online() |
web_server 设备列表 (924 / 1011 / 1079) |
STF 池合并 | SQLite devices 表 + 本地 adb(_merged_device_list 改数据源,保留 stf_not_ready 状态的等价物"未连接") |
web_server.api_release (740) / 启动清理 (1581) |
release_all_mine | 删除或改为清理本实例 _running 状态(重启本就清零) |
验证清单(阶段 1 完成后全跑一遍):
- 任务调度(serial/group/all 三种模式)+ 抢占/归还 + 重试 + 离线跳过
- 一键亮屏/息屏、剪贴板注入、应用版本查询、维护终端设备列表
- 前台 App 扫描
- 对照 STF 状态确认无行为差异
阶段 2:USB 打通 + 网页看屏(阶段 1 稳定运行 ≥ 3 天后)
- USB 远程 adb server:
- 220 侧一次性改动:adb 容器发布 5037 端口(
docker run -p 5037:5037或 iptables), Tailscale 可达 core/adb_helper._adb支持-H <220-tailscale-ip> -P 5037(仅 USB 序列号设备)- u2 连接:USB 设备走
adbutils.Adb(host=220_ip, port=5037)→u2.Device(dev)(已验证 u2 3.7.0 底层 adbutils 支持远程 adb server) - 本机 USB 设备照旧走本地 adb,零改动
- 需要一台真机 USB 设备验证
- 220 侧一次性改动:adb 容器发布 5037 端口(
- 网页看屏(ws-scrcpy):
- 平台机部署 ws-scrcpy(Node 服务,WebRTC 低延迟流 + 触控),本机 adb 为数据源
- 管理员页面新增「远程看屏」入口,iframe 内嵌;登录态复用(ws-scrcpy 自身鉴权 走 token 或仅内网/Tailscale 暴露)
- 备选方案(若 ws-scrcpy 试用不达标):自建 minicap JPEG 流 + u2 触控注入(2-3 天)
阶段 3:界面清理 + STF 停用(已完成代码部分,2026-08-18)
✅ 已完成的代码部分(commit a5ce57b,-956 行):
- 删「一键重启 STF 容器」区块、设备表 STF 占用列、强制释放占用按钮
- 删「STF 设备管理」子分栏(设备池管理面板接管)+ 卸载/检查 STF agent 按钮
- 删除
core/stf_client.py、core/stf_device_mgmt.py及全部引用(含 web_server 全部 STF API、启动残留清理、设备池首导 seed) - 错误类(STFError/DeviceOfflineError)迁入
core/device_worker.py;create_worker/BaseWorker去掉 stf 参数;stf_occupied字段全链路移除 - 文案清理(tools/apps/editor/monitor)+
config.pySTF/SSH 配置标注废弃 - 文档更新(ARCHITECTURE/DEPLOY)
⏳ 待人工确认的最后一步(220 侧):
- 停 STF 容器(
docker stop stf,不删除,可docker start stf回滚) - 保留 adb 容器(host 网络 5037,USB 设备远程驱动依赖它); connect_devices.sh cron 可留可退役(对网络设备补连已无必要,无害)
- 停容器前请确认:任务调度/看屏/设备池管理已稳定运行 ≥1 天
阶段 4(可选,未来多实例/多机时)
跨实例互斥:SQLite 行锁替代 occupy——
UPDATE device_locks SET owner=?, ts=? WHERE serial=? AND (owner IS NULL OR owner=?)
回滚方式
- 每个阶段一个 commit,问题可整体
git revert;STF 阶段 3 前一直运行,随时回切 - 阶段 3 的 STF 容器是
docker stop而非删除,回滚 =git revert+docker start stf - 每个阶段 commit 后在 dev 观察 ≥3 天再进下一阶段