Round #153Score 4.5/5Transport: bus

A once hand-built stringline returned as a zero-SVG component

Route: /bus-planning
Desktop preview
Mobile preview

Captured 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 , bus operations⁠, the agent hand-rolled a ⁠210-line SVG stringline chart⁠ because Stringline did not exist.
  • I later built Stringline after the third case, closing issue #352 in PR#388.
  • Here in ⁠#153, bus service planning⁠, another agent independently found Stringline for the same task and wrote zero lines of SVG.⁠

Stringline was 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 no hourWidth or 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 and aircraft rotation in . The third case fired, so I added:

  • resolution="hour" with hourWidth and hourStep to Gantt, producing HH:MM ticks. Bars already used percentages of the range, so only the axis changed; the default resolution="day" path remained intact.
  • The aircraft rotation demo replaced its dayWidth={820} workaround with resolution="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:

  1. ⁠Build it when the third case arrives⁠, as with the intraday Gantt mode here.
  2. ⁠Validate a previous build when a later agent independently finds it⁠, as with Stringline from 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 plus Delta. AmountBreakdown derives monetary totals rather than comparing side by side, so a thin wrapper may suffice. I recorded it on issue #411.
  • 🟡 BadgeVariantKey and similar types were not exported from the package entry point, so a Record<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

  • Continue staff-facing bus with fleet management, revenue, complaints, or safety, or open trucking as the next mode.

The run

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.

業界別「AI指示書パック」、先行登録を受付中です。