From 1a4de26966f0f90adc2e242079c058fd4ea768d4 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 30 Jan 2026 21:12:48 +0100 Subject: [PATCH] feat(06-03): add coordination tRPC procedures - Add coordinationManager to TRPCContext and CreateContextOptions - Add requireCoordinationManager helper function - Add queueMerge mutation for queuing tasks for merge - Add processMerges mutation for processing merges in dependency order - Add getMergeQueueStatus query for queue state inspection - Add getNextMergeable query for next mergeable task --- src/trpc/context.ts | 5 ++++ src/trpc/router.ts | 68 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/trpc/context.ts b/src/trpc/context.ts index 8a42c24..8168876 100644 --- a/src/trpc/context.ts +++ b/src/trpc/context.ts @@ -10,6 +10,7 @@ import type { AgentManager } from '../agent/types.js'; import type { TaskRepository } from '../db/repositories/task-repository.js'; import type { MessageRepository } from '../db/repositories/message-repository.js'; import type { DispatchManager } from '../dispatch/types.js'; +import type { CoordinationManager } from '../coordination/types.js'; // Re-export for convenience export type { EventBus, DomainEvent }; @@ -32,6 +33,8 @@ export interface TRPCContext { messageRepository?: MessageRepository; /** Dispatch manager for task queue operations (optional until server wiring complete) */ dispatchManager?: DispatchManager; + /** Coordination manager for merge queue operations (optional until server wiring complete) */ + coordinationManager?: CoordinationManager; } /** @@ -45,6 +48,7 @@ export interface CreateContextOptions { taskRepository?: TaskRepository; messageRepository?: MessageRepository; dispatchManager?: DispatchManager; + coordinationManager?: CoordinationManager; } /** @@ -62,5 +66,6 @@ export function createContext(options: CreateContextOptions): TRPCContext { taskRepository: options.taskRepository, messageRepository: options.messageRepository, dispatchManager: options.dispatchManager, + coordinationManager: options.coordinationManager, }; } diff --git a/src/trpc/router.ts b/src/trpc/router.ts index 69ae66b..9f9aaf0 100644 --- a/src/trpc/router.ts +++ b/src/trpc/router.ts @@ -12,6 +12,7 @@ import type { AgentInfo, AgentResult } from '../agent/types.js'; import type { TaskRepository } from '../db/repositories/task-repository.js'; import type { MessageRepository } from '../db/repositories/message-repository.js'; import type { DispatchManager } from '../dispatch/types.js'; +import type { CoordinationManager } from '../coordination/types.js'; /** * Initialize tRPC with our context type. @@ -218,6 +219,19 @@ function requireDispatchManager(ctx: TRPCContext): DispatchManager { return ctx.dispatchManager; } +/** + * Helper to ensure coordinationManager is available in context. + */ +function requireCoordinationManager(ctx: TRPCContext): CoordinationManager { + if (!ctx.coordinationManager) { + throw new TRPCError({ + code: 'INTERNAL_SERVER_ERROR', + message: 'Coordination manager not available', + }); + } + return ctx.coordinationManager; +} + // ============================================================================= // Application Router with Procedures // ============================================================================= @@ -245,6 +259,10 @@ function requireDispatchManager(ctx: TRPCContext): DispatchManager { * - dispatchNext: Dispatch next available task * - getQueueState: Get dispatch queue state * - completeTask: Mark a task as complete + * - queueMerge: Queue a completed task for merge + * - processMerges: Process all ready merges in dependency order + * - getMergeQueueStatus: Get merge queue status + * - getNextMergeable: Get next task ready to merge */ export const appRouter = router({ /** @@ -565,6 +583,56 @@ export const appRouter = router({ await dispatchManager.completeTask(input.taskId); return { success: true }; }), + + // =========================================================================== + // Coordination Procedures + // =========================================================================== + + /** + * Queue a completed task for merge. + * Task will be merged when all dependencies complete. + */ + queueMerge: publicProcedure + .input(z.object({ taskId: z.string().min(1) })) + .mutation(async ({ ctx, input }) => { + const coordinationManager = requireCoordinationManager(ctx); + await coordinationManager.queueMerge(input.taskId); + return { success: true }; + }), + + /** + * Process all ready merges in dependency order. + * Returns results of all merge operations. + */ + processMerges: publicProcedure + .input(z.object({ + targetBranch: z.string().default('main'), + })) + .mutation(async ({ ctx, input }) => { + const coordinationManager = requireCoordinationManager(ctx); + const results = await coordinationManager.processMerges(input.targetBranch); + return { results }; + }), + + /** + * Get merge queue status. + * Shows queued, in-progress, merged, and conflicted tasks. + */ + getMergeQueueStatus: publicProcedure + .query(async ({ ctx }) => { + const coordinationManager = requireCoordinationManager(ctx); + return coordinationManager.getQueueState(); + }), + + /** + * Get next task ready to merge. + * Returns task with all dependencies resolved. + */ + getNextMergeable: publicProcedure + .query(async ({ ctx }) => { + const coordinationManager = requireCoordinationManager(ctx); + return coordinationManager.getNextMergeable(); + }), }); /**