How Agentsview Manages Multiple Agents and Their Session Directories

Agentsview manages multiple agents through a centralized Registry in internal/parser/types.go that defines each agent's session directories, environment overrides, and discovery functions, while a unified sync engine in internal/sync/engine.go coordinates filesystem watching and periodic scanning across all configured agent types.

Agentsview is an open-source session aggregator for AI coding assistants like Claude, Copilot, and Codex. Instead of hardcoding agent-specific logic throughout the codebase, Agentsview manages multiple agents and their session directories through a declarative registry pattern that separates agent metadata from synchronization mechanics. This design allows the system to support new agents by adding entries to a single configuration structure rather than modifying core logic.

The Agent Registry: Centralized Agent Definitions

The foundation of multi-agent support lives in internal/parser/types.go, where the Registry slice enumerates all supported agents. Each entry is an AgentDef struct that encapsulates everything the system needs to know about an agent's storage layout and discovery behavior.

AgentDef Structure

The AgentDef struct defines multiple configuration vectors for each agent:

  • EnvVar: Environment variable that overrides default directories (e.g., COPILOT_DIR for AgentCopilot)
  • ConfigKey: TOML key in config.toml for persistent configuration (e.g., "copilot_dirs")
  • DefaultDirs: Relative paths from $HOME used as fallbacks (e.g., ".copilot")
  • IDPrefix: Session ID prefix for agent identification (e.g., "codex:")
  • WatchSubdirs: Subdirectories requiring recursive filesystem monitoring
  • WatchRootsFunc: Optional function to compute dynamic watch roots
  • ShallowWatch: Boolean indicating whether to watch only root directories (true for Aider)
  • FileBased: Boolean indicating file-storage vs database-storage agents (false for Claude-AI, ChatGPT)
  • DiscoverFunc: Function pointer to locate session files (e.g., DiscoverCodexSessions)
  • FindSourceFunc: Function to resolve source files for a given session

Resolving Session Directories

Agentsview implements a hierarchical configuration system that resolves session directories through three layering mechanisms defined in internal/config/config.go.

Default Directory Initialization

When the application starts, config.Default() constructs a map of default directories for every registered agent based on their AgentDef.DefaultDirs values. These paths are relative to the user's home directory and serve as the base configuration layer.

Environment Variable Overrides

The config.loadEnv() function (lines 52-57 in internal/config/config.go) iterates over the Registry and checks for the presence of each agent's EnvVar. When set, this value replaces the default directory entirely:

// Conceptual representation of the environment loading logic
for _, def := range parser.Registry {
    if envPath := os.Getenv(def.EnvVar); envPath != "" {
        cfg.AgentDirs[def.Type] = []string{envPath}
    }
}

Configuration File Layering

The config.applyConfigTOML() function (lines 645-682 in internal/config/config.go) reads the user's config.toml and applies agent-specific directory arrays for any ConfigKey defined in the Registry. These values override defaults unless the environment variable has already been set, establishing the final configuration in Config.AgentDirs.

The Config.ResolveDirs(agent) helper provides a clean interface to retrieve the definitive directory list for any agent type:

cfg, _ := config.LoadMinimal()
codexDirs := cfg.ResolveDirs(parser.AgentCodex)
fmt.Println("Codex session dirs:", codexDirs)

Filesystem Watching and Synchronization

The sync engine coordinates monitoring across heterogeneous agent storage layouts through agent-specific watch strategies implemented in internal/sync/engine.go and internal/sync/watcher.go.

Watcher Initialization Strategy

Around line 2535 in internal/sync/engine.go, the engine initializes watchers for each agent by evaluating their AgentDef properties:

for _, def := range parser.Registry {
    dirs := cfg.ResolveDirs(def.Type)
    // Configure watching based on def.WatchSubdirs, def.WatchRootsFunc, def.ShallowWatch
}

Shallow vs. Deep Watching

Agentsview supports two monitoring modes:

  • Recursive watching: When ShallowWatch is false, the watcher monitors WatchSubdirs recursively beneath each configured root, catching all file changes immediately.
  • Shallow watching: When ShallowWatch is true (as with Aider), the watcher registers only the root directory and relies on a 15-minute periodic sync to detect deeper changes, reducing filesystem overhead.

The Sync Pipeline

The synchronization workflow follows a deterministic sequence:

  1. Startup: cmd/agentsview/main.go loads configuration and builds Config.AgentDirs
  2. Watcher setup: internal/sync/engine.go creates Watcher instances for each agent based on their AgentDef watch parameters
  3. Live events: The watcher triggers onChange callbacks for filesystem events, causing targeted re-parsing of affected sessions
  4. Periodic reconciliation: Every 15 minutes, engine.SyncAll walks each agent's directories using their DiscoverFunc to catch changes missed by shallow watches
  5. API exposure: internal/server/server.go serves aggregated sessions via REST, preserving the Agent field for UI grouping

Session Discovery and Parsing

Discovery logic varies between file-based and database-backed agents.

File-Based Discovery

For file-based agents (where FileBased is true), the sync engine invokes the agent's DiscoverFunc during engine.SyncAll. For example, DiscoverCodexSessions walks the filesystem roots returned by ResolveDirs and returns DiscoveredFile slices. The engine then parses these into ParsedSession structs.

Database-Backed Agents

When FileBased is false (as with AgentClaudeAI or ChatGPT), the DiscoverFunc queries the agent's native storage rather than walking filesystem paths. This abstraction allows Agentsview to handle both local file sessions and cloud-synchronized conversations through the same interface.

You can enumerate all registered agents and their prefixes:

for _, def := range parser.Registry {
    fmt.Printf("%s (%s) → prefix %q\n",
        def.DisplayName, def.Type, def.IDPrefix)
}

To manually trigger synchronization for a specific agent:

engine := sync.NewEngine(cfg, db)
for _, def := range parser.Registry {
    if def.Type == parser.AgentWorkBuddy {
        engine.SyncAgent(def)
    }
}

Summary

  • Agentsview manages multiple agents through a central Registry in internal/parser/types.go that declares each agent's metadata, directories, and discovery behavior.
  • Session directories resolve hierarchically: defaults from $HOME → environment variables → config.toml values, implemented in internal/config/config.go.
  • Filesystem watching adapts to each agent's storage pattern via ShallowWatch, WatchSubdirs, and WatchRootsFunc properties in the Registry.
  • The sync engine (internal/sync/engine.go) unifies live watching and periodic 15-minute scans using agent-specific DiscoverFunc implementations.
  • All agents expose sessions through a common REST API that preserves agent type information for client-side grouping.

Frequently Asked Questions

How does Agentsview determine which directories to monitor for each agent?

Agentsview consults the AgentDef struct in internal/parser/types.go for each registered agent. It first resolves directories via Config.ResolveDirs(), checking environment variables (lines 52-57 in internal/config/config.go) and config.toml entries before falling back to DefaultDirs. The watcher then applies agent-specific rules from WatchSubdirs or WatchRootsFunc to establish monitoring boundaries.

What is the difference between shallow watching and recursive watching in Agentsview?

Shallow watching (enabled when AgentDef.ShallowWatch is true) registers only the root session directory with the filesystem watcher, relying on periodic 15-minute syncs to detect deeper changes. Recursive watching monitors the full subdirectory tree defined in WatchSubdirs, providing immediate change detection but higher resource usage. The sync engine selects the strategy per-agent based on Registry configuration in internal/sync/engine.go.

Can I override the default session directories for a specific agent?

Yes. Agentsview checks the environment variable defined in the agent's EnvVar field first, then the TOML key defined in ConfigKey. For example, setting COPILOT_DIR=/custom/path overrides the default .copilot directory. These overrides are processed during config.Load() in internal/config/config.go before the sync engine initializes.

How does Agentsview handle agents that store sessions in databases rather than files?

Agentsview distinguishes these through the FileBased boolean in AgentDef. When false (as with Claude-AI or ChatGPT), the agent's DiscoverFunc queries the database or API rather than walking filesystem paths. The sync engine treats these identically after discovery, converting results to ParsedSession structs regardless of the original storage medium.

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 →