Skip to main content

Integration

Trait Integration 

Source
pub trait Integration: Send + Sync {
    // Required methods
    fn id(&self) -> &'static str;
    fn display_name(&self) -> &'static str;
    fn supported_scopes(&self) -> &'static [ScopeKind];
    fn status(
        &self,
        scope: &Scope,
        tag: &str,
    ) -> Result<StatusReport, AgentConfigError>;
    fn plan_install(
        &self,
        scope: &Scope,
        spec: &HookSpec,
    ) -> Result<InstallPlan, AgentConfigError>;
    fn plan_uninstall(
        &self,
        scope: &Scope,
        tag: &str,
    ) -> Result<UninstallPlan, AgentConfigError>;
    fn install(
        &self,
        scope: &Scope,
        spec: &HookSpec,
    ) -> Result<InstallReport, AgentConfigError>;
    fn uninstall(
        &self,
        scope: &Scope,
        tag: &str,
    ) -> Result<UninstallReport, AgentConfigError>;

    // Provided methods
    fn is_installed(
        &self,
        scope: &Scope,
        tag: &str,
    ) -> Result<bool, AgentConfigError> { ... }
    fn validate(
        &self,
        scope: &Scope,
        tag: &str,
    ) -> Result<ValidationReport, AgentConfigError> { ... }
    fn migrate(
        &self,
        _scope: &Scope,
        _tag: &str,
    ) -> Result<MigrationReport, AgentConfigError> { ... }
}
Expand description

One AI harness’s hook installer.

The trait is intentionally narrow so adding a new harness is a small, mechanical exercise: implement Integration, then register it in crate::registry::all.

All operations must be idempotent: calling install twice with the same spec, or uninstall twice with the same tag, must produce the same end state as calling once.

Required Methods§

Source

fn id(&self) -> &'static str

Stable, kebab-case identifier (e.g., "claude", "cursor").

Source

fn display_name(&self) -> &'static str

Human-readable name (e.g., "Claude Code").

Source

fn supported_scopes(&self) -> &'static [ScopeKind]

Which scopes this integration accepts.

Source

fn status( &self, scope: &Scope, tag: &str, ) -> Result<StatusReport, AgentConfigError>

Detailed installation state for the hook identified by tag.

Distinguishes installed-by-us from installed-by-someone-else, surfaces drift (parse failures, duplicate entries), and reports any pending .bak files. See StatusReport for the full shape.

§Errors

Parse failures are intentionally folded into a StatusReport with crate::status::DriftIssue::InvalidConfig rather than surfaced as errors.

Source

fn plan_install( &self, scope: &Scope, spec: &HookSpec, ) -> Result<InstallPlan, AgentConfigError>

Plan a hook install without mutating user files.

§Errors
Source

fn plan_uninstall( &self, scope: &Scope, tag: &str, ) -> Result<UninstallPlan, AgentConfigError>

Plan a hook uninstall without mutating user files.

§Errors

Same envelope as plan_install. Predictable refusals (unsupported scope, owner mismatch) are encoded as crate::plan::PlanStatus::Refused.

Source

fn install( &self, scope: &Scope, spec: &HookSpec, ) -> Result<InstallReport, AgentConfigError>

Install the hook. Repeated calls with the same spec.tag are a no-op after the first (the on-disk state is reached, then preserved).

§Errors
Source

fn uninstall( &self, scope: &Scope, tag: &str, ) -> Result<UninstallReport, AgentConfigError>

Uninstall the hook identified by tag. Restores .bak files when removing our content leaves the target file empty or pristine.

§Errors

Same envelope as install. Hooks have no separate ownership ledger (the tag is the owner), so there is no AgentConfigError::NotOwnedByCaller arm here.

Provided Methods§

Source

fn is_installed( &self, scope: &Scope, tag: &str, ) -> Result<bool, AgentConfigError>

Returns true if a hook with this tag is currently installed in this scope. Used by CLI consumers to render install/uninstall state.

Default impl matches on the richer status result and treats InstallStatus::InstalledOwned and InstallStatus::InstalledOtherOwner as installed; agents that have already implemented status get this for free.

§Errors

Propagates whatever status returns: typically AgentConfigError::PathResolution, AgentConfigError::Io, AgentConfigError::JsonInvalid, or AgentConfigError::ConfigTooLarge.

Source

fn validate( &self, scope: &Scope, tag: &str, ) -> Result<ValidationReport, AgentConfigError>

Validate hook state without mutating user files.

Unlike status, this reports whether the discovered state is internally consistent and safe to repair.

§Errors
Source

fn migrate( &self, _scope: &Scope, _tag: &str, ) -> Result<MigrationReport, AgentConfigError>

Migrate any prior layout produced by an earlier version of the consumer (e.g., remove a legacy shell-script wrapper that has since been superseded by a native binary). Default impl is a no-op.

§Errors

Implementation-defined; the default returns MigrationReport::NoOp unconditionally. Concrete impls typically return AgentConfigError::Io or AgentConfigError::PathResolution.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§