From 5124209ddb088657249d07cada4d3ed132369b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Fri, 27 Mar 2026 19:45:30 -0400 Subject: [PATCH] feat(09-02): convert high-frequency callsites to granular emitEvent - Replace publishDomainChanged() with granular events at 9 high-frequency callsites - saveTask/deleteTask emit task-updated events in ipc-core-work-graph-handlers - decideApproval emits approval-updated, addComment emits task-updated - worker-service emits run-updated for status changes and completion - worker-service emits agent-updated for budget hard-stop pause - orchestration-service emits agent-updated for auto-pause, run-updated for dispatch - Wire emitEvent dependency to orchestration-service via service-graph - Keep publishDomainChanged for low-frequency and multi-entity paths Co-Authored-By: Claude Opus 4.6 (1M context) --- src/main/ipc-core-operations-handlers.ts | 4 ++-- src/main/ipc-core-work-graph-handlers.ts | 10 ++++++++-- src/main/orchestration-service.ts | 8 +++++--- src/main/service-graph.ts | 1 + src/main/worker-service.ts | 8 ++++---- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/ipc-core-operations-handlers.ts b/src/main/ipc-core-operations-handlers.ts index 5f29d810..13716450 100644 --- a/src/main/ipc-core-operations-handlers.ts +++ b/src/main/ipc-core-operations-handlers.ts @@ -114,7 +114,7 @@ export function registerCoreOperationHandlers({ decisionNote: parsed.decisionNote, detail: parsed.decisionNote, }); - publishDomainChanged(); + emitEvent({ type: "approval-updated", approvalId: approval.id, action: "decided" }); return ok(true); }); @@ -179,7 +179,7 @@ export function registerCoreOperationHandlers({ detail: parsed.body.slice(0, 100), }); emitEvent({ type: "agent-message", taskId: parsed.taskId, comment }); - publishDomainChanged(); + emitEvent({ type: "task-updated", taskId: parsed.taskId, action: "updated" }); try { const task = db.getTask(parsed.taskId); if (task.assigneeAgentId) { diff --git a/src/main/ipc-core-work-graph-handlers.ts b/src/main/ipc-core-work-graph-handlers.ts index 9ac2a941..e9992df4 100644 --- a/src/main/ipc-core-work-graph-handlers.ts +++ b/src/main/ipc-core-work-graph-handlers.ts @@ -18,6 +18,7 @@ export function registerCoreWorkGraphHandlers({ ensureCompanyExists, findInvalidReference, publishDomainChanged, + emitEvent, wakeAgentIfPossible, handleApprovalResolved, handleTaskCreated, @@ -29,6 +30,7 @@ export function registerCoreWorkGraphHandlers({ | "ensureCompanyExists" | "findInvalidReference" | "publishDomainChanged" + | "emitEvent" | "wakeAgentIfPossible" | "handleApprovalResolved" | "handleTaskCreated" @@ -355,7 +357,7 @@ export function registerCoreWorkGraphHandlers({ wakeAgentIfPossible(parsed.assigneeAgentId, parsed.companyId, "assignment"); } } - publishDomainChanged(); + emitEvent({ type: "task-updated", taskId: id, action: isNew ? "created" : "updated" }); return ok(id); }); @@ -437,7 +439,11 @@ export function registerCoreWorkGraphHandlers({ entityId: parsed.id, detail: "", }); - publishDomainChanged(); + if (entity === "task") { + emitEvent({ type: "task-updated", taskId: parsed.id, action: "deleted" }); + } else { + publishDomainChanged(); + } return ok(true); }); } diff --git a/src/main/orchestration-service.ts b/src/main/orchestration-service.ts index e6e40a36..4bb27276 100644 --- a/src/main/orchestration-service.ts +++ b/src/main/orchestration-service.ts @@ -54,6 +54,7 @@ interface OrchestrationDependencies { error: (...args: unknown[]) => void; }; publishDomainChanged: () => void; + emitEvent: (event: any) => void; notify: (options: NotificationOptions) => void; createRunToken: (agentId: string, companyId: string, runId: string) => string; getApiPort: () => number; @@ -67,6 +68,7 @@ export function createOrchestrationService({ db, logger, publishDomainChanged, + emitEvent, notify, createRunToken, getApiPort, @@ -138,7 +140,7 @@ export function createOrchestrationService({ navigation: { section: "agents", entityId: agent.id }, batchKey: "agent_paused", }); - publishDomainChanged(); + emitEvent({ type: "agent-updated", agentId: agent.id, action: "paused" }); return true; } @@ -449,7 +451,7 @@ export function createOrchestrationService({ entityId: agent.id, detail: `${trigger} heartbeat for ${agent.name}`, }); - publishDomainChanged(); + emitEvent({ type: "run-updated", runId: run.id, action: "created" }); return run.id; } @@ -560,7 +562,7 @@ export function createOrchestrationService({ entityId: run.id, detail: task.title, }); - publishDomainChanged(); + emitEvent({ type: "run-updated", runId: run.id, action: "created" }); return ok(run.id); } diff --git a/src/main/service-graph.ts b/src/main/service-graph.ts index aae90abd..1c13dadb 100644 --- a/src/main/service-graph.ts +++ b/src/main/service-graph.ts @@ -169,6 +169,7 @@ export function createServiceGraph({ db, logger, publishDomainChanged, + emitEvent, notify, createRunToken, getApiPort: () => apiServerRef.current?.getPort() ?? 0, diff --git a/src/main/worker-service.ts b/src/main/worker-service.ts index a29496a1..f967d6e8 100644 --- a/src/main/worker-service.ts +++ b/src/main/worker-service.ts @@ -46,7 +46,7 @@ interface WorkerServiceDependencies { workerPath: string; isQuitting: () => boolean; publishDomainChanged: () => void; - emitEvent: (event: WorkerUiEvent) => void; + emitEvent: (event: any) => void; wakeAgentIfPossible: (agentId: string | null | undefined, companyId: string, trigger: string) => string | null; dispatchRunToWorker: (params: { runId: string; @@ -239,7 +239,7 @@ export function createWorkerService({ } } emitEvent(event); - publishDomainChanged(); + emitEvent({ type: "run-updated", runId: event.runId, action: "status_changed" }); return; } @@ -280,7 +280,7 @@ export function createWorkerService({ entityId: run.id, detail: event.summary ?? event.errorMessage ?? "", }); - publishDomainChanged(); + emitEvent({ type: "run-updated", runId: run.id, action: "completed" }); emitEvent({ type: "run-status", runId: run.id, @@ -320,7 +320,7 @@ export function createWorkerService({ navigation: { section: "agents", entityId: updatedAgent.id }, batchKey: "agent_paused", }); - publishDomainChanged(); + emitEvent({ type: "agent-updated", agentId: updatedAgent.id, action: "paused" }); } if ((event.status === "failed" || event.status === "timed_out") && !isQuitting() && !destroyed) {