Skip to content

refactor: decompose SessionManager into focused services (ARC-3)#1704

Merged
OneStepAt4time merged 3 commits intodevelopfrom
refactor/1696-session-decompose
Apr 12, 2026
Merged

refactor: decompose SessionManager into focused services (ARC-3)#1704
OneStepAt4time merged 3 commits intodevelopfrom
refactor/1696-session-decompose

Conversation

@OneStepAt4time
Copy link
Copy Markdown
Owner

Summary

Decomposes the 1,747-line SessionManager monolith into focused service classes via internal composition. Public API remains unchanged.

Extracted services

Service Lines Responsibility
SessionTranscripts 313 JSONL reading, caching (with truncation detection), pagination, cursor-based reads, summaries
SessionDiscovery 321 Discovery polling (2s interval + 5min timeout), session_map.json sync with 3 guards, filesystem fallback scan

What stays in SessionManager (1,321 lines)

  • Session lifecycle: create, kill, reconcile, reconcileTmuxCrash
  • State persistence: load, save, debouncedSave, encryption (AES-256-GCM)
  • Terminal interaction: sendMessage, escape, interrupt, sendInitialPrompt
  • Health monitoring: getHealth, isWindowAlive, detectWaitingForInput
  • Permission/question delegation (already thin wrappers)
  • Session access: getSession, listSessions, findIdleSessionByWorkDir

Approach

  • Services receive dependencies via constructor injection (DiscoveryDeps interface / direct tmux+config)
  • SessionInfo objects are passed by reference — mutations in services are visible to SessionManager
  • Discovery service gets a callback interface (\getSession, \getAllSessions, \save) to avoid circular deps

Quality gate


  • px tsc --noEmit\ — passes

  • pm run build\ — passes

  • pm test\ — 159 passed, 2 skipped (2,814 tests)

Aegis version

Developed with: v0.5.0-alpha

Closes #1696

Extract two focused service classes from the 1,747-line SessionManager:

- SessionTranscripts: JSONL reading, caching, pagination, summaries (313 lines)
  Owns parsedEntriesCache, getCachedEntries, readMessages, readMessagesForMonitor,
  readTranscript, readTranscriptCursor, getSummary

- SessionDiscovery: discovery polling, session map sync, filesystem scan (321 lines)
  Owns pollTimers, discoveryTimeouts, startDiscoveryPolling, stopDiscoveryPolling,
  syncSessionMap, maybeDiscoverFromFilesystem, cleanSessionMapForWindow,
  purgeStaleSessionMapEntries

SessionManager retains lifecycle (create/kill), persistence (load/save/encrypt),
terminal interaction (send/escape/interrupt), and health monitoring.
Delegates to extracted services via composition with dependency injection.

session.ts reduced from 1,747 to 1,321 lines (24% reduction).
Public API unchanged — all consumers see the same SessionManager interface.

Closes #1696
@OneStepAt4time OneStepAt4time added this to the v0.5.1-alpha milestone Apr 12, 2026
OneStepAt4time and others added 2 commits April 12, 2026 15:54
- session.ts: use Object.create(null) for sessions dictionary to eliminate
  prototype chain (fixes CodeQL js/prototype-polluting-assignment in
  session-transcripts.ts lines 48-49)
- tmux-polling-395.test.ts: access discovery methods/properties through
  sm.discovery instead of sm directly after ARC-3 extraction (fixes CI
  test failures on ubuntu)
@OneStepAt4time OneStepAt4time merged commit 7bfed32 into develop Apr 12, 2026
10 checks passed
@OneStepAt4time OneStepAt4time deleted the refactor/1696-session-decompose branch April 12, 2026 14:01
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