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_DIRfor AgentCopilot)ConfigKey: TOML key inconfig.tomlfor persistent configuration (e.g.,"copilot_dirs")DefaultDirs: Relative paths from$HOMEused as fallbacks (e.g.,".copilot")IDPrefix: Session ID prefix for agent identification (e.g.,"codex:")WatchSubdirs: Subdirectories requiring recursive filesystem monitoringWatchRootsFunc: Optional function to compute dynamic watch rootsShallowWatch: 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
ShallowWatchis false, the watcher monitorsWatchSubdirsrecursively beneath each configured root, catching all file changes immediately. - Shallow watching: When
ShallowWatchis 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:
- Startup:
cmd/agentsview/main.goloads configuration and buildsConfig.AgentDirs - Watcher setup:
internal/sync/engine.gocreatesWatcherinstances for each agent based on theirAgentDefwatch parameters - Live events: The watcher triggers
onChangecallbacks for filesystem events, causing targeted re-parsing of affected sessions - Periodic reconciliation: Every 15 minutes,
engine.SyncAllwalks each agent's directories using theirDiscoverFuncto catch changes missed by shallow watches - API exposure:
internal/server/server.goserves aggregated sessions via REST, preserving theAgentfield 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.gothat declares each agent's metadata, directories, and discovery behavior. - Session directories resolve hierarchically: defaults from
$HOME→ environment variables →config.tomlvalues, implemented ininternal/config/config.go. - Filesystem watching adapts to each agent's storage pattern via
ShallowWatch,WatchSubdirs, andWatchRootsFuncproperties in the Registry. - The sync engine (
internal/sync/engine.go) unifies live watching and periodic 15-minute scans using agent-specificDiscoverFuncimplementations. - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →