Skip to content

feat(mobile): pinned "Active now" tray on the Agents session list#4626

Merged
iscekic merged 16 commits into
mainfrom
feat/active-now-pinned-section
Jul 21, 2026
Merged

feat(mobile): pinned "Active now" tray on the Agents session list#4626
iscekic merged 16 commits into
mainfrom
feat/active-now-pinned-section

Conversation

@iscekic

@iscekic iscekic commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a pinned "Active now" tray to the Agents session list. Live sessions are pinned above history and appear only in the tray (excluded from the history date sections), so an active session is never shown twice. Each tray row shows a platform badge (e.g. CLI) — or a LIVE fallback when the session isn't enriched — alongside a live dot and a relative-time meta line.

Stacked on top of feature/mobile-agent-attention-notifications (PR #4605); please merge that first.

What changed

  • webactiveSessions.list is enriched by joining cli_sessions_v2 for per-session platform + timestamps. Two-phase failure handling: a worker/parse failure degrades to an empty list; a DB failure during enrichment falls back to unenriched rows (never collapses the list).
  • sharedKNOWN_PLATFORMS relocated to @kilocode/app-shared/platforms as the single source for web routers and the mobile other bucket.
  • mobile — pure tray-selection helpers (selectPinnedActiveSessions, excludeActiveFromGroups, remoteAgentLabel/remoteMeta), the ActiveNowSection tray, a session-list-body-model state machine, and the section header / empty-body components. History rows are no longer marked live; the tray owns live presentation via metaWhileLive. Loading→loaded uses an animated cross-fade; the inline "Couldn't refresh" retry line shows only when cached content is visible.
  • fix — the body/full-screen error is driven by the stored-list query only; a transient active-poll blip surfaces solely through the inline refresh line and never hides stored history.

Verification

  • On-device E2E (iOS + Android): pinned tray, tray/history exclusivity, search (tray persists while typing), project filter, platform filter incl. clear/restore, handover (live → history on CLI exit), and the retryable refresh error + recovery. Account B empty states: first-use empty, LIVE fallback badge with empty history under the tray, and filtered active-only-empty with clear/restore.
  • Unit: mobile suite (1087 tests) and the active-sessions-router tests pass.
  • Checks: typecheck, lint, check:unused, and formatting are clean.

Follow-ups (not in this PR)

  • Push sessions.heartbeat updates into the mobile list so the tray updates without waiting on the 10s poll.
  • Tray overflow treatment when many sessions are active at once.
  • Optionally expose the row eyebrow badge (LIVE/CLI) and meta to screen readers; today the row's accessibility label is the title only, matching the existing Home/history row pattern.

iscekic added 14 commits July 17, 2026 00:43
Anchor the attention ack store on globalThis so the single-writer detail
screen and the session-list readers share one instance across Expo Router
route bundles, and remount the Agents list on attention-revision change
after refocus so the freezeOnBlur'd list re-reads the ack store on return.
- cloud-agent-next: fetch session metadata inside the attention-push
  try/catch so a metadata failure is logged and swallowed as documented,
  never breaking the best-effort ingest path.
- mobile: key the Agents list on an attention revision snapshotted at tab
  focus, so it remounts to re-read the ack store only on return from a
  just-opened session, not on any unrelated session's attention change
  during browsing (preserving scroll).
- mobile: isolate attention-store subscribers so one throwing listener
  cannot prevent the rest from being notified.
oxlint no-confusing-void-expression forbids returning the void expression
from the arrow shorthand passed to expect().
Thread the heartbeat session title from UserConnectionDO through
SessionIngestDO into the notifications service so attention and
session-ready push notifications lead with the session title.

- packages/notifications: optional title on sendSessionReadyNotificationInputSchema.
- services/notifications: add a code-point-safe title sanitizer (collapse
  whitespace, <=80 code points incl. ellipsis, no split surrogate) used by
  dispatchCloudAgentSessionPush and the ready push. Ready push prefers the
  heartbeat title hint, then the DB title, then the fixed 'Kilo session ready'.
- services/session-ingest: forward the heartbeat title from
  UserConnectionDO.claimSessionReadyPush into SessionIngestDO and on to
  sendSessionReadyNotification.
- Tests cover title composition, long-title and surrogate-pair truncation,
  whitespace handling, hint-vs-DB precedence, and schema strip-on-parse.
The Agents session list body/full-screen error was driven by the combined
isError (stored || active), so a transient active-poll failure could wrongly
surface a full-screen "Could not load sessions" (or a query-error-empty under
the tray) instead of the intended first-use / no-past-sessions state. Active
poll failures already surface only through the inline "Couldn't refresh" line
via activeIsError, per the useAgentSessions contract. Wire the non-search body
error to storedIsError so active blips never hide stored history.
@iscekic iscekic self-assigned this Jul 19, 2026
@kilo-code-bot

kilo-code-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the mobile "Active now" tray UI/state-machine, the web active-sessions enrichment router (tenant-scoped, two-phase failure handling verified against the PR's stated non-collapse behavior), and the shared KNOWN_PLATFORMS relocation, with no high-confidence security, correctness, or logic issues found on changed lines.

Files Reviewed (23 files)
  • apps/mobile/src/components/agents/active-now-section.tsx
  • apps/mobile/src/components/agents/session-list-body-empty.tsx
  • apps/mobile/src/components/agents/session-list-body-model.test.ts
  • apps/mobile/src/components/agents/session-list-body-model.ts
  • apps/mobile/src/components/agents/session-list-content.tsx
  • apps/mobile/src/components/agents/session-list-helpers.test.ts
  • apps/mobile/src/components/agents/session-list-helpers.ts
  • apps/mobile/src/components/agents/session-list-screen.tsx
  • apps/mobile/src/components/agents/session-list-section-header.tsx
  • apps/mobile/src/components/agents/session-row.tsx
  • apps/mobile/src/components/ui/session-row-eyebrow-right.test.ts
  • apps/mobile/src/components/ui/session-row-eyebrow-right.ts
  • apps/mobile/src/components/ui/session-row.tsx
  • apps/mobile/src/lib/agent-session-groups.ts
  • apps/mobile/src/lib/hooks/use-agent-sessions.ts
  • apps/web/src/routers/active-sessions-router.test.ts
  • apps/web/src/routers/active-sessions-router.ts
  • apps/web/src/routers/cli-sessions-router.ts
  • apps/web/src/routers/cli-sessions-v2-router.ts
  • apps/web/src/routers/unified-sessions-router.ts
  • packages/app-shared/package.json
  • packages/app-shared/src/platforms.ts

Reviewed by claude-sonnet-5 · Input: 26 · Output: 7.6K · Cached: 607.6K

Review guidance: REVIEW.md from base branch feature/mobile-agent-attention-notifications

Base automatically changed from feature/mobile-agent-attention-notifications to main July 21, 2026 12:25
iscekic added 2 commits July 21, 2026 15:00
# Conflicts:
#	apps/mobile/src/components/agents/session-list-content.tsx
#	apps/mobile/src/components/agents/session-row.tsx
#	apps/mobile/src/components/ui/session-row.tsx
#	apps/web/src/routers/active-sessions-router.test.ts
#	apps/web/src/routers/active-sessions-router.ts
#	services/session-ingest/src/remote-session-notifications.test.ts
#	services/session-ingest/src/remote-session-notifications.ts
# Conflicts:
#	apps/web/src/routers/active-sessions-router.ts
@iscekic
iscekic merged commit 805353d into main Jul 21, 2026
62 checks passed
@iscekic
iscekic deleted the feat/active-now-pinned-section branch July 21, 2026 13:13
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.

2 participants