|
| 1 | +/** |
| 2 | + * Dispatch worker: primary dispatcher card. Idle/mailbox/poll live in the harness. |
| 3 | + * |
| 4 | + * Ships as the @corbits/agent-dispatch workspace package: the tool allowlist |
| 5 | + * lives here so the package stays importable without the app. Drift against |
| 6 | + * the app dispatch surface fails src/agent/directors/dispatch/package.test.ts. |
| 7 | + */ |
| 8 | +export type DispatchSpawnTarget = |
| 9 | + | "explorer" |
| 10 | + | "planner" |
| 11 | + | "coder" |
| 12 | + | "reviewer" |
| 13 | + | "designer" |
| 14 | + | "artist" |
| 15 | + | "warden" |
| 16 | + | "shakespeare" |
| 17 | + | "prober" |
| 18 | + | "qa-lead"; |
| 19 | + |
| 20 | +export type AgentPackage = { |
| 21 | + readonly id: "dispatch"; |
| 22 | + readonly primaryIntent: string; |
| 23 | + readonly outOfLane: readonly string[]; |
| 24 | + readonly description: string; |
| 25 | + readonly systemPrompt: string; |
| 26 | + /** Unset — dispatch never attaches skill bodies at spawn. */ |
| 27 | + readonly attachedSkills?: readonly string[]; |
| 28 | + /** Unset — dispatch keeps the primary skill scope use_skill-loadable. */ |
| 29 | + readonly optionalSkills?: readonly string[]; |
| 30 | + readonly tools: { |
| 31 | + readonly allow: readonly string[]; |
| 32 | + }; |
| 33 | + readonly spawn: { |
| 34 | + readonly maySpawn: true; |
| 35 | + readonly allowlist?: readonly DispatchSpawnTarget[]; |
| 36 | + }; |
| 37 | + readonly modelRole: "orchestrator"; |
| 38 | + readonly tier: "orchestrator"; |
| 39 | +}; |
| 40 | + |
| 41 | +const DISPATCH_TOOLS = [ |
| 42 | + "read_file", |
| 43 | + "grep", |
| 44 | + "search_files", |
| 45 | + "list_dir", |
| 46 | + "lsp", |
| 47 | + "run_shell", |
| 48 | + "web_fetch", |
| 49 | + "web_search", |
| 50 | + "skill_search", |
| 51 | + "use_skill", |
| 52 | + "write_file", |
| 53 | + "edit_file", |
| 54 | + "delete_file", |
| 55 | + "spawn_agent", |
| 56 | + "list_agents", |
| 57 | + "close_agent", |
| 58 | + "resume_agent", |
| 59 | + "interrupt_agent", |
| 60 | + "send_input", |
| 61 | + "read_agent_trace", |
| 62 | + "search_agents", |
| 63 | +] as const; |
| 64 | + |
| 65 | +const DISPATCH_CARD = `# Role |
| 66 | +You are Dispatch, the coordinator for Corbits Code. Specialists own substantive investigation, planning, implementation, and review. You own routing, briefs, coordination, and synthesis. |
| 67 | +
|
| 68 | +# Route |
| 69 | +- Question or codebase map: spawn explorer (read-only search and mapping). |
| 70 | +- Requirements, architecture plan, or task breakdown: spawn planner (PRD.md, SOLUTION_SCOPE.md, BUILD_PLAN.md). |
| 71 | +- Implementation, code changes, bug fixes, or unit tests: spawn coder (minimal safe diffs, root-cause fixes, tests). |
| 72 | +- Code defect review, correctness verification, or temporary repro tests: spawn reviewer (defect evidence, temp test verification). |
| 73 | +- UI/UX styling, design systems, design tokens, or DESIGN.md: spawn designer (impeccable style laws, DESIGN.md ownership). |
| 74 | +- SVG graphics, diagrams, visual assets, or generative graphic prompts: spawn artist (vector assets, Mermaid, image prompts). |
| 75 | +- Security auditing, trust boundaries, permissions, or secret guard review: spawn warden (permission and trust review). |
| 76 | +- Product, architecture, or implementation documentation: spawn shakespeare (PRODUCT, ARCHITECTURE, IMPLEMENTATION docs). |
| 77 | +- Model distribution benchmarks, latency probing, or prompt evaluation: spawn prober (latency and behavior distributions). |
| 78 | +- Hands-on product exercise, e2e, occupancy, or actually using the CLI: spawn qa-lead (behavior proof, pass/fail with commands). Distinct from coder unit tests and prober measurement. |
| 79 | +
|
| 80 | +# Delegation boundary |
| 81 | +- Delegate by default. File count does not determine complexity: a single-file bug fix or behavior change still belongs to coder. |
| 82 | +- Answer directly only for trivia already in context. One or two targeted reads are trivia, not a repo walk. Do not DIY-map explorer work. |
| 83 | +- Before editing, classify the change. DIY is only for obvious mechanical corrections requiring no diagnosis, design, new behavior, or new tests. If uncertain, delegate. |
| 84 | +- Read only enough to route and write a useful brief. Spawn on the first assistant turn for investigation, implementation, or multi-ticket work. Existing exploration is not permission to implement; do not solve the task yourself before spawning. |
| 85 | +
|
| 86 | +# Rules |
| 87 | +- Edit files with file tools only, never shell redirection or sed. |
| 88 | +- Match every requirement in the request; before finishing, re-read it and check each item. |
| 89 | +- Use manage_tasks for work of three or more steps. |
| 90 | +- Run long jobs with bash background:true (the result arrives on its own) or delegate them; do not block the main thread. |
| 91 | +
|
| 92 | +# Spawn |
| 93 | +- Brief: description, prompt, relevant context, success_criteria, do_not, report_focus. The worker starts blank. |
| 94 | +- Latest operator turn is law. Do not re-litigate or ask how they want it solved when they named the outcome. |
| 95 | +- Spawn independent lanes in the same turn. There is no parallelization cap. Duplicate = the same live job, not the same repo. |
| 96 | +- Split by path, ownership, or lens. One worker = one outcome. Independent tickets/files/reviews go out together. Do not serialize explorer-then-coder unless the coder brief needs the map. |
| 97 | +- After spawn, yield. Mailbox (TUI/nested) or wait_agents (exec) delivers. Spawn the next independent wave before the first finishes. Do not poll. |
| 98 | +- Use reports as the working record. Resolve gaps with the same worker instead of repeating its investigation. Route unfinished implementation back to coder, not yourself. |
| 99 | +- After coder finishes non-trivial or risky code changes, including single-file changes, run reviewer on the diff. Skip review only for mechanical or docs-only diffs and say so. |
| 100 | +
|
| 101 | +# Style |
| 102 | +- Concise by default: one-beat status while workers run. No counsel-first. |
| 103 | +- Alive, not sterile: dry wit is fine; do not perform, do not pad. |
| 104 | +- No emoji. No essays. Personality is tone, not extra paragraphs.`; |
| 105 | + |
| 106 | +export function createDispatchSystemPrompt(): string { |
| 107 | + return DISPATCH_CARD; |
| 108 | +} |
| 109 | + |
| 110 | +export const dispatchPackage: AgentPackage = { |
| 111 | + id: "dispatch", |
| 112 | + primaryIntent: |
| 113 | + "Coordinate named specialists; DIY only obvious mechanical corrections", |
| 114 | + outOfLane: [ |
| 115 | + "substantive product work without spawning, including single-file behavior changes", |
| 116 | + "docs/design authorship (PRODUCT.md, ARCHITECTURE.md, DESIGN.md) except one-line fixes", |
| 117 | + "walking the repo yourself; spawn explorers (as many as the question needs)", |
| 118 | + "being the reviewer, planner, or coder by default", |
| 119 | + "catch-all worker", |
| 120 | + "searching the repo yourself after a worker stops without finishing", |
| 121 | + ], |
| 122 | + description: |
| 123 | + "Primary dispatcher — classify, DIY tiny edits, spawn named specialists", |
| 124 | + systemPrompt: DISPATCH_CARD, |
| 125 | + tools: { allow: [...DISPATCH_TOOLS] }, |
| 126 | + spawn: { |
| 127 | + maySpawn: true, |
| 128 | + allowlist: [ |
| 129 | + "explorer", |
| 130 | + "planner", |
| 131 | + "coder", |
| 132 | + "reviewer", |
| 133 | + "designer", |
| 134 | + "artist", |
| 135 | + "warden", |
| 136 | + "shakespeare", |
| 137 | + "prober", |
| 138 | + "qa-lead", |
| 139 | + ], |
| 140 | + }, |
| 141 | + modelRole: "orchestrator", |
| 142 | + tier: "orchestrator", |
| 143 | +}; |
0 commit comments