Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: Dev-4
Claimed-by: Dev-4
Claim-Id: 5f72ad0251a34bcdb0953a06f36309c4
Branch: dev/4-drawer-wire-hit-targets
Base: 16d1645
At: 2026-11-04T17:38:30Z
What the user sees
Open a workflow lane, click a run card (or Flow) and the drawer shows the run's flowchart. The cards are readable; the wires between them are not. Pointing at a wire does nothing — no highlight, no dimming of the other wires — and a screen reader gets an aria-hidden SVG, so it never reads which step feeds which. Two wires that land on the same port are one stroke to the eye: there is nothing to point at, so a reader cannot tell that both Reviewer and Tester feed Deployer.
The Settings canvas already solved exactly this shape in core (core/src/client/workflows.js ~460: role="group", aria-label, per-route 10px transparent hit path with <title>, data-active/data-dim). The drawer's read-only plane never got it.
Where
plugins/workflow/client.js, FlowView (~1338) renders:
h('svg', { className: 'wf-wires', 'aria-hidden': true, ... },
h('defs', ...),
layout.wires.map(wire => h('path', { key, d, 'data-wire': wire.kind, ... })))Each route painted by flowWires carries only its d; there is no id pair, no name, no hit path, and the whole layer is hidden from a reader.
Reproduction (no UI needed)
plugins/workflow/test/client.test.js: mount client.Section, click a workflow row and the Flow tab without pressing Edit, on the delivery() graph. Then:
- The wire layer has
aria-hidden: true, norole, no name. path[data-hit="1"]does not exist, so a wire has no hit target of its own.- There is no hover state at all (
data-active/data-dimnever appear).
Expected
- The wire layer is a named
group(Connections, zh连线), notaria-hidden. - Every route drawn by
flowWiresis a named image (role="img",aria-label,<title>) with a 10px transparent hit path of its own (pointer-events: stroke), named by both ends — a join/fork bus and its drops are named by the group they carry, e.g.Coder → Reviewer + TesterandReviewer + Tester → Deployer. - Pointing at one wire marks it
data-activeand dims the othersdata-dim; leaving clears both. - Read-only stays read-only: pointing at, clicking or leaving a wire writes nothing (
workflow/stateis the only call). - Geometry is untouched: same route list, same
d, so the pinned plane geometry and layout tests stay green.
Red first (clean 16d16456, only these tests added)
plugins/workflow/test/client.test.js, 170 tests → 167 pass / 3 fail:
not ok 2 - the read-only run flowchart names every wire and gives each one a hit target of its own (#2422)
error: 'the wire layer is hidden from a reader'
not ok 3 - pointing at one wire in the read-only flowchart picks it out and lets the others recede (#2422)
error: "Cannot read properties of undefined (reading 'props')"
not ok 4 - a read-only run flowchart commits nothing when a wire is pointed at (#2422)
error: "Cannot read properties of undefined (reading 'props')"
Scope
plugins/workflow/client.js (flowWires id pairs + FlowView + three CSS rules), plugins/workflow/test/client.test.js, docs/subsystems/workflow.md, one changelog.d fragment. No core/client.js, no patches/ds-bot/**, no other plugin, no core file.
Dedupe
Checked the open and merged workflow/social PRs and issues: #2142 (Settings canvas hit targets, closed) covers the Settings plane only; #2421 (social read-only invites) is a different surface; #2415/#2403 belong to other lines and are untouched. plugins/social has no wire/edge rendering at all (only a QR svg and two icon svgs), so the reported "social connection" surface is this read-only run flowchart.
Activity
social: name the read-only Sharing change by its own issue (ThinkFlow…