Skip to content

feat(dashboard): agent reads per doc, this week vs last (BEA-244) - #263

Open
ssowonny wants to merge 1 commit into
mainfrom
bea-244-ph-idea-show-which-docs-your-agents-actually-read-week-over
Open

ssowonny wants to merge 1 commit into
mainfrom
bea-244-ph-idea-show-which-docs-your-agents-actually-read-week-over

Conversation

@ssowonny

Copy link
Copy Markdown
Contributor

TL;DR

  • The Dashboard now shows agent reads for every markdown doc, this week vs last, with ▲/▼/new, so you can finally tell whether rewriting a doc for agents changed anything.
  • Frontend only: heat?days=7 and heat?days=14 subtracted. No new endpoint, no server change.
  • CLAUDE.md / AGENTS.md / GEMINI.md are pinned as "auto-loaded - not counted", and a visible caveat says why. Without that, the most important doc would look dead.
  • Known gap: auto-loaded files still aren't counted. That needs a new hook event, which is a follow-up (it touches the pure-shell hook-guard invariant).

Closes BEA-244.

How it's built

Two windows plus the tree go into one pure helper:

flowchart LR
  A["heat?days=7<br/>agent = this week"] --> H
  B["heat?days=14<br/>minus days=7 = last week"] --> H
  T["tree: *.md / *.mdx in scope"] --> H
  H["weeklyAgentReads()<br/>lib/heat.ts"] --> R["ranked rows"]
  H --> P["pinned: CLAUDE.md,<br/>AGENTS.md, GEMINI.md"]
Loading
  • lib/heat.ts: weeklyAgentReads + weekChange, unit-tested in heat.test.ts (clamp on a B<A race, auto-loaded basenames at any depth and case-sensitive, .mdx included, .txt out, sort tie-breaks, 0/0 for unread docs).
  • Insights.tsx: useAgentWeeks makes two queries keyed under ["heat", apiBase, "days", N]. The existing refresh-on-open prefix-matches them, and they never collide with useHeat's 30-day key. It returns null unless both requests succeed, so a failed or older hub hides the section and nothing else. AgentWeekTable renders below Hot path: top 20, then a "show all N" toggle.
  • Browser.tsx: it's gated on insightsOpen (the Dashboard or the project home), so no other page fires the new requests.
  • Rows come from the tree, so unread docs show as 0/0 and hidden paths can't appear, because the tree and /heat share s.visibility(r).
  • The window arithmetic is spelled out in a code comment. days=7 covers today plus 7 prior UTC days, so "this week" carries one extra, partial day. The UI just says "the last 7 days, today included".

Screenshots

Before After
before after
Pinned auto-loaded row (CLAUDE.md injected into the tree) Phone, 390px
pinned mobile

What was run

  • go test ./...: all packages ok (internal/webapp 419s).
  • npm test: 149/149.
  • npm run e2e: 283 passed, 2 failed, both unrelated to this PR:
    • edit-url.spec.ts "a failing read leaves the editor…" fails on main too. I checked by running it against main's committed static/.
    • layout.spec.ts "the gutter belongs to the scroll container" is a flake that passes when re-run alone.
  • New e2e specs in dashboard.spec.ts cover: the caveat is visible, index.md shows 30/0 new, deploy.md shows 0/5 ▼ 5, human reads are excluded, folder scope shows only notes/, and the section hides when heat?days=7|14 returns 500.
  • check-dist.sh: fresh.
  • UI evaluation: I checked desktop and a 390px phone in the seeded hub. At phone width the column headers wrapped, so I added a narrow-screen rule for them.

Deviations from the plan (small)

  • The seed row is deploy.md, 5 agent reads, ten days back. No other spec counts that file.
  • Pinned-row label reads "(k explicit reads in 14 days)" rather than a bare count, so the window is unambiguous.
  • Rows use their own in-wk-* classes instead of the plan's reuse of in-hp-*. Existing specs count .in-hp-row by filename, and reusing the class doubled those counts.
  • An existing test fix rides along. staleNote in heat.test.ts pinned "now" to 2026-08-18 while staleNote reads the real clock, so it has failed on main since the calendar passed it. It now uses Date.now().
  • Docs: guides/what-agents-read.md gets the new view and the auto-load caveat. No architecture diagram change, since no new component file or seam was added.

Open question

Once this is in use, is 7 vs 7 days the right grain? A multi-week sparkline or a window picker was scoped out of v1.

Build session

cd $(git worktree list | grep bea-244-ph-idea-show-which-docs-your-agents-actually-read-week-over | awk '{print $1}') && claude --resume 94f496cb-70a4-4035-a161-721acbeff0f8

(only works on the machine that ran the build)

🤖 Generated with Claude Code

The Dashboard gets an "Agent reads, this week vs last" section: every
markdown doc in scope with its agent reads over the last 7 days against
the 7 before, and a ▲/▼/new change. Built from heat?days=7 and
heat?days=14 — no server change. CLAUDE.md / AGENTS.md / GEMINI.md are
pinned as "auto-loaded - not counted", with a visible caveat, since
their real use never passes through the read hook.

Also fixes a clock-dependent staleNote unit test that pinned "now" to
2026-08-18 while staleNote measures from the real clock.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant