离开工位的时候,代理还在跑。回来之后,浏览器里多了一堆页面,历史记录把它们和你自己点开的混在一起,分不清哪些是程序打开的。这是 ccdeck 作者遇到的一个问题:他没法回答一个简单的问题——我不在的时候,浏览器里有没有东西自己开了页面,开的是哪些。
![]()
答案藏在 Chromium 的历史数据库里。每一次访问都带一个 transition 值,记录你是怎么到那个页面的——点链接、敲地址,诸如此类。其中一个限定符 FROM_API(0x08000000,第 27 位)用来标记来自外部应用的特定导航。
这个标记的范围比“用了 API”要窄得多,得说清楚哪些算、哪些不算:
- 会被标记:通过 DevTools 协议的 Page.navigate 发起的导航,或者扩展用 chrome.tabs.update 带 URL 打开。
- 不会被标记:通过 Target.createTarget 或 chrome.tabs.create 直接以某个 URL 打开的标签页,程序点击的链接,以及经 open 或 xdg-open 传入的地址。
Browser Watch 检测的就是这一位,而不是试图从 URL 反推意图。分类代码和对应的 Chromium 源码引用把这个区别写在了文档里。这个信号只覆盖一部分浏览器活动,不是完整的自动化检测器。
所以,当某个时间段里没人手动打开页面,却出现一串 FROM_API 访问,这件事就值得告诉浏览器的主人。这就是 Browser Watch 的全部思路——ccdeck 里的一个面板。它没有空闲计时器,也不监听键盘,只看历史记录。
点工具栏上的 Browser watch 眼睛图标,或者按 B。徽标会统计你上次关闭面板以来开始的“事件”数量。左栏显示正在监视哪些浏览器配置文件,以及自 deck 启动以来程序在每个配置里打开了多少页面。右侧的 Findings 列出无人浏览时程序打开的东西。
每张卡片是一个事件:一个浏览器里的一个主机。点开它,会完整列出程序打开的每一个地址和时间,包括 ? 后面和 # 后面的部分。
什么算“离开”?一个页面只有在带 FROM_API 标记、并且该配置在它前后各一段“无人浏览”时间内没有任何未标记访问时,才被计入。这个时间默认 15 分钟。时间没到之前,卡片会显示 provisional:一次未标记访问仍可能把它撤回,包括不设标记的自动化访问。只要相邻两个页面间隔不到 15 分钟,它们就留在同一个事件里。deck 自己的标签页永远不会被报告。
一条发现不是判决。它通常就是你自己的代理在按你说的做。监视告诉你程序打开了什么,判断权在你。核对过的卡片点 ×,它就会永久离开列表。
发现之后做什么,可以在页脚齿轮里设:
- Nobody browsing for:1、5、15、30 或 60 分钟。时间越短,抓到的越多,也包括更多你自己的操作。
- 发现时:通知我(默认)、关闭标签页(仅 macOS),或退出浏览器。在 Linux 上只退出持有该配置的浏览器,判断不出是哪个进程时什么也不做,比如 Flatpak 版 Brave。
反应有边界。关闭标签页只是清理,页面那时已经加载完了;退出会停掉那个浏览器进程,但拦不住程序再把它拉起来。反应也不是即时的:每个新事件只触发一次,在它的第一个页面不再是 provisional 之后——按默认 15 分钟算,大约是那个页面之后 16 分钟,在下一次检查时。每次反应还会弹一条标题为“Browser watch”的系统通知,除非 deck 启动时带了 AGENTS_DECK_NO_NOTIFY=1;设置里的“关闭时通知”开关改不了这一点。多个 deck 同时运行时,只有端口最低的那个记录事件并做出反应。
这个面板读你的浏览历史,所以清单得说精确。它默认开启,页脚的 Watch browser activity 开关初始就是开的。
它读什么:它能找到的每个 Chromium 配置的历史——Google Chrome、Chromium、Brave、Microsoft Edge、Vivaldi,以及 macOS 上的 Arc。Firefox 和 Safari 不读。只读 deck 启动之后的访问,已有历史不会被扫描、归档或展示。为了不打开活动数据库就能查询,deck 会把 History 文件复制到 browser-watch/staging/ 下的私有文件夹,只在文件变化时复制,跑一次查询,然后删掉副本。至于 Remote control 那一行(某个配置里 Claude in Chrome 是否在线),它还会读 hosts 文件和装有 Claude in Chrome 的配置设置,并在面板打开且装了 dig 时,大约每 30 秒查一次中继的名字。那次 DNS 查询就是监视唯一的对外网络请求,浏览历史不会随它发出去。
它永远不读:cookie、保存的密码、页面内容。
监视开启期间它保留什么:
- ~/.claude/agent-dag/browser-watch/watch.log:每个被标记的事件及其下所有地址,在不再是 provisional 之后写入。涨到 2 MiB 时滚动到 watch.log.1。macOS 或 Linux 上可以 tail -f 看。
- 旁边的 state.json:最多 500 个事件、你的忽略记录和设置。
- 设了 CLAUDE_CONFIG_DIR 时两者都跟着走;CCDECK_HOME 不会移动它们。
只保留被标记的事件,从不保留你自己的浏览。Live activity 列表会计数你自己的页面,但不写下来。历史里的任何东西都不会离开这台机器。齿轮下的“Browser Watch 能访问什么”会在面板里重复这份清单。监视关闭时,后台检查完全不读浏览器,也不保留新东西;打开面板仍然实时读取——那是你在看——并且只显示这个 deck 启动以来看到的内容。
它做不到的事也得摆出来:
- 不是实时防护。deck 页面打开时每 5 分钟读一次历史,面板本身打开时每 10 秒读一次;标题栏的循环箭头会再读一次,最多每分钟一次。检查在页面里跑,没有 deck 页面打开(浏览器标签页或桌面应用窗口)时,什么都不检查。
- 看不全浏览器。Firefox 和 Safari 不读,从独立文件夹运行的浏览器也不读,比如自动化工具的一次性配置。
- 分不清意图,也抓不全自动化。被标记的访问可能是你自己的代理、扩展或脚本;未标记的自动化对检测器不可见,还可能取消附近的一条发现。
- 需要 SQLite 读取器:Node.js 22.13 或更新版本,或者 PATH 里有 sqlite3 命令。macOS 自带 sqlite3,Windows 没有。
- 可能漏掉你就在旁边的情况。如果你在那段安静时间内手动在该配置里开过页面,紧挨着的程序页面就不算。把时间设成 1 或 5 分钟能抓到更多。
看发现的时候,记得带上它的限制。有 deck 页面打开时按 B 就能查看 Browser Watch。一条发现意味着某次被标记的导航满足了安静窗口规则;列表为空,并不能证明没有程序用过浏览器。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.