Skip to content

fix(desktop): name the session in the usage activity task column - #4219

Open
liuxiaocs7 wants to merge 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/usage
Open

fix(desktop): name the session in the usage activity task column#4219
liuxiaocs7 wants to merge 1 commit into
apache:mainfrom
liuxiaocs7:liuxiaocs7/usage

Conversation

@liuxiaocs7

@liuxiaocs7 liuxiaocs7 commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

On the Usage Statistics page (使用统计) → Activity records (活动记录), the 任务 (Task) column showed 未命名会话 · <short id> ("Untitled session") for every row — even sessions that have a real title.

This is a regression. #3833 fixed exactly this column by carrying the session name (SessionHeader.name) through the old packages/storage/src/usage-stats-store.ts pipeline. #3697 then moved usage onto the Runtime Host projection and #4060 deleted that store. The new pipeline only carried sessionId, never the title, so UsageRequestLog.sessionName was declared-but-never-populated and the UI's usageSessionDisplayLabel always fell back to the untitled label.

Resolve the title on the Host, where every usage-bearing session is reachable:

  • HostUsagePricingCoordinator takes a session-title reader (stores.sessionStore.readHeaderSnapshot). Per logs page it resolves the title for each row's sessionId and emits it as a new bounded sessionTitle field on the LLM/tool usage projections (projectText, ≤1024 bytes).
  • Reading the durable session header by id bypasses the catalog's role/preparing/ledger-v0 filters (sqliteOrdinarySessionRolePredicate et al.), so reserved-role, coordination (e.g. WorkHub), and legacy sessions are named too — not just ordinary ones.
  • Resolution is per-row and tolerant: a session the reader can't read is simply left untitled; one unreadable session never blanks the rest.
  • The desktop layer copies sessionTitlesessionName; the renderer (usageSessionDisplayLabel) already owns the untitled fallback, so no UI change.

Fixes #4218

Review responses

This supersedes the earlier main-process/catalog-join approach. Addressing the review:

  • Spec P2 (catalog is not a complete usage-session source). Confirmed: readCatalogRecord applies the same role/preparing/ledger-v0 filters as the list query, so no complete name source is reachable from the desktop process. Fixed at the source — the Host resolves titles from the unfiltered durable header, covering reserved-role/coordination/legacy sessions.
  • Spec P2 (one legacy session blanks all titles). Gone: resolution is per-row via readHeaderSnapshot, wrapped per-id, so a single unreadable/unprojectable session can't affect the others. The all-or-nothing client.listSessions() is no longer used here.
  • Standards P2 (reconnect exception swallowed). Gone: the separate loadSessionNames() catch was removed. The title now rides the existing queryUsage read, which already propagates reconnectable failures through handleReconnectableRead.
  • Standards P3 (blank-title test not actually covered). Covered on the Host: a coordinator test seeds a whitespace-only title and asserts the row is emitted without sessionTitle (removing the .trim() guard fails it), alongside a resolved title and a throwing (unreadable) session.

Verification

Same Storybook case (product-settings-pages--usage-long-tail), differing only by whether the title is populated. Named sessions show their real title; genuinely unnamed rows still fall back:

Usage 任务 column before/after

Checks run locally:

  • tsc build of @maka/runtime-host and tsc -p tsconfig.main.json (desktop main) — both clean.
  • node --test — 23/23 across the affected suites:
    • usage-pricing-two-client-uds incl. a new case: the LLM/tool logs carry the Host-resolved title, a whitespace-only title is dropped, and an unreadable session is tolerated.
    • usage-pricing-protocol incl. sessionTitle round-trip + over-length rejection.
    • runtime-host-usage-ipc-main: sessionName is surfaced from the projection's sessionTitle.
  • biome check on the changed files — clean.

Not run in this environment: the full workspace typecheck / full test suite / e2e / a real Electron window. @maka/ui currently has pre-existing @astryxdesign/core type errors unrelated to this change; the desktop main process and the Host packages don't depend on @maka/ui, and Storybook renders it from source, so the evidence above is unaffected.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code (claude-opus-4-8) — diagnosis, the fix, the tests, and the before/after evidence. The commit carries a Generated-by trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/M Under 500 readable lines label Aug 29, 2026
liuxiaocs7 added a commit to liuxiaocs7/maka that referenced this pull request Aug 29, 2026
The Usage Statistics activity log's 任务 (Task) column showed
`未命名会话 · <id>` for every row. apache#3833 fixed this by carrying
`SessionHeader.name` through the old usage-stats-store.ts pipeline, but
apache#3697 moved usage onto the Runtime Host projection and apache#4060 deleted
that store — the new pipeline only carried `sessionId`, so
`UsageRequestLog.sessionName` was declared but never populated and the
UI always hit the untitled fallback.

Resolve the title on the Host, where every usage-bearing session is
reachable. HostUsagePricingCoordinator takes a session-title reader
(sessionStore.readHeaderSnapshot) and, per logs page, resolves the title
for each row's sessionId, emitting it as a new bounded `sessionTitle`
field on the LLM/tool usage projections. Reading the durable header by
id bypasses the catalog's role/preparing/ledger-v0 filters, so
reserved-role, coordination, and legacy sessions are named too; an
unreadable session is tolerated per-row and simply stays untitled. The
desktop layer copies `sessionTitle` onto `sessionName`; the renderer
(usageSessionDisplayLabel) already owns the untitled fallback.

Bump the Host compatibility epoch (68 → 69): the new projection field is
rejected by older Clients, so the same protocol version no longer
guarantees safe interoperability.

Closes apache#4218

Generated-by: Claude Code (claude-opus-4-8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(desktop): Usage Statistics activity log always shows "未命名会话" in the 任务 (Task) column

1 participant