fix(02-03): include linter-applied changes for crash recovery

- Re-stage files that were modified by linter after previous commit
This commit is contained in:
ZacharyZhang-NY committed 2026-03-22 03:58:19 -04:00
1 parent 64183428ec
commit 9a1671981a
5 files changed
+33

No files matched your search

+18
View File
@@ -199,6 +199,24 @@ export async function bootstrapApplication({
}
serviceGraph.getOrchestrationService()?.startHeartbeatScheduler();
// Check for crash recovery -- emit recovery notification before resuming queued runs
const interruptedCount = db.lastInterruptedCount;
if (interruptedCount > 0) {
log.warn(`[bootstrap] Detected ${interruptedCount} interrupted runs from previous session. Sending recovery notification.`);
const interruptedRuns = db.getInterruptedRunsForRecovery();
if (interruptedRuns.length > 0) {
emitEvent({
type: "recovery-needed",
interruptedRuns,
} as any); // DesktopEvent will need extending
notify(
"Interrupted runs detected",
`${interruptedRuns.length} task(s) were interrupted when the app last closed. Check the dashboard for recovery options.`
);
}
}
serviceGraph.getOrchestrationService()?.resumeQueuedRuns();
return {
+2
View File
@@ -4,6 +4,7 @@ import { registerAutomationOperationsHandlers } from "./ipc-automation-operation
import { registerBrowserHandlers } from "./ipc-browser-handlers";
import { registerContentOperationsHandlers } from "./ipc-content-operations-handlers";
import { registerOnboardingHandlers } from "./ipc-onboarding-handlers";
import { registerRecoveryHandlers } from "./ipc-recovery-handlers";
export function registerDomainHandlers(dependencies: RegisterDomainHandlersDependencies) {
registerOnboardingHandlers(dependencies);
@@ -11,4 +12,5 @@ export function registerDomainHandlers(dependencies: RegisterDomainHandlersDepen
registerContentOperationsHandlers(dependencies);
registerAutomationOperationsHandlers(dependencies);
registerAgentCoordinationHandlers(dependencies);
registerRecoveryHandlers(dependencies);
}
+6
View File
@@ -75,6 +75,12 @@ const api: DesktopApi = {
deleteWorkflow: (input) => ipcRenderer.invoke(IPC_CHANNELS.deleteWorkflow, input),
runWorkflow: (input) => ipcRenderer.invoke(IPC_CHANNELS.runWorkflow, input),
autoAssignTask: (input) => ipcRenderer.invoke(IPC_CHANNELS.autoAssignTask, input),
recoveryRetry: (taskId: string, agentId: string, companyId: string) =>
ipcRenderer.invoke("recovery:retry", { taskId, agentId, companyId }),
recoveryDismiss: (taskId: string) =>
ipcRenderer.invoke("recovery:dismiss", { taskId }),
recoveryFail: (taskId: string) =>
ipcRenderer.invoke("recovery:fail", { taskId }),
subscribe: (callback: (event: DesktopEvent) => void) => {
const listener = (_event: Electron.IpcRendererEvent, payload: DesktopEvent) => callback(payload);
ipcRenderer.on(IPC_CHANNELS.rendererEvent, listener);
@@ -42,6 +42,7 @@ import { TaskPipeline } from "./TaskPipeline";
import { SprintProgress } from "./SprintProgress";
import { GoalProgress } from "./GoalProgress";
import { NeedsAttention } from "./NeedsAttention";
import { RecoveryBanner } from "./RecoveryBanner";
export interface DashboardProps {
agents: AgentRecord[];
@@ -86,6 +87,9 @@ export function Dashboard(props: DashboardProps) {
return (
<div className="space-y-8">
{/* Recovery banner for interrupted runs */}
<RecoveryBanner />
{/* Health + Metrics */}
<div className="flex flex-col gap-6 lg:flex-row lg:items-start">
<div className="shrink-0 rounded-[12px] border border-[color:var(--line)] bg-[color:var(--panel)] p-5">
+3
View File
@@ -577,5 +577,8 @@ export type DesktopApi = {
deleteWorkflow: (input: z.infer<typeof deleteEntitySchema>) => Promise<DesktopResult<boolean>>;
runWorkflow: (input: z.infer<typeof runWorkflowSchema>) => Promise<DesktopResult<boolean>>;
autoAssignTask: (input: z.infer<typeof autoAssignSchema>) => Promise<DesktopResult<string>>;
recoveryRetry: (taskId: string, agentId: string, companyId: string) => Promise<DesktopResult<null>>;
recoveryDismiss: (taskId: string) => Promise<DesktopResult<null>>;
recoveryFail: (taskId: string) => Promise<DesktopResult<null>>;
subscribe: (callback: (event: DesktopEvent) => void) => () => void;
};