diff --git a/src/trpc/router.ts b/src/trpc/router.ts index f54b2ef..10fc278 100644 --- a/src/trpc/router.ts +++ b/src/trpc/router.ts @@ -17,7 +17,7 @@ import type { PlanRepository } from '../db/repositories/plan-repository.js'; import type { DispatchManager } from '../dispatch/types.js'; import type { CoordinationManager } from '../coordination/types.js'; import type { Phase, Plan, Task } from '../db/schema.js'; -import { buildDiscussPrompt, buildBreakdownPrompt } from '../agent/prompts.js'; +import { buildDiscussPrompt, buildBreakdownPrompt, buildDecomposePrompt } from '../agent/prompts.js'; /** * Initialize tRPC with our context type. @@ -1056,6 +1056,49 @@ export const appRouter = router({ mode: 'breakdown', }); }), + + /** + * Spawn architect in decompose mode. + * Uses comprehensive decompose prompt to break a plan into executable tasks. + */ + spawnArchitectDecompose: publicProcedure + .input(z.object({ + name: z.string().min(1), + planId: z.string().min(1), + context: z.string().optional(), + })) + .mutation(async ({ ctx, input }) => { + const agentManager = requireAgentManager(ctx); + const planRepo = requirePlanRepository(ctx); + const phaseRepo = requirePhaseRepository(ctx); + + // 1. Get plan and its phase + const plan = await planRepo.findById(input.planId); + if (!plan) { + throw new TRPCError({ + code: 'NOT_FOUND', + message: `Plan '${input.planId}' not found`, + }); + } + const phase = await phaseRepo.findById(plan.phaseId); + if (!phase) { + throw new TRPCError({ + code: 'NOT_FOUND', + message: `Phase '${plan.phaseId}' not found`, + }); + } + + // 2. Build decompose prompt + const prompt = buildDecomposePrompt(plan, phase, input.context); + + // 3. Spawn agent in decompose mode + return agentManager.spawn({ + name: input.name, + taskId: input.planId, // Associate with plan + prompt, + mode: 'decompose', + }); + }), }); /**