How Herdr Built-In Agent Integrations Report State
TLDR: Herdr built-in agent integrations report state by checking for versioned installation files at well-known paths, parsing the HERDR_INTEGRATION_VERSION marker, and comparing it against compiled constants to determine if the integration is Current, Outdated, or NotInstalled.
Herdr is an open-source tool that manages AI agent workflows by installing hooks for popular coding assistants like Claude, Codex, and Pi. Understanding how Herdr built-in agent integrations report state is essential for developers building custom UIs or diagnosing installation issues. The system uses a file-based versioning approach defined in src/integration/mod.rs to track the health of every supported agent.
The State Reporting Pipeline
Herdr determines the state of each built-in integration—Pi, Omp, Claude, Codex, Opencode, Hermes, and Qodercli—through a deterministic three-step process.
Locating Installation Files
Each integration has a well-known path generated by integration_specs(). For example, the Claude integration expects its state file at ~/.config/claude/hooks/herdr-agent-state.sh. The function integration_status_at (src/integration/mod.rs‑L138) performs the actual filesystem check to verify the file exists.
Parsing Version Markers
When the installation file exists, Herdr reads its contents to locate the line starting with HERDR_INTEGRATION_VERSION=. The helper parse_integration_version (src/integration/mod.rs‑L52) extracts the numeric version from this marker.
Determining Integration Status
Each integration defines a constant such as PI_INTEGRATION_VERSION = 2. The logic compares the installed version against the expected version:
- If installed version ≥ expected: Current
- If installed version < expected: Outdated
- If file missing: NotInstalled
The IntegrationStatus Data Structure
The result is encapsulated in the IntegrationStatus struct defined in src/integration/mod.rs (lines 87‑94):
pub(crate) struct IntegrationStatus {
pub target: crate::api::schema::IntegrationTarget,
pub path: PathBuf,
pub state: IntegrationStatusKind,
pub installed_version: Option<u32>,
pub expected_version: u32,
}
This structure provides a type-safe representation of the integration's health, including the target agent, filesystem path, and version metadata.
Programmatically Querying Integration State
The ogulcancelik/herdr repository exposes several helper functions to access these statuses in Rust code.
Retrieving All Integration Statuses
To fetch a vector containing the current status for every built-in integration:
use crate::integration;
let statuses = integration::installed_integration_statuses();
for status in statuses {
println!(
"{} → {} (installed: {:?}, expected: {})",
status.target,
status.state_label(),
status.installed_version,
status.expected_version
);
}
Generating UI Recommendations
For CLI or TUI applications that need user-friendly labels and availability information:
use crate::integration;
let recommendations = integration::integration_recommendations();
for rec in recommendations {
println!(
"{} [{}] – {}",
rec.label,
rec.path.display(),
rec.status_label()
);
}
Checking a Single Agent Integration
To manually verify the state of a specific agent like Claude:
use crate::integration;
use crate::api::schema::IntegrationTarget;
let path = integration::claude_dir()
.unwrap()
.join("hooks")
.join(integration::CLAUDE_HOOK_INSTALL_NAME);
let status = integration::integration_status_at(
IntegrationTarget::Claude,
path,
integration::CLAUDE_INTEGRATION_VERSION,
);
println!("Claude integration is {:?}", status.state);
Core Implementation Files
The state reporting logic spans several key files in the repository:
| File | Purpose |
|---|---|
src/integration/mod.rs |
Core logic for locating, installing, and reporting the state of agent integrations. Contains integration_status_at, parse_integration_version, and the IntegrationStatus struct. |
src/api/schema.rs |
Defines the IntegrationTarget enum used to identify each built-in integration. |
src/integration/assets/* |
Sample integration assets containing the HERDR_INTEGRATION_VERSION= marker parsed at runtime. |
Summary
- Herdr built-in agent integrations report state through versioned files at well-known paths like
~/.config/claude/hooks/herdr-agent-state.sh. - The
integration_status_atfunction checks file existence and parses theHERDR_INTEGRATION_VERSIONmarker to determine if the state is Current, Outdated, or NotInstalled. - Version constants such as
PI_INTEGRATION_VERSIONdefine the minimum required version for each integration. - The
IntegrationStatusstruct encapsulates the target agent, path, state, and version metadata for type-safe access. - Helper functions
installed_integration_statuses()andintegration_recommendations()provide high-level APIs for consumption by the CLI and TUI.
Frequently Asked Questions
How does Herdr determine if an agent integration is outdated?
Herdr compares the numeric version parsed from the HERDR_INTEGRATION_VERSION line in the installation file against a compiled constant (e.g., CLAUDE_INTEGRATION_VERSION). If the installed version is less than the expected version, the integration is marked as Outdated; if greater or equal, it is Current.
Where are Herdr integration state files stored?
Each integration follows a well-known path generated by integration_specs(). For example, Claude integrations reside at ~/.config/claude/hooks/herdr-agent-state.sh, while other agents use their respective configuration directories under ~/.config/.
Can I programmatically check a specific integration's state?
Yes. Use the integration_status_at function from src/integration/mod.rs, providing the IntegrationTarget, the specific PathBuf, and the expected version constant. This returns an IntegrationStatus struct containing the state and version metadata for that specific agent.
What happens if the integration file does not exist?
If integration_status_at cannot locate the file at the expected path, it returns an IntegrationStatus with the state field set to NotInstalled and installed_version set to None, allowing the UI to prompt for installation.
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 →