How the agentsview CLI Manages Different Agent Session Formats

The agentsview CLI manages different agent session formats through a centralized AgentDef registry in internal/parser/types.go, where each AI agent registers custom discovery and parsing functions that normalize diverse formats into a unified SQLite schema.

The agentsview CLI from the kenn-io/agentsview repository is a Go-based command-line tool that monitors directories containing session files from multiple AI coding assistants. Understanding how the agentsview CLI manages different agent session formats reveals a plugin-style architecture that abstracts away format-specific complexities, allowing the same sync engine and HTTP API to handle everything from Claude Code's JSONL streams to Cursor's project layouts.

The Agent Registry: Centralized Format Definitions

At the heart of the format management system lies the AgentDef struct defined in internal/parser/types.go. This struct serves as a contract that every supported agent must implement:

type AgentDef struct {
    Type         AgentType          // “claude”, “codex”, …
    DisplayName  string            // Human‑readable name
    EnvVar       string            // “CLAUDE_PROJECTS_DIR”, …
    ConfigKey    string            // TOML key, empty when not configurable
    DefaultDirs  []string          // e.g. []string{".codex/sessions"}
    IDPrefix     string            // “codex:” etc.
    WatchSubdirs []string          // Sub‑directories to watch (nil ⇒ watch root)
    ShallowWatch bool              // Watch root only, rely on periodic sync
    FileBased    bool              // false for DB‑backed agents (Claude AI, ChatGPT …)

    // Functions supplied by each agent’s parser
    DiscoverFunc   func(string) []DiscoveredFile // Walk a root, return session files
    FindSourceFunc func(string, string) string   // Locate a single session’s source file
    WatchRootsFunc func(string) []string         // Optional custom watch‑root resolver
    ShallowWatchRootsFunc func(string) []string // Optional extra roots for shallow watch
}

All agent definitions are collected in the global Registry slice. During startup, the CLI iterates over this registry in cmd/agentsview/main.go to build a watch list, applying environment variable overrides (via EnvVar) and resolving default directories (via DefaultDirs) for each file-based agent.

Discovery: Agent-Specific File Walking

Each parser supplies a DiscoverFunc that knows how to locate session files within its specific directory structure. For example, internal/parser/claude.go implements DiscoverClaudeSessions(root string) []DiscoveredFile which walks the ~/.claude/projects tree to collect every *.jsonl file.

The discovery phase operates as follows:

  1. The sync engine resolves roots using environment variables or default paths
  2. It invokes def.DiscoverFunc(root) for each registered agent
  3. Returned DiscoveredFile objects are queued for parsing

Agents like Copilot, Cursor, and Kilo maintain analogous discovery functions in their respective parser files, each handling their unique file naming conventions and sub_directory structures.

Parsing and Normalization: Unified Output Structure

After discovery, the sync engine loads each file and calls the appropriate parser. Claude's parser (ParseClaudeSession in internal/parser/claude.go) handles the most complex format, processing JSON-L streams that may contain UUID/parent-UUID DAGs, merging streamed assistant chunks, and resolving tool-result references.

Crucially, every parser returns the same ParseResult type defined in internal/parser/types.go:

type ParseResult struct {
    Session ParsedSession
    Messages []ParsedMessage
}

This contract ensures that downstream components—the SQLite writer in internal/db/sessions.go, the SSE server, and the frontend—treat every session uniformly regardless of its original on-disk representation.

Session ID Management and Prefix Disambiguation

The CLI uses the IDPrefix field to disambiguate between agents when handling session identifiers. For example:

  • Codex: Uses prefix codex:
  • Cursor: Uses prefix cursor:
  • Claude Code: Uses an empty string (un-prefixed UUID)

The AgentByPrefix function (also in internal/parser/types.go) maps session IDs back to their originating agents by stripping any host prefix (host~id) and matching the remaining identifier against known prefixes. For Claude, where the prefix is empty, the match succeeds only if the ID contains no colon, effectively disambiguating it from all prefixed agents.

Watch Strategies: File-Based vs. Database Agents

The FileBased boolean field distinguishes between two fundamentally different agent types:

File-Based Agents (FileBased: true):

  • Register with the file watcher (fsnotify/recursive)
  • Support real-time updates via DiscoverFunc
  • May use ShallowWatch: true to avoid recursive inotify registration (used by high-volume agents like Aider), relying instead on a periodic 15-minute scan

Database-Backed Agents (FileBased: false):

  • Include Claude.ai, ChatGPT, Forge, and Piebald
  • Do not set up file watchers
  • Query session data directly via PostgreSQL sync code in internal/postgres
  • Still populate the same ParsedSession struct, but from DB queries rather than files

Some agents like Codex and Antigravity need to watch additional metadata directories (e.g., session_index.jsonl). These provide ShallowWatchRootsFunc that the watcher merges with normal WatchRootsFunc returns.

Complete Sync Workflow

The agentsview CLI orchestrates format management through a six-stage pipeline defined across internal/sync/engine.go and related modules:

  1. Load configuration (internal/config/config.go): Resolve environment overrides and TOML settings
  2. Build watch list: Iterate parser.Registry, skipping non-file-based agents
  3. Discover: Execute each agent's DiscoverFunc to find existing sessions
  4. Parse: Call agent-specific Parse*Session functions to normalize data
  5. Store: Persist normalized ParsedSession objects to SQLite (internal/db/sessions.go)
  6. Serve: Expose data through the HTTP API and SSE endpoints (internal/server/*)

Summary

  • Centralized Registry: The AgentDef struct in internal/parser/types.go defines metadata, discovery functions, and parsing logic for each supported agent.

  • Uniform Interface: All parsers return a standardized ParseResult, allowing the sync engine and API layers to remain agnostic of original file formats.

  • Flexible Discovery: Each agent implements a custom DiscoverFunc (e.g., DiscoverClaudeSessions) to handle its specific directory layout and file patterns.

  • ID Namespacing: Session IDs use agent-specific prefixes (e.g., codex:) except for Claude Code, enabling unambiguous cross-agent identification.

  • Dual Storage Models: File-based agents use recursive or shallow file watching, while database-backed agents query remote PostgreSQL instances, both feeding the same normalized schema.

Frequently Asked Questions

How does agentsview distinguish between different agent session files?

The CLI uses the IDPrefix field in each AgentDef to namespace session identifiers. When processing a session ID, the AgentByPrefix function strips any host prefix and matches the remainder against registered prefixes like codex: or cursor:. Claude Code uses an empty prefix and is identified by the absence of a colon in the UUID, ensuring unambiguous routing to the correct parser.

What is the difference between file-based and database-backed agents in agentsview?

File-based agents (FileBased: true) store sessions as files on disk and are monitored via fsnotify watchers or periodic scans, while database-backed agents (FileBased: false) such as Claude.ai and ChatGPT store data in remote PostgreSQL databases. The CLI queries the latter directly via internal/postgres rather than watching directories, though both types ultimately populate the same ParsedSession struct in SQLite.

How can I configure a custom directory for a specific agent in agentsview?

Set the environment variable specified in the agent's AgentDef.EnvVar field before running the CLI. For example, export COPILOT_DIR=$HOME/my-copilot-sessions overrides the default directory for Copilot sessions. When agentsview sync --agent copilot executes, it resolves the custom path through internal/config/config.go and watches the specified location instead of the default.

Why does agentsview use shallow watching for some agents like Aider?

Agents that generate a high volume of files, such as Aider, set ShallowWatch: true in their AgentDef to avoid the performance cost of recursive inotify registration. Instead of watching the entire directory tree, the CLI watches only the root directory and relies on a periodic 15-minute scan to discover new session files, balancing real-time responsiveness with system resource efficiency.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →