Skip to content

Unified session list: backend service + endpoint#139

Open
aakhter wants to merge 2 commits into
Ark0N:masterfrom
aakhter:cod-160-unified-session-service
Open

Unified session list: backend service + endpoint#139
aakhter wants to merge 2 commits into
Ark0N:masterfrom
aakhter:cod-160-unified-session-service

Conversation

@aakhter

@aakhter aakhter commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

First increment of a read-only "complete + searchable session list" — the backend half. Frontend (rich list UI, persistent modal, live refresh) and polish (pinning, cross-device ordering, name/prompt retention) follow in stacked PRs.

What this adds

  • New src/services/unified-session-service.ts — pure, IO-free, unit-testable:
    • mergeUnifiedSessions() combines five sources — live sessions + persisted (state.json) + lifecycle log + ~/.claude transcript history + mux stats — into one list de-duped by sessionId, with precedence history < lifecycle < persisted < live, a meaningfulness floor that drops bare lifecycle/mux-only noise, and a stable newest-first sort.
    • filterAndPaginate() — case-insensitive q over name/firstPrompt/workingDir/sessionId; total computed before paging; limit clamped to [1, 500].
  • New GET /api/sessions/unified in session-routes.ts — gathers the five sources from ctx (each try/caught so one bad source can't fail the request), feeds the pure service, returns { sessions, total } in the standard ApiResponse envelope. Short-circuits to empty in test mode.

Tests

  • test/services/unified-session-service.test.ts — 12, pure (merge precedence, de-dup, meaningfulness floor, sort, filter, pagination, limit-clamp).
  • test/routes/unified-sessions-routes.test.ts — 4, via app.inject (envelope, pagination, q-search, limit-clamp).

Verification

tsc --noEmit clean · new tests 16/16 · existing session-routes suite 53/53 (no regression) · prettier + eslint clean · build clean.

Read-only and additive — no existing route or behavior changes.

aakhter added 2 commits July 1, 2026 13:25
First increment of the read-only "complete + searchable session list".

- New src/services/unified-session-service.ts: mergeUnifiedSessions() combines
  live + persisted (state.json) + lifecycle + ~/.claude transcript history + mux
  stats into one list de-duped by sessionId, with precedence
  history < lifecycle < persisted < live, a meaningfulness floor that drops bare
  lifecycle/mux-only noise, and a stable newest-first sort. Plus
  filterAndPaginate() (case-insensitive q over name/firstPrompt/workingDir/
  sessionId; total before paging; limit clamped [1,500]). No IO — unit-testable.
- New GET /api/sessions/unified in session-routes.ts: gathers the five sources
  from ctx (sessions/store/lifecycle/scanProjectDir/mux, each try/caught), feeds
  the pure service, returns { sessions, total } (ApiResponse envelope). testMode
  short-circuits to empty.

Tests: unified-session-service.test.ts (12, pure) + unified-sessions-routes.test.ts
(4, app.inject).
createInitialRalphTrackerState() stamps lastActivity: Date.now(). The
'should create fresh instances each time' test deep-equaled two factory
results, so two calls straddling a millisecond boundary differed by 1ms
and failed intermittently (e.g. PR Ark0N#139 CI: 1782927694581 vs ...580).

Exclude the dynamic lastActivity from the equality check and assert it
is a number separately, preserving the test's intent (distinct instances
with identical initial field values) without the timing race.
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