import { END } from "@uncaged/nerve-core"; import type { Moderator } from "@uncaged/nerve-core"; import { TESTER_MAX_ATTEMPTS } from "./lib/constants.js"; import type { IntakeMeta } from "./roles/intake/index.js"; import type { IssueReaderMeta } from "./roles/issue-reader/index.js"; import type { PlannerMeta } from "./roles/planner/index.js"; import type { ImplementerMeta } from "./roles/implementer/index.js"; import type { ReviewerMeta } from "./roles/reviewer/index.js"; import type { TesterMeta } from "./roles/tester/index.js"; import type { PrPublisherMeta } from "./roles/pr-publisher/index.js"; export type WorkflowMeta = { intake: IntakeMeta; "issue-reader": IssueReaderMeta; planner: PlannerMeta; implementer: ImplementerMeta; reviewer: ReviewerMeta; tester: TesterMeta; "pr-publisher": PrPublisherMeta; }; export const moderator: Moderator = (context) => { if (context.steps.length === 0) { return "intake"; } const last = context.steps[context.steps.length - 1]; if (last.role === "intake") { const meta = last.meta as WorkflowMeta["intake"]; return meta.valid ? "issue-reader" : END; } if (last.role === "issue-reader") { const meta = last.meta as WorkflowMeta["issue-reader"]; if (meta.fetchOk) { return "planner"; } return END; } if (last.role === "planner") { const meta = last.meta as WorkflowMeta["planner"]; return meta.planningOk ? "implementer" : END; } if (last.role === "implementer") { return "reviewer"; } if (last.role === "reviewer") { const meta = last.meta as WorkflowMeta["reviewer"]; if (meta.approved) return "tester"; return "implementer"; } if (last.role === "tester") { const meta = last.meta as WorkflowMeta["tester"]; if (meta.passed) { return "pr-publisher"; } return meta.attempt < TESTER_MAX_ATTEMPTS ? "implementer" : END; } if (last.role === "pr-publisher") { return END; } return END; };