fix(424): add throttled field to all StoryAgent ctors and handle HardBlock in ws.rs

The initial commit added the `throttled` field to `StoryAgent` but missed
several construction sites in lifecycle.rs, test_helpers.rs, and scan.rs.
Also adds the `HardBlock` match arm in the WebSocket event conversion and
minor CSS/import ordering fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dave
2026-03-28 09:55:19 +00:00
parent ebdcf18134
commit 3639d64da6
7 changed files with 19 additions and 12 deletions
+4 -4
View File
@@ -127,13 +127,13 @@ details summary::-webkit-details-marker {
display: none; display: none;
} }
details[open] summary span:first-child { details summary span:first-child {
transform: rotate(90deg);
display: inline-block;
transition: transform 0.2s ease; transition: transform 0.2s ease;
} }
details summary span:first-child { details[open] summary span:first-child {
transform: rotate(90deg);
display: inline-block;
transition: transform 0.2s ease; transition: transform 0.2s ease;
} }
+2 -2
View File
@@ -70,11 +70,11 @@ export type WsResponse =
// Re-export API client types for convenience // Re-export API client types for convenience
export type { export type {
CommandOutput as ApiCommandOutput,
FileEntry as ApiFileEntry,
Message as ApiMessage, Message as ApiMessage,
ProviderConfig as ApiProviderConfig, ProviderConfig as ApiProviderConfig,
FileEntry as ApiFileEntry,
SearchResult as ApiSearchResult, SearchResult as ApiSearchResult,
CommandOutput as ApiCommandOutput,
WsRequest as ApiWsRequest, WsRequest as ApiWsRequest,
WsResponse as ApiWsResponse, WsResponse as ApiWsResponse,
}; };
@@ -154,6 +154,7 @@ mod tests {
project_root: None, project_root: None,
log_session_id: None, log_session_id: None,
merge_failure_reported: false, merge_failure_reported: false,
throttled: false,
} }
} }
+2
View File
@@ -552,6 +552,7 @@ impl AgentPool {
base_branch: None, base_branch: None,
completion: None, completion: None,
log_session_id: Some(log_session_id), log_session_id: Some(log_session_id),
throttled: false,
}) })
} }
@@ -676,6 +677,7 @@ impl AgentPool {
base_branch: None, base_branch: None,
completion: None, completion: None,
log_session_id: None, log_session_id: None,
throttled: false,
} }
}); });
} }
+3 -3
View File
@@ -71,11 +71,11 @@ impl AgentPool {
_ => continue, _ => continue,
}; };
let key = composite_key(&story_id, &agent_name); let key = composite_key(&story_id, &agent_name);
if let Ok(mut agents) = agents_clone.lock() { if let Ok(mut agents) = agents_clone.lock()
if let Some(agent) = agents.get_mut(&key) { && let Some(agent) = agents.get_mut(&key)
{
agent.throttled = true; agent.throttled = true;
} }
}
let _ = watcher_tx_clone.send(WatcherEvent::AgentStateChanged); let _ = watcher_tx_clone.send(WatcherEvent::AgentStateChanged);
} }
}); });
+4
View File
@@ -33,6 +33,7 @@ impl AgentPool {
project_root: None, project_root: None,
log_session_id: None, log_session_id: None,
merge_failure_reported: false, merge_failure_reported: false,
throttled: false,
}, },
); );
tx tx
@@ -68,6 +69,7 @@ impl AgentPool {
project_root: None, project_root: None,
log_session_id: None, log_session_id: None,
merge_failure_reported: false, merge_failure_reported: false,
throttled: false,
}, },
); );
tx tx
@@ -100,6 +102,7 @@ impl AgentPool {
project_root: Some(project_root), project_root: Some(project_root),
log_session_id: None, log_session_id: None,
merge_failure_reported: false, merge_failure_reported: false,
throttled: false,
}, },
); );
tx tx
@@ -131,6 +134,7 @@ impl AgentPool {
project_root: None, project_root: None,
log_session_id: None, log_session_id: None,
merge_failure_reported: false, merge_failure_reported: false,
throttled: false,
}, },
); );
tx tx
+2 -2
View File
@@ -158,8 +158,8 @@ impl From<WatcherEvent> for Option<WsResponse> {
}), }),
WatcherEvent::ConfigChanged => Some(WsResponse::AgentConfigChanged), WatcherEvent::ConfigChanged => Some(WsResponse::AgentConfigChanged),
WatcherEvent::AgentStateChanged => Some(WsResponse::AgentStateChanged), WatcherEvent::AgentStateChanged => Some(WsResponse::AgentStateChanged),
// MergeFailure, RateLimitWarning, and StoryBlocked are handled by the // MergeFailure, RateLimitWarning, StoryBlocked, and RateLimitHardBlock are handled
// chat notification listener only; no WebSocket message is needed for the frontend. // by the chat notification listener only; no WebSocket message is needed for the frontend.
WatcherEvent::MergeFailure { .. } => None, WatcherEvent::MergeFailure { .. } => None,
WatcherEvent::RateLimitWarning { .. } => None, WatcherEvent::RateLimitWarning { .. } => None,
WatcherEvent::StoryBlocked { .. } => None, WatcherEvent::StoryBlocked { .. } => None,