huskies: merge 686_refactor_decompose_server_src_io_watcher_rs_1202_lines

Manual merge resolution: feature branch deleted watcher.rs and split
into watcher/{mod,events,sweep,tests}.rs, while master modified the
old watcher.rs (738's FS-shadow stripping). The auto-resolver kept
both, producing an ambiguous-module compile error.

Resolution: drop watcher.rs (feature's delete wins). The new
watcher/mod.rs absorbs the FS-shadow code semantically — gates pass
(cargo check, clippy --all-targets -D warnings, fmt --check, 29/29
io::watcher tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
dave
2026-04-27 21:55:04 +00:00
parent be7b7025d5
commit 574df48ff3
5 changed files with 1215 additions and 473 deletions
+75
View File
@@ -0,0 +1,75 @@
//! 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,
},
}