feat(CF-580): Implement transcript-based session recovery for MCP

Add direct transcript ingestion and orphan recovery using Claude Code's JSONL
transcripts instead of relying on daemon-based note synchronization.

Changes:

1. **Database migration** (027_session_transcript_storage.sql):
   - Add transcript_jsonl, transcript_ingested_at, transcript_file_path columns
   - Add indexes for efficient ingestion tracking

2. **Transcript parser utility** (src/utils/transcript-parser.ts):
   - parseTranscriptFile(): Parse JSONL line-by-line, handle corrupt lines
   - encodeWorkingDir(): Convert paths to Claude Code directory encoding
   - findOrphanedTranscripts(): Scan for stale transcript files
   - ingestTranscriptToDatabase(): Main ingestion function for Node.js

3. **Orphan recovery enhancement** (src/tools/sessions.ts):
   - sessionRecoverOrphaned() now tries transcript ingestion first
   - Finds most recently modified JSONL in project directory
   - Falls back to legacy notes.md recovery for backward compatibility
   - Properly handles path encoding (/ and . → -)

Benefits:
- No daemon needed for recovery (Phase 2 will remove LaunchAgent)
- Full transcript audit trail stored in database
- Immediate recovery capability for orphaned sessions
- Cleaner architecture (no markdown parsing complexity)
- Compatible with Claude Code's UUID-based session files

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-01-29 17:53:37 +02:00
parent 30650cf47f
commit e04a8ab524
3 changed files with 290 additions and 2 deletions

View File

@@ -0,0 +1,24 @@
-- Migration 027: Add transcript storage for session recovery
-- Purpose: Store full JSONL transcripts from Claude Code for session recovery (CF-580)
-- Context: Replace daemon-based notes syncing with direct transcript ingestion
-- Add columns to sessions table for transcript storage
ALTER TABLE sessions
ADD COLUMN IF NOT EXISTS transcript_jsonl TEXT,
ADD COLUMN IF NOT EXISTS transcript_ingested_at TIMESTAMPTZ,
ADD COLUMN IF NOT EXISTS transcript_file_path TEXT;
-- Index for efficient querying of ingested sessions
CREATE INDEX IF NOT EXISTS idx_sessions_transcript_ingested
ON sessions(transcript_ingested_at)
WHERE transcript_ingested_at IS NOT NULL;
-- Index for finding sessions by transcript file path (for recovery)
CREATE INDEX IF NOT EXISTS idx_sessions_transcript_file_path
ON sessions(transcript_file_path)
WHERE transcript_file_path IS NOT NULL;
-- Comments for documentation
COMMENT ON COLUMN sessions.transcript_jsonl IS 'Full JSONL transcript from Claude Code for complete session audit trail';
COMMENT ON COLUMN sessions.transcript_ingested_at IS 'Timestamp when transcript was ingested into database';
COMMENT ON COLUMN sessions.transcript_file_path IS 'Path to source JSONL file for debugging and recovery';