A once hand-built stringline returned as a zero-SVG component
/bus-planningCaptured at a 375px viewport. Long pages scroll inside the frame.
The screenshots stay in Japanese. Every round is a real screen for a real Japanese industry, so an English re-render would no longer be the screen the agent actually produced.
Write-up
A once hand-built stringline returned as a zero-SVG component
Build log series: I give an AI that has never seen Gunjo (
@gunjo/ui) only the public npm package and the gunjo.jp docs, then ask it to build a real screen. This third staff-facing bus round covered a dense service planning and timetable console: routes, stops, service counts, a stringline chart, vehicle workings, and timetable revisions.
Result: 4.5/5, with the strongest validation of a previous build
The desktop-density screen passed tsc. The agent reported:
This had the strongest domain fit of any library I have adopted without prior context. A bus planning console should be difficult for a general component library, yet both pieces I expected to hand-roll, the stringline chart and vehicle-working Gantt, had purpose-built components.
The core observation: a hand-built diagram returned as a component
The sequence made this the most satisfying validation in the series:
- In #136, bus operations, the agent hand-rolled a 210-line SVG stringline chart because
Stringlinedid not exist. - I later built
Stringlineafter the third case, closing issue #352 in PR#388. - Here in #153, bus service planning, another agent independently found
Stringlinefor the same task and wrote zero lines of SVG.
Stringlinewas built for this. No friction. The docstring names stringline, timetable diagram, and Marey chart, models each run as a diagonal polyline, and even explains how converging lines reveal bunching and why Gantt differs. I wrote no SVG. This is the most important component in the library for this domain.
The catalog also sent a time-against-distance diagram with diagonal lines crossing stops to the right component. This was the strongest form of build validation: the exact task that once forced 210 hand-written lines became a component another agent found and used without prompting. A later adopter proved that the build actually closed the gap.
Another core observation: the third intraday Gantt case triggered a build
Vehicle workings produced a familiar complaint:
Gantt's axis was measured in days, so one day of vehicle workings collapsed into one column about 44px wide. The agent forced
dayWidth={1100}. There was nohourWidthor time tick. It was the only unfinished part of the screen, and an intraday scale was the highest-value addition.
The same workaround had appeared in rail planning in #133 and aircraft rotation in #135. The third case fired, so I added:
resolution="hour"withhourWidthandhourSteptoGantt, producing HH:MM ticks. Bars already used percentages of the range, so only the axis changed; the defaultresolution="day"path remained intact.- The aircraft rotation demo replaced its
dayWidth={820}workaround withresolution="hour". - PR#410 closed issue #386 after structural verification, a green build, and browser checks for hour ticks from 06:00 through 15:00 plus the existing day ticks.
What I took away: gaps close in two ways
This screen showed two distinct endings for a missing component:
- Build it when the third case arrives, as with the intraday Gantt mode here.
- Validate a previous build when a later agent independently finds it, as with
Stringlinefrom #136 to #153.
The first closes a gap. The second proves it stayed closed. As the catalog matures, the second becomes more common. This rare screen did both: it validated Stringline and built the intraday Gantt axis. The steady state of a mature foundation is mostly independent discovery, with an occasional remaining thin gap settling on new evidence.
What it flagged
- 🟡
ComparisonTable for current versus proposed values in two columns plusDelta.AmountBreakdownderives monetary totals rather than comparing side by side, so a thin wrapper may suffice. I recorded it on issue #411. - 🟡
BadgeVariantKeyand similar types were not exported from the package entry point, so aRecord<Status, BadgeVariantKey>failed even though the variant prop uses that type. I added the developer-experience fix to issue #411.
What I built under src this round: the intraday Gantt mode. The 4.5/5 also validated Stringline and logged ComparisonTable.
📊 Component scoreboard (15 built, plus intraday Gantt)
Stringline / StatusBoard / ExpiryBadge / BottomActionBar plus Gantt with intraday resolution In progress: SegmentedControl beyond three cases, ReferralCard, RatingInput, and ComparisonTable.
📋 Mode progress
- ✈️ Air ✅ / 🚆 Rail ✅ / 🚕 Taxi ✅ / 🚌 Bus: three staff (operations, dispatch, planning) + three passenger screens, with staff depth still growing
- 🚚 Trucking: not started
Next up: build log #154
- Continue staff-facing bus with fleet management, revenue, complaints, or safety, or open trucking as the next mode.
The run
- gunjo.jp / Stringline / Gantt with intraday resolution / Delta / npm
@gunjo/ui/ GitHub / previous rounds #1 through #152 - GunjoUI by UIXHERO
A diagram once hand-rolled in 210 SVG lines returned as a component another agent found for the same task. That is the strongest proof that a build closed its gap.
This series is co-created with AI (Claude and Codex). A human designs the experiments, makes the calls, and fact-checks before publishing; the AI does the hands-on work and drafting.
Components from @gunjo/ui
The components this screen's source imports directly.
The code the agent actually wrote
Click a file to expand its source.