Surface legroom + amenities + seatmap from gflight responses (work-5ewe)#11
Merged
Conversation
The Legrooms+ Chrome extension overlays cabin, pitch, and amenity info on Google Flights search results. Originally I assumed we'd need to capture a third-party API (api.travelarrow.io) to mirror that — but the extension's load_flight_data.js shows the data is already in-band in Google's own /GetShoppingResults response at per-leg tuple indices 12-17. Our gflight backend already hits that endpoint via fli; we just had to read the fields. The Legrooms+ extension v11.5.0's bit positions have drifted since the extension was last updated. I empirically recalibrated 2026-05 by driving Google Flights via Patchright, scraping the rendered amenity labels from the detail panel, and correlating against the bit array. The wifi signal in particular moved from a single Boolean at [0] to a three-state enum at [11] (1=none, 2=free, 3=paid). Validated end-to-end against AA 952 and B6 1072: every decoded field (pitch, legroom class, cabin, aircraft, power, video, wifi) exactly matches Google's UI labels. Seatmap URLs are a separate per-flight concern. `flight seatmap` is a new subcommand that hits travelarrow.io/api/s (the same endpoint the Legrooms+ extension uses on click) and resolves to a seatmaps.com URL. Field detail and the calibration story are in docs/memories/legroom_recipe.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
legroomcolumn onflight searchoutput: pitch in inches (red for BELOW, green for ABOVE), cabin letter (Y/W/J/F), premium-cabin seat-type labels (Lie Flat / Suite / etc.), and single-glyph amenity icons.📶(free) or📶$in yellow (paid); 1-col Unicode for power (↯plug /⌁USB) and video (▶live TV /▷seatback on-demand /◰BYOD streaming).flight seatmapsubcommand resolves a flight to its seatmaps.com URL via one HTTP call to travelarrow.io's/api/s(or--no-fetchto just emit the API URL).Why the path got non-obvious
The bd item assumed we'd need to capture a third-party API (
api.travelarrow.io/v3/deals). The actual finding: the data is in-band in Google Flights' own/GetShoppingResultsresponse at per-leg tuple indices 12-17 — the Legrooms+ extension'sload_flight_data.jsparses exactly those positions. We just had to read them.The Legrooms+ extension v11.5.0's bit positions have drifted since the extension was last updated, so a direct port read every wifi flag as False. I empirically recalibrated the mapping 2026-05 by driving Google Flights via Patchright, expanding flight detail panels, scraping the rendered amenity labels, and correlating against the bit array. The headline fix: wifi moved from a single Boolean at
[0]to a three-state enum at[11](1=none / 2=free / 3=paid). Both ground-truth flights (AA 952 with "Free Wi-Fi + Stream-to-device" and B6 1072 with "Free Wi-Fi + Live TV") now decode every field — pitch, legroom class, cabin, aircraft, power, video, wifi — to a value that exactly matches Google's UI.Detailed index map, enum decodings, ground-truth validation set, and the calibration story are in
docs/memories/legroom_recipe.md.Test plan
uv run pytest tests/— 161 passing (24 new tests acrosstest_legroom_parser.pyandtest_seatmap.py)basedpyright src/flight_cli/— 0 errors / 0 warningsflight search MIA LGA --dep 2026-06-16matches Google's labels for AA 952 (Y 30" 📶↯◰) and B6 1072 (Y 32" 📶↯▶)flight search JFK DXB --dep 2026-09-10surfaces paid wifi correctly (📶$↯▷on RJ regional,📶↯▷on QR mainline)flight search MCO LAS --dep 2026-09-10shows F9 with no glyphs (no wifi/IFE/power) and WN with📶⌁◰(BYOD streaming + USB-only + free wifi)flight seatmap JFK LHR DL2 --date 2026-08-15 --aircraft "Airbus A330"returns a working seatmaps.com URL