Commit graph

7 commits

Author SHA1 Message Date
ozymandiashh
af0f23d09d fix(sharing,mcp): drop or pseudonymize pull request rows in redacted payloads
current.pullRequests survived both sanitizeForSharing and
redactProjectNames(include_project_names: false) verbatim, so each row's
full GitHub url and owner/repo#123 label named the repository to a paired
peer device and to a name-redacted MCP client — the same class of leak

Sharing drops the block like it drops the project, session and per-branch
rows. The MCP pass pseudonymizes url and label from the url (the
aggregation key) with the same salted, domain-separated hash as the other
pseudonyms, so rows referring to the same PR still line up and every
number stays untouched.

Closes #1346
2026-09-14 17:53:04 +03:00
ozymandiashh
e04ff869b4 fix(mcp): pseudonymize project keys, session ids and branch names
redactProjectNames rebuilt every row with a spread and replaced only the
fields it knew about, so identities added to the payload later rode
through untouched with include_project_names: false:

- topSessions[].projectKey, the raw sessions-list row key, is a
  dash-encoded absolute working directory (-Users-<user>-Projects-<repo>).
  Hash it with the project pseudonym, the way topProjects[].id already is.
- topSessions[].sessionId and topProjects[].sessionDetails[].sessionId are
  the drill-through identity; a Codex id also carries the rollout
  timestamp this pass blanks out of `date`. Hash them as session-xxxxxx.
  provider stays: it is claude/codex, not identity.
- byBranch[].branch is the raw git branch, which encodes ticket ids,
  customer names and feature codenames. Give each distinct branch a
  stable branch-xxxxxx pseudonym and keep the row's numbers. A null
  branch stays null: that is unbranched spend, not a name.

The new pseudonyms are domain-separated inside the digest so a branch and
a project of the same name do not share a hash; the project pseudonym
itself is unchanged. redactSessionDetails now takes its type from the
payload instead of a hand-copied inline type that had drifted from it,
which is why the leak type-checked. include_project_names: true is
unchanged.

Refs #1325, #1321
2026-09-13 01:42:28 +03:00
Aditya Vikram Singh
f5fd47e83d fix(usage): preserve project identity and qualify incomplete session counts 2026-09-07 22:02:54 +05:30
iamtoruk
53c5c7b370 feat(dock): glance popover with hero window, sessions and today strip
The Capacity Dock hover panel becomes a glance: a provider header, the
sessions running right now as pills with their context rings, a Today
strip, and a row of quota-window percentages, separated by hairlines.
Window percentages stay plain text until 70 percent so a healthy row
reads as text rather than a wall of colour. The panel stays 350pt wide;
every block height is a whole point and is summed into the panel frame,
since the hosting view does not size itself.

Running sessions are new CLI surface. `liveSessions` is add-only on the
menubar payload: sessions whose transcript was appended inside a 120s
window, carrying the branch, the model that answered last, and the
context that turn reported. Absence means "unknown", so the section
hides rather than claiming nothing is running. The block names projects
and branches, so sharing and MCP output strip it.

Today's totals needed no CLI change; the app simply was not decoding the
cache token counts the payload already carried.
2026-09-02 06:09:06 -07:00
ozymandiashh
5d366fb03b
feat(dashboard): add granular session and model timelines (#673)
* feat(dashboard): add granular usage timelines

* fix(dashboard): readable timeline legend and month-scale buckets

Session legend labels now use the real projectPath's last two segments
(app/web) instead of the sanitized project dir, which rendered as an
unreadable -Users-name-... dump and truncated in the legend.

Hourly buckets now cap at 8 days; longer ranges bucket daily. A 30-day
window rendered 720 overlapping hourly spikes, unreadable as a chart.

The browser no longer gives the backend session_other/model_other
aggregate a top-N slot, which rendered two identical Other legend
entries whenever the backend fold out-ranked a real series.

---------

Co-authored-by: AgentSeal <hello@agentseal.org>
2026-07-16 03:04:54 -07:00
AgentSeal
679f7ba5a6 fix(mcp): harden redaction, error responses, and pre-warm race
- Add per-install random salt to pseudonym hash to prevent rainbow table
  reversal of common project names
- Redact session details (dates, models) when project names are hashed
  to prevent re-identification via cost fingerprinting
- Return structuredContent in error responses to satisfy strict MCP
  clients that validate against declared outputSchema
- Remove pre-warm fire-and-forget that raced with the inflight map
- Fix empty markdown table producing malformed cells
- Add tests for session detail redaction and cross-field consistency
2026-06-03 00:56:30 +02:00
iamtoruk
1e82a9cf21 feat(mcp): hash project names by default with opt-in reveal 2026-06-02 02:13:08 -07:00