webwatch:Prime Agent 实时观看 Web APP(2026-08-11)

位置D:\hermes\hsdesign_work\webwatch\(server.py 纯 stdlib SSE + index.html 暗色移动端 UI + start.sh + setup_tailscale.cmd)

访问http://desktop-f9ksppp.tail1b1993.ts.net:8787/?token=<webwatch/config.json 的 token> (手机 Tailscale 内网;token 鉴权,无 token 401;URL 含 token 勿外传)

启动/运维

  • cd /mnt/d/hermes/hsdesign_work/webwatch && ./start.sh start|restart|stop|status|log|urls
  • Tailscale 暴露(Windows 侧):tailscale serve --bg --http=8787 http://localhost:8787(或跑 setup_tailscale.cmd;WSL2 localhost 转发到 WSL 服务)
  • HTTPS(443) 可选但证书申请可能阻塞,未启用;HTTP 走 tailnet 已是 WireGuard 加密

要点:SSE 实时流 + Last-Event-ID 续传;session 切换按钮(点击即切);卡死指示(stale_minutes=10 无事件 → ⚠️ 可能卡死,空闲等待输入也会触发);多 session = 扫描 sessions//.jsonl;prime-agent list 仅作活动状态增强(后台缓存)。

:Windows .cmd 必须 CRLF 编码(LF 会解析错乱);server.py 里 subprocess 调 ip 要用绝对路径 /usr/sbin/ip(nohup 环境 PATH 不全);Chrome headless --virtual-time-budget 遇 fetch 会挂死(截图用 CDP 或不用 vtb)。

2026-08-11 UX 补丁:执行中(working) session 置顶(server.py get_sessions 排序);prime-agent enrichment 需完整路径(nvm bin glob 兜底,且顶层必须 import shutil——原补丁遗漏导致 activity 全 None)。

2026-08-11 滚动跟随修复:autoScroll 去掉 nearBottom 限制(follow 时总是 instant 贴底,tail -f 语义);上翻暂停保留但按钮红闪”已暂停 ✗”+ 浮动”⬇ 回到最新”按钮恢复;滚动监听按方向(向上才暂停)。报告 master-review/WEBWATCH_SCROLL_FIX.md。

2026-08-11 历史/列表优化:历史回放(after=0)改为最近 300 条倒序(最新在前);3 天无消息 session 从列表隐藏(hide_after_days 可配,文件保留)。报告 master-review/WEBWATCH_HISTORY_FIX.md。

2026-08-13 /stats 并入 27123(验收闭环):stats 服务并入 webwatch 同端口 27123(无 token 内网直读),8787 主路径保留(token 保护);独立实测 curl localhost:27123/stats = 200 / 5977B;手机访问 https://desktop-f9ksppp.tail1b1993.ts.net/stats;报告 master-review/WEBWATCH_STATS_FIX.md。⚠️ 27123 = Obsidian Local REST API 同端口——Obsidian 常驻会互斥,届时用 --stats-port 覆盖(无需其他动作)。

2026-08-13 傍晚 Prime Watch 修复(Prime Pro max 执行 + Hermes 独立验收):①显示修复——scan_sessions() 每域只取 mtime 最新 jsonl(旧重跑残留不再显示;session 数 27→12;状态判定零改动)②总览 menu bar 跳动 → overlay 化(.overview position:fixed; inset:0; z-index:60 + 关闭按钮——点总览不挤压布局,实测 navY=0)③system-fix 归档(8/11 早死遗留——早期命名后来统一 system-ops → archive/ 不再显示)。⚠️ Prime Watch「空闲」显示对 CLI 独立模式 session 有延迟(只在启动/完成写状态)——实验运行中显示空闲 ≠ 卡死,以进程/文件 mtime 为准(watch_exp.py 监控兜底)。

2026-08-14 故障排查(tailscale 打不开面板)

  • 三层根因链:① 8787 服务被误伤(重启 Prime supervisor 时)→ 手动拉起;② token 每次重启变化 → 发新链接;③ tailscale 虚拟网卡流量到不了 WSL(WSL 只转发 localhost)→ 加 netsh portproxy 转发(tailscale IP:8787 → localhost:8787) 修复
  • 正确链接是 HTTPS serve 无端口https://desktop-f9ksppp.tail1b1993.ts.net/?token=...(PWA install 需要 HTTPS;http+端口 会出现左上角感叹号 + 无法 install)
  • 手机打不开先查手机 Tailscale 状态(显示 ”-” = 掉线);PC 端同理
  • 待办(webwatch 面板修复时做):token 持久化(重启不变)+ 8787 服务守护(挂了自动拉起)

2026-08-16 凌晨(停滞监控体系 + 实时队列 + SSO 同源)

  • 停滞警示(8/15 深夜派 PI 上线):STALE_MIN = 10(index.html 常量,459-460 行)→ 进行中任务最后活动 >10 分钟 → 红框/红底 + ⚠ 停滞 N 分钟徽标 + 置顶;不误标 done/daemon;顺手修 st→state 排序 bug;备份 index.html.bak-20260816
  • Hermes 侧 watchdog 双保险:cron 239b9a05ed72「PI 任务停滞巡检」每 10 分钟跑 D:\hermes\scripts\watch_pi_stall.py;停滞 >12 分钟推送到手机,正常静默(MSYS 路径坑:直接跑会变成 D:\\d\\hermes\\...,要用 Windows 全路径 python D:\hermes\scripts\watch_pi_stall.py
  • /api/domains 实时队列 endpoint(8/15 深夜修复”总览显示历史任务”bug):读 bench/domains/<域>/RUNNING.lock + queue/ → 面板按域显示「当前:xxx」+ 待办 + 空闲灰点;历史 jsonl 区默认折叠;服务重启 pid 66309
  • SSO 同源事实:master app SSO_SECRET 与 webwatch .sso_secret 64 字节完全相同(同一密钥体系)——未来跨 app 代理/认证桥可直接用自家 secret 现签票据(方案 A 分屏已验证可行)
  • 运维坑:域队列 enqueue 复制而非移动 → 任务完成后清 queue/ 残留,否则重复派发(详见 agent-task-routing2026-08-16 清晨(Hermes 监控体系 + 实时卡片 + 语义修正,8 任务连跑全 PI max)
  • ① Hermes 监控卡(hermes_monitor):默认 filter agentSel=['pi','hermes']、琥珀色 #f2c14e/api/hermes 路由读 state.db(只读)、cron 停滞 >10min 标红置顶;pid 84174
  • ② PI 卡实时任务(card realtime):server.py get_pi() 注入 realtimeDomain/Running/Task(读 /api/domains RUNNING.lock,get_domains()_scan_lock 外调用避免嵌套死锁);卡片「实时:xxx」紫标 /「状态:空闲」灰标;pid 85413
  • ③ Hermes 卡语义(hermes_semantics):主会话空闲不红闪不置顶(空闲≠卡机);cron「运行中」= 最近 5 分钟有消息(HERMES_CRON_RUNNING_SECONDS=5*60),其余「最近运行 X 前」;删 hermesStaleMins();pid 85708
  • ④ 最后消息摘要(hermes_summary):_msg_summary(content, limit=40) 折叠空白+40 字截断;Hermes 卡主显示「最后:<摘要>」,静态标题退副位灰字;pid 87552
  • ⑤ 健康状态三态(health_status):_hermes_proc_alive() = PowerShell Get-Process hermes(实测进程名 hermes.exe PID 3964,30s 缓存);_pi_proc_alive(domain) = WSL pgrep -f "session-id <域>";🟢运行中/⚪空闲/🔴进程离线;PI 停滞去误报——进程已退出 = 「完成(待解锁)」绿中性不标红(+ lock 残留提示),进程活+停写 = 真卡死仍红;pid 89157
  • ⑥ 旧标题三处全消(hide_stale_title):Hermes 卡副显示 → 「Telegram 主会话」、总览条目 → 最后消息摘要、时间线行 → 「Hermes · Telegram 主会话」;pid 90068
  • ⑦ 总览排序三规则(overview_sort):Hermes 主会话第一 → 进行中(state==='busy' 有 RUNNING.lock)优先 → 其余按 lastActivity 降序(tie-break 字母序稳定);域行 meta 加「最后活动 X」;fetchPi 补调 renderOverview 修首帧竞态;pid 92530
  • ⑧ PI 卡域名+相关任务(card_domain):DOMAIN_DISPLAY 映射(WebWatch/Master App/Portal/HS Design/Life Map/Research/WhatsApp/System Ops/Misc);done_recent = done/ 最近 3 任务 friendly 化;卡片显示最近 2 个相关任务 + has_more →「查看更多 ›」(点开总览);pid 93175
  • ⑨ Prime section 移除(remove_prime):019ffb45 0 残留;prime daemon 已杀(见 PrimeAgent_Graph
  • 服务现役 pid:93175+(多轮重启后);SSO .sso_secret 64B 不变
  • 流程纪律(06:34):完成通知 = 立即验收 → finish → 自动派发下一个,不等用户催

2026-08-19 移动端「PI 卡不显示」真根因修复(第二轮,mobile view 验证)

  • 根因scan_interval 2s 太激进——移动端 funnel 路径每次请求触发全量扫描(服务端串行排队 0.6–2.8s)+ 前端 15s 超时过早中断 + 9 请求同时发射 → 慢请求在 Tab 网络路径失败 → PI 数据加载不出(桌面 Chrome 正常=时间线差异,非 agent 丢失)
  • 修复 3 处:扫描缓存 2s→5s(pi 响应 2.8s→0.13s)/ 前端超时 15s→30s / 轮询错峰 250ms
  • 验证:CDP 移动模拟(Android UA + 375px)+ 真实 funnel URL(不屏蔽 API)→ PI 卡 9 张 + 时间线 15 会话全显示、首屏 5.3s、375px 无溢出;桌面回归 13/13 PASS;待用户 Tab 强刷实测
  • 上轮前端兜底仍在:数据加载失败显示「⚠ 加载失败 — 立即重试」按钮

2026-08-22 凌晨(「网络问题」真根因:state.db 读取竞态,已派 PI)

  • 现象:面板「网络有问题」= 前端对后端 401 的通用伪装文案(token 缺失/无效时);带 token 实测 api/pi、api/overview、api/hermes 全 200;SSO cookie 7 天 TTL(8/19 11:33 最后签发)
  • 真根因:WSL 读 /mnt/d/hermes/state.db(3.3GB)用 immutable 连接模式 → 与 Windows 侧 Hermes 写入竞态 → database disk image is malformed(8/20 12:33 起,webwatch.log 有记录);WSL mode=ro 不带 immutable 实测同样 disk I/O error
  • state.db 本身完好(PRAGMA integrity_check = ok,3.3GB 全扫)——库没坏,是读法不对
  • 修复任务书 state_db_read_fix 已派 webwatch 域 PI(server.py 两处读库代码定位写清);系统类修复默认派 PI,主 agent 不亲手改(用户 8/22 00:03 第二次提醒)

2026-08-22 state.db 读取修复(Windows ro 桥,PI webwatch 域)

  • 故障:8/20 起 hermes state.db 查询失败: database disk image is malformed(8/20 12:33、8/21 00:01 等)→ 前端渲染成「网络问题」文案(误导)
  • 根因:WSL 读 /mnt/d/hermes/state.db(3.3GB)用 mode=ro&immutable=1 → immutable 跳过 WAL 检查,与 Windows 侧 Hermes 活跃 checkpoint(~40s 一次)竞态 → 读到 torn 页 → malformed;WSL mode=ro(不带 immutable)实测也 disk I/O error(drvfs shm 坑);state.db 本身 integrity ok(3.3GB 全扫通过)
  • 修复:Windows 原生 ro 桥 scripts/hermes_read.py(替代 WSL 读取);git 818dc10;验收:/api/hermes 5 连 healthy + 压力 15/15、10 分钟 malformed 零新增(8/8)、verify_ww.sh 13/13、11 API 全 200
  • ⚠️ 未闭环:手机 PWA 时间线区仍现「部分数据加载失败」横幅(服务端 17 端点全 200)→ 疑似 PWA 缓存;PWA 无硬刷新,清站点数据代替;等用户截图点名源
  • 排查技巧沉淀:模拟 portal SSO 全链(票据→ww_token cookie→api 200);截图用 OpenClaw CDP(headless Chrome --virtual-time-budget 遇 fetch 挂死);MSYS 路径坑:/d/... 会被转 D:\d\... 用原生 Windows 路径

2026-08-23(晚间收尾场)公网入口定案 = CF Tunnel + 手机端根治

  • 公网访问(首选)https://webwatch.hsdesign.biz(Cloudflare Tunnel → 本机 8787;App Portal 卡片 → SSO 一次过;任何网络免 Tailscale)——funnel 手机 TLS 断(移动网络 TLS decode error + IPv6 优先;Windows 8787 只绑 127.0.0.1 外部不可达)作废;备胎:tailscale serve + funnel(内网)
  • CF zone 通配 Workers Route(*.hsdesign.biz → hsdesign-saas)劫持子域 → 精确 route 透传后才通(否则全 502/404)
  • 性能:zstd 冷解压 4s → 3s 缓存 + 后台预热(0.02s;localhost 0.21s);hermes bridge 根因 = GBK 编码(commit fcfff44
  • 前端:SW 版本自动注入(服务每次重启=新 SW 版本,旧缓存自动清理——用户零操作);HTML no-cache + network-first
  • 运维:tunnel 启动器含 WSL 唤醒(Windows 重启后自动拉起 WSL→8787→tunnel);单实例检测 + 计划任务自启;手机 SSH 测试通道:-p 8022 [email protected](S23 Ultra)
  • 新工具:scripts/popup_watcher.py(弹窗捕获:2s 枚举窗口 → 4s 落盘 D:\hermes\hsdesign_work\cache\popups\popup_*.jsonl → 分析短暂窗口;ctypes 直取进程名,勿用 tasklist 子进程)