How ModLens Recovers Pasted Images from LLM Harness Session Storage
ModLens reconstructs pasted images through a three-stage pipeline: detecting the active LLM harness via process inspection, delegating extraction to harness-specific adapters, and securely writing hashed image files to private directories.
ModLens is an open-source tool that extracts visual assets from LLM-powered development harnesses like Claude, Pi, and Opencode. When developers paste screenshots into these AI assistants, the images get embedded in proprietary session storage formats; ModLens provides a unified recovery interface to retrieve these assets regardless of the underlying harness architecture.
The Three-Stage Recovery Pipeline
The recovery system in liustack/modlens abstracts harness differences into a consistent workflow implemented in src/recoverPaste/.
Stage 1: Harness Detection
The detect.ts module identifies which LLM harness is active by inspecting the runtime environment. It examines the process tree via /proc on Unix systems and scans for known session markers—such as Claude’s ~/.claude directory, Pi’s ~/.cache/pi, or Opencode’s SQLite transcript files.
The exported helper detectHarness() returns a HarnessSource object that specifies which adapter should handle the recovery. If automatic detection fails, users can bypass this stage by manually specifying a transcript directory via the --out-dir CLI flag.
Stage 2: Adapter Delegation
The adapters/ folder contains harness-specific modules that implement the HarnessAdapter interface defined in types.ts. Each adapter provides two functions:
detect(source): boolean– Confirms the adapter can handle the given sourcerecover(source, outDir): RecoveredImage[]– Extracts and returns image metadata
Claude Adapter (adapters/claude.ts): Parses Claude’s JSONL transcript files to locate image blocks, then extracts the raw base-64 payload. It also exports claudeProjectSlug for integration with the guard subsystem.
Pi Adapter (adapters/pi.ts): Handles Pi’s custom log format using the piExtractLine helper to pull image bytes from temporary storage. It exports piSessionSlug for session identification.
Opencode Adapter (adapters/opencode.ts): Queries Opencode’s SQLite transcript database via opencodeSourceFor() to extract image columns from the session storage.
Stage 3: Orchestration and Safe File Writing
The index.ts module orchestrates the recovery process. It calls prepareOutDir() to create a secure output directory—either a temporary folder created with mkdtemp using 0700 permissions, or a user-specified path verified to be a real directory owned by the current user (with symlink checks to prevent path traversal).
The system iterates over the static ADAPTERS array ([claudeAdapter, piAdapter, opencodeAdapter]), delegating recovery to the first matching adapter. For each recovered image, ModLens:
- Computes a SHA-256 hash of the byte content using
crypto.createHash('sha256') - Derives the file extension from the MIME type via
extensionFromMediaType() - Writes the file to the secure output directory
The function returns a RecoverResult containing the list of recovered images and their source paths.
Harness-Specific Implementation Details
Each adapter handles unique storage mechanisms while conforming to the shared interface.
Claude JSONL Transcript Parsing
Claude stores conversation history in JSONL format where image blocks contain base-64 encoded data. The Claude adapter in src/recoverPaste/adapters/claude.ts streams these transcript files, detects image block markers, decodes the base-64 payload, and returns the raw bytes for hashing and storage.
Pi Custom Log Format Extraction
Pi uses a proprietary logging structure. The Pi adapter leverages piExtractLine from src/recoverPaste/adapters/pi.ts to parse log entries, locate references to temporarily stored image files, and read the binary data from Pi’s cache directory.
Opencode SQLite Database Queries
Opencode persists transcripts in SQLite. The adapter in src/recoverPaste/adapters/opencode.ts (which includes a test suite in adapters/opencode.test.ts) executes queries against the transcript database to select image columns, then buffers the results for file writing.
Security and Extensibility Architecture
Security Controls
ModLens implements defense-in-depth for file system operations. The prepareOutDir() function ensures output directories are never world-readable by enforcing 0700 permissions on temporary folders. When users specify custom output paths, the system verifies directory ownership and rejects symlinks to prevent directory traversal attacks. All output filenames are derived from content hashes (SHA-256) rather than original metadata, eliminating path injection risks.
Extensibility Model
Adding support for new harnesses requires implementing the HarnessAdapter interface and registering the adapter in the ADAPTERS array within src/recoverPaste/index.ts. The modular design isolates harness-specific parsing logic while the core orchestration handles security, hashing, and file I/O consistently.
Usage Examples
Command-Line Recovery
Recover images from the automatically detected harness:
modlens recover-paste
Specify a custom output directory with ownership verification:
modlens recover-paste --out-dir ./my-images
Programmatic Integration
Import the recovery function in TypeScript projects:
import { recoverPastedImages } from 'modlens/src/recoverPaste/index';
// Recover from current working directory to temporary folder
const result = await recoverPastedImages({ count: 3 });
console.log('Recovered files:', result.images.map(i => i.path));
Adding a Custom Harness Adapter
Implement the interface and register the adapter:
// src/recoverPaste/adapters/myharness.ts
import type { HarnessAdapter } from '../types';
export const myHarnessAdapter: HarnessAdapter = {
name: 'my-harness',
detect: (source) => source.someCondition,
recover: async (source, outDir) => {
// Parse harness-specific storage
// Return RecoveredImage[]
},
};
// Register in src/recoverPaste/index.ts
import { myHarnessAdapter } from './adapters/myharness';
const ADAPTERS = [claudeAdapter, piAdapter, opencodeAdapter, myHarnessAdapter];
Summary
- Detection Strategy:
detect.tsidentifies active harnesses via process tree inspection and filesystem markers, returning aHarnessSourcefor adapter selection. - Adapter Pattern: Each harness implements the
HarnessAdapterinterface withdetect()andrecover()methods; current adapters support Claude (JSONL), Pi (custom logs), and Opencode (SQLite). - Security Model:
prepareOutDir()enforces0700permissions and ownership verification; output filenames use SHA-256 content hashes to prevent collisions and injection attacks. - Core Orchestration:
src/recoverPaste/index.tscoordinates detection, adapter iteration, and safe file writing, returning structuredRecoverResultobjects. - Extension Points: New harnesses integrate by implementing the interface and adding to the
ADAPTERSarray without modifying core recovery logic.
Frequently Asked Questions
How does ModLens determine which LLM harness is currently running?
ModLens uses the detectHarness() function in src/recoverPaste/detect.ts to inspect the process tree via /proc on Unix systems and check for harness-specific filesystem markers like ~/.claude for Claude or ~/.cache/pi for Pi. This detection returns a HarnessSource object that determines which adapter handles the recovery.
What security measures protect recovered image files?
The system creates output directories with 0700 permissions using mkdtemp for temporary folders, or validates user-specified paths for ownership and symlink integrity. All recovered files are named using SHA-256 hashes of their content via crypto.createHash('sha256'), preventing filename collisions and path traversal vulnerabilities.
Can ModLens recover images from harnesses not officially supported?
Yes, the architecture supports custom adapters by implementing the HarnessAdapter interface defined in types.ts. Developers create a module with detect() and recover() methods, then register the adapter in the ADAPTERS array in src/recoverPaste/index.ts to extend support to additional LLM platforms.
Where does ModLens store recovered images by default?
By default, ModLens creates a temporary directory using prepareOutDir() with restricted 0700 permissions. Users can override this behavior by specifying a custom path via the --out-dir CLI argument, which must be a real directory owned by the current user and cannot be a symlink.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →