refactor: centralize notifications in core dispatch/completion functions (#150)

This commit is contained in:
Lauren ten Hoor
2026-02-13 17:00:42 +08:00
parent 80587412ee
commit 265f82f3a9
8 changed files with 72 additions and 88 deletions

View File

@@ -18,7 +18,6 @@ import { log as auditLog } from "../audit.js";
import { checkWorkerHealth, fetchGatewaySessions, type SessionLookup } from "./health.js";
import { projectTick } from "./tick.js";
import { createProvider } from "../providers/index.js";
import { notifyTickPickups, getNotificationConfig } from "../notify.js";
// ---------------------------------------------------------------------------
// Types
@@ -281,15 +280,7 @@ export async function tick(opts: {
result.totalPickups += tickResult.pickups.length;
result.totalSkipped += tickResult.skipped.length;
// Notify project group about any pickups
if (tickResult.pickups.length > 0) {
const notifyConfig = getNotificationConfig(pluginConfig);
await notifyTickPickups(tickResult.pickups, {
workspaceDir,
config: notifyConfig,
channel: project.channel,
});
}
// Notifications now handled by dispatchTask
if (isProjectActive || tickResult.pickups.length > 0) activeProjects++;
}

View File

@@ -6,6 +6,7 @@
import type { StateLabel, IssueProvider } from "../providers/provider.js";
import { deactivateWorker } from "../projects.js";
import { runCommand } from "../run-command.js";
import { notify, getNotificationConfig } from "../notify.js";
export type CompletionRule = {
from: StateLabel;
@@ -70,8 +71,11 @@ export async function executeCompletion(opts: {
prUrl?: string;
provider: IssueProvider;
repoPath: string;
projectName: string;
channel?: string;
pluginConfig?: Record<string, unknown>;
}): Promise<CompletionOutput> {
const { workspaceDir, groupId, role, result, issueId, summary, provider, repoPath } = opts;
const { workspaceDir, groupId, role, result, issueId, summary, provider, repoPath, projectName, channel, pluginConfig } = opts;
const key = `${role}:${result}`;
const rule = COMPLETION_RULES[key];
if (!rule) throw new Error(`No completion rule for ${key}`);
@@ -108,6 +112,28 @@ export async function executeCompletion(opts: {
if (prUrl) announcement += `\n🔗 PR: ${prUrl}`;
announcement += `\n${NEXT_STATE[key]}.`;
// Notify workerComplete (non-fatal)
const notifyConfig = getNotificationConfig(pluginConfig);
await notify(
{
type: "workerComplete",
project: projectName,
groupId,
issueId,
issueUrl: issue.web_url,
role,
result: result as "done" | "pass" | "fail" | "refine" | "blocked",
summary,
nextState: NEXT_STATE[key],
},
{
workspaceDir,
config: notifyConfig,
groupId,
channel: channel ?? "telegram",
},
).catch(() => { /* non-fatal */ });
return {
labelTransition: `${rule.from}${rule.to}`,
announcement,

View File

@@ -176,7 +176,9 @@ export async function projectTick(opts: {
role, level: selectedLevel, fromLabel: currentLabel, toLabel: targetLabel,
transitionLabel: (id, from, to) => provider.transitionLabel(id, from as StateLabel, to as StateLabel),
provider: provider as IssueProvider,
pluginConfig, sessionKey,
pluginConfig,
channel: fresh.channel,
sessionKey,
});
pickups.push({
project: project.name, groupId, issueId: issue.iid, issueTitle: issue.title, issueUrl: issue.web_url,