2026-04-27 21:55:04 +00:00
|
|
|
//! 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,
|
|
|
|
|
},
|
2026-05-15 00:30:07 +00:00
|
|
|
/// A new work item was successfully created and added to the backlog.
|
|
|
|
|
/// Triggers a creation notification to configured chat rooms.
|
|
|
|
|
NewItemCreated {
|
|
|
|
|
/// Work item ID (e.g. `"1075_refactor_split_stage_enum"`).
|
|
|
|
|
item_id: String,
|
|
|
|
|
/// Human-readable item type (`"story"`, `"bug"`, `"refactor"`, `"spike"`).
|
|
|
|
|
item_type: String,
|
|
|
|
|
/// Human-readable item name.
|
|
|
|
|
name: String,
|
|
|
|
|
},
|
2026-04-27 21:55:04 +00:00
|
|
|
}
|