跳到正文
DEV Community· Bargan Constantin·· 3 小時前AI 評分59

ccdeck Browser Watch 如何從 Chromium 瀏覽記錄找出部分自動化瀏覽

Did an AI agent drive your browser while you were away? Chromium already knows

AI 導讀

ccdeck 的 Browser Watch 讀取 Chromium 瀏覽記錄,利用 FROM_API 標記和閒置時間條件,找出部分由程式開啟的頁面。預設需在頁面前後各有 15 分鐘沒有未標記的瀏覽記錄,事件才會確認;功能不讀取 cookies、已儲存密碼或頁面內容,並只在本機保存標記事件。它並非即時防護,不讀取 Firefox 或 Safari,也無法識別未帶標記的自動化瀏覽。

正文

I build ccdeck. The step-by-step version of this post, with every setting, is at ccdeck.dev/guides/browser-watch.

The question I could not answer

More of my agents can drive a browser now: through an extension or through the browser's debugging protocol. Most of the time that is exactly what I asked for. But I leave agents running when I step away, and when I came back I had no way to answer a simple question:

Did something open pages in my browser while I was not there — and which ones?

The browser's history mixes those pages in with everything I opened myself. Some automated navigations carry a flag that can help separate them.


The mark Chromium already writes

Every visit in a Chromium history database has a transition value that says how you got there — a link, a typed address, and so on. One qualifier, FROM_API (0x08000000, bit 27), marks certain navigations from an external application.

The distinction is narrower than “an API was used”:

  • Marked: a navigation through the DevTools protocol’s Page.navigate, or an extension’s chrome.tabs.update with a URL.
  • Unmarked: a tab opened directly at a URL through Target.createTarget or chrome.tabs.create, a link clicked by a program, or an address passed through open or xdg-open.

Browser Watch tests that bit rather than trying to infer intent from a URL. The classification code and its Chromium source references document the distinction. This signal covers some browser activity; it is not a complete automation detector.

So a run of FROM_API visits, in a stretch when nobody opened a page by hand in that profile, is worth showing to the person who owns the browser. That is the whole idea behind Browser Watch, a panel in ccdeck.

It has no idle timer and does not watch your keyboard. It goes by the history alone.


What you see

Click the Browser watch eye in the toolbar, or press B. A badge counts the episodes that began since you last closed the panel.

The Browser watch eye in the toolbar with a badge reading 2 and its tooltip
Demo data.

The left column shows which browser profiles are watched, and how many pages a program opened in each since the deck started. On the right, Findings lists what a program opened while nobody was browsing.

The Browser watch panel: activity per browser on the left, two findings on the right (docs.example.com, 4 pages; shop.example.com, 1 page), and the Watch browser activity switch on in the footer
Demo data.

Each card is one episode: one host in one browser. Click it to list every address the program opened, in full, with its time — the part after ? and the part after # included.

A finding opened: docs.example.com with its four addresses, one ending in ?tab=headers and one in #errors
Demo data.

What counts as "away"

A page counts only when it carries the FROM_API mark and there are no unmarked visits in that profile for the Nobody browsing for time — 15 minutes by default — before and after it. Until that time has passed, the card says provisional: an unmarked visit can still withdraw it, including one made by automation that does not set the flag. Pages stay in one episode while no two in a row are 15 minutes or more apart. The deck never reports its own tabs.

A finding is not a verdict. It is usually your own agent doing what you asked. The watch tells you what a program opened; the judgement is yours. Click × on a card you have checked and it leaves the list for good.


What it does when it finds one

Click the gear in the footer:

  • Nobody browsing for: 1, 5, 15, 30 or 60 minutes. A shorter time catches more, including more of your own work.
  • When it finds one: notify me (the default), close the tab (macOS only), or quit the browser. On Linux it quits only the browser holding that profile, and does nothing when it cannot tell which process that is, as with a Flatpak Brave.

The settings: Nobody browsing for 15 min, When it finds one: notify me
Demo data. This deck runs on Linux, so the menu holds notify me and quit the browser.

Reaction limits:

  • Closing the tab is only cleanup. The page has already loaded by then. Quitting stops that browser process; it does not prevent a program from launching it again.
  • It is not instant. A reaction runs once per new episode, after its first page is no longer provisional — with the default 15 minutes, about 16 minutes after that page, at the next check. Every reaction also raises a system notification titled "Browser watch", unless the deck was started with AGENTS_DECK_NO_NOTIFY=1; the Notifications while closed switch in Settings does not change that. When several decks are running, only the one on the lowest port records episodes and reacts.

Exactly what it reads, and what it keeps

This panel reads your browsing history, so here is the precise list.

It is on by default. The Watch browser activity switch in the panel's footer starts on.

What it reads:

  • The history of every Chromium profile it finds: Google Chrome, Chromium, Brave, Microsoft Edge and Vivaldi, and Arc on macOS. Firefox and Safari are not read.
  • Only visits made after the deck started. Your existing history is not swept, archived or shown.
  • To query the history without opening the live database, the deck copies the History file into a private folder under browser-watch/staging/, only when it changed, runs one query, and deletes the copy.
  • For the Remote control line (whether Claude in Chrome is live in a profile), it also reads the hosts file and the settings of profiles with Claude in Chrome, and, while the panel is open and dig is installed, looks up the relay's name about every 30 seconds. That DNS lookup is the watch’s outgoing network request; browsing history is not sent with it.

What it never reads: cookies, saved passwords, page contents.

What it keeps, while the watch is on:

  • ~/.claude/agent-dag/browser-watch/watch.log — each flagged episode with every address under it, once it is no longer provisional. It rolls over to watch.log.1 at 2 MiB. On macOS or Linux, tail -f it.
  • state.json beside it — up to 500 episodes, your dismissals and the settings.
  • Both move under CLAUDE_CONFIG_DIR when you set it; CCDECK_HOME does not move them.

Only flagged episodes are kept, never your own browsing. The Live activity list counts your own pages without writing them down. And nothing from your history leaves the machine. What Browser Watch can access, under the gear, repeats this list in the panel itself.

When the watch is off, the background check reads no browser at all and nothing new is kept. Opening the panel still reads live — that is you looking — and shows only what this deck has seen since it started.


What it does not do

  • It is not real-time protection. It reads the history every five minutes while a deck page is open, and every 10 seconds while the panel itself is open; the circular arrow in the header reads it again, at most once a minute. The check runs in the page, so with no deck page open (a browser tab or the desktop app's window), nothing is checked.
  • It cannot see every browser. Firefox and Safari are not read, and neither is a browser run from a folder of its own, such as an automation tool's throwaway profile.
  • It cannot tell intent or catch all automation. A marked visit may be your own agent, an extension or a script. Unmarked automation is invisible to the detector and can cancel a nearby finding.
  • It needs a SQLite reader. Node.js 22.13 or newer, or a sqlite3 command on the PATH. macOS ships sqlite3; Windows does not.
  • It can miss things you were near. If you opened a page by hand in that profile within the quiet time, a program's page next to it does not count. Set the time to 1 or 5 minutes to catch more.

Read a finding with its limits in mind

npx ccdeck

With a deck page open, press B to inspect Browser Watch. A finding means a marked navigation met the quiet-window rule. An empty list does not establish that no program used the browser.

來源:DEV Community · dev.to