pub struct TranscriptScanner<'a, S: Storage> { /* private fields */ }Expand description
Orchestrates transcript file scanning with storage integration.
TranscriptScanner provides a high-level API for scanning Claude Code
transcript files and inserting events into storage. It handles:
- Incremental parsing (only reads new content since last scan)
- Deduplication by UUID
- Position tracking for future scans
§Example
use mi6_core::{Storage, TranscriptScanner};
use mi6_storage_sqlite::SqliteStorage;
use std::path::Path;
let storage = SqliteStorage::open(Path::new("mi6.db"))?;
let scanner = TranscriptScanner::new(&storage, "my-machine-id");
let result = scanner.scan_file(Path::new("/path/to/transcript.jsonl"))?;
println!("Inserted {} events", result.inserted);Implementations§
Source§impl<'a, S: Storage> TranscriptScanner<'a, S>
impl<'a, S: Storage> TranscriptScanner<'a, S>
Sourcepub fn new(storage: &'a S, machine_id: impl Into<String>) -> Self
pub fn new(storage: &'a S, machine_id: impl Into<String>) -> Self
Create a new scanner with the given storage and machine ID.
The machine ID is used to tag events with their source machine, enabling multi-machine aggregation.
Sourcepub fn scan_file(&self, path: &Path) -> Result<ScanResult, ScanError>
pub fn scan_file(&self, path: &Path) -> Result<ScanResult, ScanError>
Scan a transcript file and insert events into storage.
This method:
- Loads the last scanned position for the file
- Parses new entries since that position
- Inserts new events (checking for duplicates by UUID)
- Updates the position for future incremental scans
§Returns
Returns a ScanResult with the count of inserted events and
parse errors encountered.
§Errors
Returns a ScanError if:
- The file cannot be read
- Storage operations fail
Sourcepub fn scan_sessions(
&self,
session_ids: &[&str],
) -> Result<ScanResult, ScanError>
pub fn scan_sessions( &self, session_ids: &[&str], ) -> Result<ScanResult, ScanError>
Scan transcripts for specific sessions by ID.
Looks up each session, checks if it has a transcript_path that exists,
and scans it. Sessions without transcript paths or with missing files
are silently skipped.
§Arguments
session_ids- Slice of session IDs to scan
§Returns
Returns an aggregated ScanResult with the total count of inserted
events and parse errors across all scanned files.
§Errors
Returns a ScanError if a storage operation fails or a transcript
file cannot be parsed.
Sourcepub fn backfill_initial_prompt(
&self,
session_id: &str,
transcript_path: &Path,
) -> Result<bool, ScanError>
pub fn backfill_initial_prompt( &self, session_id: &str, transcript_path: &Path, ) -> Result<bool, ScanError>
Backfill the initial prompt for a session from its transcript file.
This is a fallback for when the UserPromptSubmit hook doesn’t fire,
such as when Claude is started with an inline prompt like
claude 'initial prompt'.
The method:
- Checks if the session exists and has no first_user_message
- Reads the transcript file to find the first user prompt
- Creates a UserPromptSubmit event with the prompt
This is idempotent - if the session already has a first_user_message, this method does nothing.
§Arguments
session_id- The session ID to backfilltranscript_path- Path to the transcript file
§Returns
Returns true if a prompt was backfilled, false otherwise.