# How the agentsview CLI Manages Different Agent Session Formats

> Discover how the agentsview CLI unifies diverse agent session formats using a centralized AgentDef registry and custom parsers, normalizing data into a single SQLite schema. Learn more today.

- Repository: [Kenn Software/agentsview](https://github.com/kenn-io/agentsview)
- Tags: how-to-guide
- Published: 2026-06-20

---

**The agentsview CLI manages different agent session formats through a centralized `AgentDef` registry in [`internal/parser/types.go`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/internal/parser/types.go). This struct serves as a contract that every supported agent must implement:

```go
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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/internal/parser/types.go):

```go
type ParseResult struct {
    Session ParsedSession
    Messages []ParsedMessage
}

```

This contract ensures that downstream components—the SQLite writer in [`internal/db/sessions.go`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/internal/sync/engine.go) and related modules:

1. **Load configuration** ([`internal/config/config.go`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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`](https://github.com/kenn-io/agentsview/blob/main/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.