rouse-context/api
Jason Monk ad628ae545
Fix #347: Client-subject notification copy + deep-link taps + Manage action (#362)
* Fix #347: Client-subject notification copy + deep-link taps + Manage action

Rewrite per-tool-call and session-summary notification copy per the locked
#342 design, wire up notification tap deep-links, and add a Manage action
button.

Per-tool-call notifications now read "${clientLabel} used ${humanized(toolName)}"
with the integration display name as body and the call timestamp rendered
natively via setWhen(). Session-summary notifications partition by client
label and emit one notification per client titled "${clientLabel} used
${count} ${tool|tools}" with up to 3 unique humanized tool names in the
body (Oxford comma, "and N more" past the cap).

Tap deep-links route to the audit-history screen — scrolled to the
specific call (per-tool-call) or filtered to the session time window
(summary) — and a single Manage action button points at the integration
manage page (or home, when a summary's calls span multiple integrations).

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>

* Update integration tests for per-client summary notification ids

#347 changed SessionSummaryNotifier from a single-id summary to one
notification per client, keyed by the clientLabel hash. The existing
:app:integrationTest fixtures still asserted against the legacy
SessionSummaryNotifier.NOTIFICATION_ID constant, so they failed in CI.

Updated each affected test to compute the expected id via
SessionSummaryNotifier.idForClient(<clientLabel>) and dropped the
now-unused NOTIFICATION_ID companion constant. The InMemoryTokenStore
resolves clientName=null to the clientId, so for tests that pass
clientName=null the expected label is their clientId string (e.g.
"race-test", "multi-test", "runtime-mode-switch"). ToolCallHappyPathTest
passes clientName = "Test Client" explicitly.

Also retargeted the MultiToolSessionTest title-string assertion from the
old "{count} calls across {N} integrations" copy to the new
"{clientLabel} used {count} tools" title shape.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>

* Move summary notification id bucket below per-call range

The previous summary id bucket (6000..15999) overlapped with
PerToolCallNotifier.BASE_ID = 7000, so any clientLabel whose hash
.mod(10000) landed in 1000..9999 produced an id that collided with
per-call notifications. RuntimeNotificationModeSwitchTest failed in CI
because its clientLabel "runtime-mode-switch" hashes to
idForClient(...) = 7465, which the test's "id >= PerToolCallNotifier.BASE_ID"
probe flagged as a per-call notification during phase 1 (SUMMARY mode).

Narrow the bucket to 4000..4999 so summary ids stay clear of the per-call
range. Collisions inside the 1000-entry bucket remain acceptable for the
expected <100-clients-on-a-device cardinality.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4 (1M context) <noreply@anthropic.com>
2026-04-22 03:11:08 -04:00
..
src Fix #347: Client-subject notification copy + deep-link taps + Manage action (#362) 2026-04-22 03:11:08 -04:00
build.gradle.kts Fix #248: Add Kover coverage measurement + CI aggregated report (#254) 2026-04-18 17:11:09 -04:00