feat: in-app Orchestrator (Phase 2) — multi-agent conductor

Brings the deterministic Han-flow conductor into BooCode: launch any read-only
flow from BooChat or BooCoder, watch each agent stream live in a Paseo-style
run pane, get an evidence-disciplined report — on local Qwen, persisted and
resumable. Read-only enforced hard via qwen --approval-mode plan (orchestrator
tasks fail closed if qwen is unavailable; never fall to write-capable native).

Backend (apps/coder): re-homed conductor defs, flow_runs/flow_steps schema,
flow-runner + dispatcher onTaskTerminal hook, restart-resume, runs routes
(launch/list/get/cancel), user-channel WS. Contracts: two flow_run_* frames.
Web: orchestrator pane kind + OrchestratorPane, Workflow button + slash flows
(BooChat/BooCoder parity), FlowLauncherDialog, "New Orchestrator" in the + and
split menus, runs history + export. Plan: openspec/changes/orchestrator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 14:59:07 +00:00
parent 519b1d2ca1
commit 1937af8df9
118 changed files with 15723 additions and 27 deletions

View File

@@ -0,0 +1,129 @@
/**
* Han planning skills as best-effort ONE-PASS flows. Han intends these to be
* human-in-the-loop refinement loops; run unattended they produce a first-draft
* artifact that still gets the adversarial-validator gate. Phase 2 (in-app)
* gives them the interactive surface they really want.
*/
import type { Spine } from '../types.js';
import { q, repoLine } from './_util.js';
export const planFeature: Spine = {
name: 'plan-a-feature',
description: 'feature spec draft (one-pass; human-in-loop intended)',
contracts: ['evidence', 'yagni'],
angles: [
{
id: 'pm',
agent: 'project-manager',
label: 'Scope & requirements (project-manager)',
task: (ctx) =>
`Draft the scope and requirements for the feature below — the problem, the user, in-scope vs out-of-scope, acceptance criteria, and the open questions a team must resolve. Evidence-based; flag assumptions.${repoLine(ctx)}\n\nFEATURE: ${q(ctx)}`,
},
{
id: 'ux',
agent: 'user-experience-designer',
label: 'UX considerations (user-experience-designer)',
minBand: 'medium',
task: (ctx) =>
`Surface the usability and interaction considerations the feature below must address — flows, affordances, accessibility, input modalities, cognitive load.\n\nFEATURE: ${q(ctx)}`,
},
{
id: 'prior',
agent: 'research-analyst',
label: 'Prior art (research-analyst)',
minBand: 'large',
task: (ctx) =>
`Research, with sources, how similar features are typically built and the options/trade-offs worth considering before specifying the feature below. STRICT evidence; no codebase context.\n\nFEATURE: ${q(ctx)}`,
},
],
synthesizer: {
agent: 'software-architect',
label: 'Feature spec draft (software-architect)',
task: (ctx) =>
`Synthesise the inputs below into a first-draft feature spec — problem, scope, a build approach with the components to create/modify, data flow, and a sequenced plan. Mark every unresolved decision as an open question rather than guessing.\n\n----- INPUTS -----\n${ctx.results.fold ?? ''}`,
},
};
export const planImplementation: Spine = {
name: 'plan-implementation',
description: 'implementation plan draft (one-pass)',
contracts: ['evidence', 'yagni'],
angles: [
{
id: 'arch',
agent: 'software-architect',
label: 'Implementation blueprint (software-architect)',
task: (ctx) =>
`Produce an implementation blueprint for the work below — the specific files to create/modify, component designs, data flow, and an ordered build sequence, grounded in the existing codebase patterns. Cite repo/path:line where it anchors on existing code.${repoLine(ctx)}\n\nWORK: ${q(ctx)}`,
},
{
id: 'tests',
agent: 'test-engineer',
label: 'Test strategy (test-engineer)',
minBand: 'medium',
task: (ctx) =>
`Recommend the test strategy that should accompany the implementation below — what to test at which level, and where test doubles isolate collaborators.\n\nWORK: ${q(ctx)}`,
},
],
};
export const planPhasedBuild: Spine = {
name: 'plan-a-phased-build',
description: 'phased build plan draft (one-pass)',
contracts: ['evidence', 'yagni'],
angles: [
{
id: 'pm',
agent: 'project-manager',
label: 'Phasing & sequencing (project-manager)',
task: (ctx) =>
`Break the initiative below into a sequence of independently shippable phases — each with a goal, the slice of work it contains, its dependencies on prior phases, and a definition of done. Flag the riskiest phase.${repoLine(ctx)}\n\nINITIATIVE: ${q(ctx)}`,
},
{
id: 'arch',
agent: 'software-architect',
label: 'Technical sequencing (software-architect)',
minBand: 'medium',
task: (ctx) =>
`Advise on the technical sequencing of the initiative below — which abstractions/boundaries must land first so later phases don't require rework.\n\nINITIATIVE: ${q(ctx)}`,
},
],
};
export const planWorkItems: Spine = {
name: 'plan-work-items',
description: 'break work into tracked items (one-pass)',
contracts: ['evidence', 'yagni'],
angles: [
{
id: 'pm',
agent: 'project-manager',
label: 'Work items (project-manager)',
task: (ctx) =>
`Break the work below into discrete, individually completable work items — each with a clear title, a one-line outcome, its dependencies, and a rough size. Order them by dependency.${repoLine(ctx)}\n\nWORK: ${q(ctx)}`,
},
],
};
export const iterativePlanReview: Spine = {
name: 'iterative-plan-review',
description: 'stress-test an existing plan (one pass of the loop)',
contracts: ['evidence', 'yagni'],
angles: [
{
id: 'junior',
agent: 'junior-developer',
label: 'Generalist stress-test (junior-developer)',
task: (ctx) =>
`Stress-test the plan below as a sharp generalist teammate: reframe it simply, surface hidden assumptions, unstated prerequisites, muddied scope, and the open questions it leaves unanswered. Cite the part of the plan each concern attaches to.${repoLine(ctx)}\n\nPLAN: ${q(ctx)}`,
},
{
id: 'risk',
agent: 'risk-analyst',
label: 'Risk review (risk-analyst)',
minBand: 'medium',
task: (ctx) =>
`Assess the risks the plan below carries or ignores — likelihood, severity, blast radius, reversibility — and which steps most need de-risking before commitment.\n\nPLAN: ${q(ctx)}`,
},
],
};