Files
huskies/server/src/io/watcher/events.rs
T

94 lines
3.9 KiB
Rust
Raw Normal View History

//! Watcher event types emitted to WebSocket clients and internal subscribers.
use serde::Serialize;
/// A lifecycle event emitted by the filesystem watcher.
#[derive(Clone, Debug, Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum WatcherEvent {
/// A work-pipeline file was created, modified, or deleted.
WorkItem {
/// Pipeline stage directory (e.g. `"2_current"`, `"5_archived"`).
stage: String,
/// Work item ID (filename stem without extension, e.g. `"42_story_my_feature"`).
item_id: String,
/// Semantic action inferred from the stage (e.g. `"start"`, `"accept"`).
action: String,
/// The deterministic git commit message used (or that would have been used).
commit_msg: String,
/// The pipeline stage the item moved FROM, populated for move operations.
/// `None` for creations, deletions, or synthetic events.
from_stage: Option<String>,
},
/// `.huskies/project.toml` was modified at the project root (not inside a worktree).
ConfigChanged,
/// An agent's state changed (started, stopped, completed, etc.).
/// Triggers a pipeline state refresh so the frontend can update agent
/// assignments without waiting for a filesystem event.
AgentStateChanged,
/// A story encountered a failure (e.g. merge failure).
/// Triggers an error notification to configured Matrix rooms.
MergeFailure {
/// Work item ID (e.g. `"42_story_my_feature"`).
story_id: String,
/// Human-readable description of the failure.
reason: String,
},
/// An agent hit an API rate limit.
/// Triggers a warning notification to configured chat rooms.
RateLimitWarning {
/// Work item ID the agent is working on.
story_id: String,
/// Name of the agent that hit the rate limit.
agent_name: String,
},
/// A story has been blocked (e.g. retry limit exceeded, empty diff).
/// Triggers a warning notification to configured chat rooms.
StoryBlocked {
/// Work item ID (e.g. `"42_story_my_feature"`).
story_id: String,
/// Human-readable reason the story was blocked.
reason: String,
},
/// An agent hit a hard API rate limit and will be blocked until `reset_at`.
/// Triggers auto-scheduling of a timer and a notification with the resume time.
RateLimitHardBlock {
/// Work item ID the agent is working on.
story_id: String,
/// Name of the agent that hit the hard rate limit.
agent_name: String,
/// UTC instant at which the rate limit resets.
reset_at: chrono::DateTime<chrono::Utc>,
},
/// An OAuth account pool swap succeeded: a different account is now active.
/// Triggers a notification to chat transports naming the new account.
OAuthAccountSwapped {
/// Email address of the newly activated account.
new_email: String,
},
/// All OAuth accounts in the pool are rate-limited — no swap was possible.
/// Triggers a notification to chat transports with the earliest reset time.
OAuthAccountsExhausted {
/// Human-readable message describing when the earliest reset occurs.
earliest_reset_msg: String,
},
2026-04-29 21:28:41 +00:00
/// An agent transitioned to the Running state for a story.
/// Triggers a status notification to configured chat rooms.
AgentStarted {
/// Work item ID the agent is working on.
story_id: String,
/// Name of the agent that started.
agent_name: String,
},
/// An agent finished processing a story (gates passed or failed).
/// Triggers a status notification to configured chat rooms.
AgentCompleted {
/// Work item ID the agent was working on.
story_id: String,
/// Name of the agent that completed.
agent_name: String,
/// `true` if acceptance gates passed; `false` if they failed.
success: bool,
},
}