Let agents see rendered diagrams and drop Mermaid support

This commit is contained in:
Ian Gulliver
2026-10-21 15:41:51 -07:00
parent ab91285dd4
commit 056c3d202a
18 changed files with 506 additions and 980 deletions
+14 -28
View File
@@ -5,39 +5,26 @@ typealias WorkflowRun = Components.Schemas.WorkflowRun
typealias RunStage = Components.Schemas.WorkflowRunStage
typealias StageAttempt = Components.Schemas.StageAttempt
private let stateColors: [RunStage.StatePayload: NodeColors] = [
.waiting: NodeColors(fill: Palette.surface, stroke: Palette.border, text: Palette.muted),
.running: NodeColors(fill: Palette.accentTint, stroke: Palette.accent, text: Palette.text),
.idle: NodeColors(fill: Palette.surface, stroke: Palette.border, text: Palette.muted),
.finished: NodeColors(fill: Palette.okTint, stroke: Palette.ok, text: Palette.text),
.merged: NodeColors(fill: Palette.okTint, stroke: Palette.ok, text: Palette.text),
.cleanedUp: NodeColors(fill: Palette.okTint, stroke: Palette.ok, text: Palette.text),
.discarded: NodeColors(fill: Palette.dangerTint, stroke: Palette.danger, text: Palette.text),
private let stateTints: [RunStage.StatePayload: BoxTint] = [
.waiting: .plain,
.running: .blue,
.idle: .plain,
.finished: .green,
.merged: .green,
.cleanedUp: .green,
.discarded: .red,
]
private func stageSteps(_ steps: [WorkflowStep]) -> [WorkflowStep] {
steps.flatMap { s in s.order.map(stageSteps) ?? s.parallel.map(stageSteps) ?? [s] }
}
private func stageGraph(_ run: WorkflowRun) -> Flowchart {
var chart = Flowchart(direction: .td)
private func runDiagram(_ run: WorkflowRun) -> String {
let steps = Dictionary(stageSteps(run.definition.steps).map { ($0.stage ?? "", $0) }, uniquingKeysWith: { a, _ in a })
for (i, s) in run.stages.enumerated() {
let id = "s\(i)"
let colors = stateColors[s.state]!
chart.node(id, label: s.name, shape: .box)
chart.nodes[id]!.style = colors
chart.nodes[id]!.members = teamNodes(id, steps[s.name]?.agents, stroke: colors.stroke)
}
let ids = Dictionary(run.stages.enumerated().map { ($0.element.name, "s\($0.offset)") }, uniquingKeysWith: { a, _ in a })
for s in run.stages {
for a in s.after {
if let from = ids[a], let to = ids[s.name] {
chart.edges.append(FlowEdge(from: from, to: to, label: nil, style: .solid, arrow: true))
}
}
}
return chart
let index = Dictionary(run.stages.enumerated().map { ($0.element.name, $0.offset) }, uniquingKeysWith: { a, _ in a })
return stageDiagram(run.stages.map { s in
GraphStage(name: s.name, tint: stateTints[s.state]!, agents: steps[s.name]?.agents, after: s.after.compactMap { index[$0] })
})
}
private func attemptLabel(_ a: StageAttempt) -> String {
@@ -103,8 +90,7 @@ struct WorkflowView: View {
.modifier(HeaderBar())
ScrollView {
VStack(alignment: .leading, spacing: 12) {
FlowchartCanvas(layout: layoutFlowchart(stageGraph(run)))
.frame(maxWidth: .infinity, alignment: .leading)
BoxDiagramView(source: runDiagram(run))
if !error.isEmpty {
EmptyText(text: error, error: true)
} else {