From a spoken idea to a working app with live alerts, a rewindable history and station art, built by Pavel and Claude in about an hour and a quarter.
The source for this episode is on GitHub: Semantic-Works-LLC/semantic-works-public
The finished app runs on the next slide, inside this presentation, replaying an afternoon of recorded MTA alerts. Nothing to install, nothing to configure.
Play with it live View the source code on GitHub
You can also see the source code of everything presented here, and how the application runs.
Press ▶ below to play with it. After that, ▶ continues with the story.
The app normally reads the MTA's feeds through a small server of its own. Here it replays the 200 alerts it recorded on 12 October 2026, from 10:42 to 14:56 New York time, and the clock stands at the end of that afternoon. Close this window, then interact with it:
To see it live, run it yourself. When you are done, press ▶ below to see how it was built.
I've heard that the New York transit authority publishes live updates about closures and similar events. I'd like an HTML page … that draws a map of the New York subway with the stations on it, periodically fetches the updates … and shows those events live on the map. … Keep the history so I can rewind the clock back and forward to the present moment.Pasha, lightly trimmed
Before writing anything, Claude checked what the MTA actually offers:
Everything went into a folder of its own, apart from the Cyber Kitchen episodes.
The first version had all its parts in place:
On its first run the server could not reach the MTA, because this Mac's Python had no list of trusted certificates, and the map area came out empty. We fixed both a few minutes later, keeping certificate checks switched on.
With the fixes in, everything we had built showed up at once:
The feed carried 189 alerts, of which 8 were in effect. Most are planned work for later dates.
The server does not keep a copy of every fetch. It keeps what changed: which alerts arrived and which were removed. The page replays those changes up to any moment, so the slider can take the map back in time.
With only a few minutes of real history, we tested it by placing one invented alert ten minutes in the past, in the browser only, and stepping back to it.
The map showed that one alert and "11 min ago". A reload cleared it.
Before building further, we downloaded the MTA's train feeds and decoded them to see what they hold.
| Question | Answer | What the live feeds showed |
|---|---|---|
| Which station has the problem? | Partly | Planned work lists its stations. Delays usually name only the line; the place is in the sentence. |
| Where is each train? | Yes, by station | 164 trains on the numbered lines in one sample, each "stopped at" or "in transit to" a station. No GPS. |
| When will it arrive? | Yes | Predicted times for up to 20 stops ahead per train. |
| How fast are things moving? | Not directly | No speed field. It can be worked out from time between stations. |
Train history cannot be downloaded later, because the MTA publishes only the present moment. So we started recording straight away, before drawing any of it.
One folder per feed under data/, each update a file named by its time.
| Folder | What | How often |
|---|---|---|
alerts/ | The change log the page replays | Checked every 30 seconds |
trains/ | Positions and predicted arrivals, all eight feeds, exactly as received | Every 15 minutes, about 13 MB a day |
elevator-…/ | Elevator and escalator outages | Every 30 seconds, saved when changed |
art/, stations/, paths/ and 18 more | The MTA's slow-changing datasets and the schedule, 220 MB | On demand |
We set trains to every 15 minutes to keep the recordings small, and left out two ridership datasets of 46 and 83 million rows.
The MTA's Permanent Art Catalog lists 309 artworks in subway stations. We put them on the map.
As there was more to show about each station, we gave it a proper home: a panel that slides in and out, with two tabs.
Lines are easiest to click after zooming in, when the stations no longer cover them.
Dimitri GerakarisÕs Woodside Continuum … Ã’The challenge and opportunity of the Woodside station is in its relationship to the past and to the future,ÓAs the MTA's file has it
253 of the catalog's 394 entries arrive like this. The text was written in the old Mac character set, then misread twice on its way to publication, so one apostrophe arrives as two unrelated characters.
We added a step that reverses both misreadings:
Dimitri Gerakaris’s Woodside Continuum … “The challenge and opportunity of the Woodside station is in its relationship to the past and to the future,”After the repair
95 characters had already been lost at the source, so for those we put back an apostrophe or quotation mark by position, which is a guess. The downloaded file is kept exactly as published.
A line with an alert, or the line you selected, has a soft outline that pulses in a lighter shade of the line's own colour. We got there in steps:
Along the way we fixed a real fault: every 5-second refresh was redrawing the pulsing shapes, which restarted each pulse and made the map jitter. They are now redrawn only when something changes.
With the Events tab open you can see what is happening and when it started.
It's all done!!! See what is wrong right now, wind the clock back to see how it got that way, and click anything to learn more.
You can run it yourself in a minute, with nothing to install but Python.
Counted from the session's own log, up to the moment this slide was added: 37.1 million tokens across 155 requests to the model, all Claude Opus 5.5.
| Kind | Tokens | What it is |
|---|---|---|
| Re-read from cache | 36,649,630 | The conversation so far, read again on every request. This is 98.7% of the total and is billed at a small fraction of the normal rate. |
| New input | 311,320 | Text entering the conversation for the first time: Pavel's messages, tool results, files and screenshots. |
| Output | 185,116 | Everything Claude wrote: answers, code, commands and its working notes. |
| Total | 37,146,066 |
The total is large because of how a long conversation works, not because much was written. Each of the 155 requests re-reads everything before it, so the same text is counted again and again: on average about 236,000 tokens of history per request. Not included: the requests made after this count.
Other statistics
About $13.50 on Claude Opus 5.5, the model that ran the session. The same token counts priced on other models:
| Model | Rough cost | Notes |
|---|---|---|
| Claude Opus 5.5 | about $13.50 | What we used: $7.33 for cache re-reads, $2.49 for new input, $3.70 for output. |
| Claude Sonnet 5.5 | about $10.40 | Its cache-read price is the same as Opus, so the saving is small. |
| Gemini 3.1 Pro | about $19 | Most requests were over 200,000 tokens, where Gemini doubles its rates. |
| Gemini 3.8 Flash | about $4 | At its price through December 2026; it doubles in January 2027. |
Caching is what keeps this small. With no caching, every re-read would be billed as fresh input: about $152 on Opus 5.5 and about $138 on Gemini 3.1 Pro.
The conversation that built the app, with Pavel's words as spoken, is in TRANSCRIPT.md.
Episode 1 looked at the subway from the outside: what is there and what is happening. Two more viewpoints have been talked about. Neither is settled.
| Episode | Viewpoint | What it could do | What it would need |
|---|---|---|---|
| 2 | The rider | Trains on the map. Pick home and work, then see the best route right now, the next trains, when to leave, and which alerts or elevator outages are in the way. | The recorded train feeds decoded and read live, and a route finder over the schedule. |
| 3 | The operator | What someone at the MTA could learn from the data: where and when things go wrong, how long incidents last, how many riders they touch, and where to put people. Or a live desk for responding to incidents as they arrive. | Weeks of recorded history, and invented staffing numbers, since none are published. |
There is more from Semantic Works to explore.
Happy vibe coding with LLM AI!