[object Object]

← back to Cli Printing Press

fix(catalog): refresh google-flights entry to reflect fli native port (#1084)

5c4ef3a7a4faea5f8f3b3eaaed4e62a8e773396e · 2026-05-11 10:34:27 -0700 · Omar Shahine

* feat(catalog): refresh google-flights entry to reflect fli native port

Fixes #1083.

The catalog entry steered prints to import krisukox/google-flights-api,
whose Options struct silently drops --airlines, --bags, --carry-on,
--emissions, --layover, --max-layover, --exclude-basic, --limited, and
the expanded sort values. Recent prints (flight-goat in
printing-press-library) instead ported fli's FlightSearchFilters.format()
to Go for full filter parity at zero Python runtime cost.

Changes
- Append filter-coverage caveats to the krisukox wrapper notes so future
  prints know what gets dropped if they import it as-is.
- Add punitarani/fli (Python, MIT) as a second wrapper option in
  `subprocess` integration mode, with a pointer to the working Go port
  in flight-goat as the recommended pattern.
- Update top-level description + notes to surface both paths and call
  out which to pick when filter parity matters.
- Bump verified_date to 2026-05-11.
- Update TestEmbeddedCatalogParsesWrapperOnlyEntries to expect both
  wrappers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(catalog): refresh catalog-list golden for google-flights description

Mirrors the catalog YAML change in this PR — the catalog row output now
mentions both wrappers (krisukox in Go, fli in Python). One-line diff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 5c4ef3a7a4faea5f8f3b3eaaed4e62a8e773396e
Author: Omar Shahine <omarshahine@users.noreply.github.com>
Date:   Mon May 11 10:34:27 2026 -0700

    fix(catalog): refresh google-flights entry to reflect fli native port (#1084)
    
    * feat(catalog): refresh google-flights entry to reflect fli native port
    
    Fixes #1083.
    
    The catalog entry steered prints to import krisukox/google-flights-api,
    whose Options struct silently drops --airlines, --bags, --carry-on,
    --emissions, --layover, --max-layover, --exclude-basic, --limited, and
    the expanded sort values. Recent prints (flight-goat in
    printing-press-library) instead ported fli's FlightSearchFilters.format()
    to Go for full filter parity at zero Python runtime cost.
    
    Changes
    - Append filter-coverage caveats to the krisukox wrapper notes so future
      prints know what gets dropped if they import it as-is.
    - Add punitarani/fli (Python, MIT) as a second wrapper option in
      `subprocess` integration mode, with a pointer to the working Go port
      in flight-goat as the recommended pattern.
    - Update top-level description + notes to surface both paths and call
      out which to pick when filter parity matters.
    - Bump verified_date to 2026-05-11.
    - Update TestEmbeddedCatalogParsesWrapperOnlyEntries to expect both
      wrappers.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * test(catalog): refresh catalog-list golden for google-flights description
    
    Mirrors the catalog YAML change in this PR — the catalog row output now
    mentions both wrappers (krisukox in Go, fli in Python). One-line diff.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 catalog/google-flights.yaml                      | 51 ++++++++++++++++++++----
 internal/catalog/catalog_test.go                 |  4 +-
 testdata/golden/expected/catalog-list/stdout.txt |  2 +-
 3 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/catalog/google-flights.yaml b/catalog/google-flights.yaml
index 4e5b77a3..4d94cd56 100644
--- a/catalog/google-flights.yaml
+++ b/catalog/google-flights.yaml
@@ -1,21 +1,56 @@
 name: google-flights
 display_name: Google Flights
-description: Flight search via Google Flights. No public API — reached through a community-maintained reverse-engineered wrapper.
+description: Flight search via Google Flights. No public API — reached through community-maintained reverse-engineered wrappers (krisukox in Go, fli in Python).
 category: travel
 tier: community
-verified_date: "2026-05-09"
+verified_date: "2026-05-11"
 homepage: https://www.google.com/travel/flights
 notes: |
-  Google does not publish a Flights API. The wrapper library below reverse-engineers
-  the internal protobuf protocol that powers the website. Prefer the native Go wrapper
-  for printed CLIs so the resulting binary has no Python runtime dependency.
+  Google does not publish a Flights API. The wrapper libraries below reverse-engineer
+  the internal protobuf protocol that powers the website.
 
-  When this entry is returned for a combo-CLI source, the skill should surface the
-  wrapper options to the user rather than searching for an OpenAPI spec.
+  Two integration paths are viable:
+
+    1. Import krisukox/google-flights-api directly (native Go). Fastest to wire in, but
+       its Options struct only exposes Stops, Class, and TripType — flags for airlines,
+       bags, carry-on, emissions, layover, exclude-basic, expanded sort values, and
+       "show all results" are silently dropped at the wrapper boundary. Acceptable for
+       a minimal price-shopping CLI; insufficient if filter parity matters.
+
+    2. Port fli's FlightSearchFilters.format() to Go. fli (Python, MIT) has the most
+       complete f.req protobuf-shape implementation we know of. Reimplementing it in
+       Go produces a single-binary CLI with full filter parity and no Python runtime
+       dependency. flight-goat in printing-press-library/library/travel/flight-goat
+       does this in ~570 LOC and is a working reference (see
+       internal/gflights/flights_native.go).
+
+  When this entry is returned for a combo-CLI source, the skill should surface both
+  paths and let the user pick — filter coverage is usually the deciding factor.
 wrapper_libraries:
   - name: krisukox/google-flights-api
     url: https://github.com/krisukox/google-flights-api
     language: go
     license: MIT
     integration_mode: native
-    notes: Pure Go, importable. Produces a single-binary CLI with no Python runtime dependency.
+    notes: |
+      Pure Go, importable. Produces a single-binary CLI with no Python runtime
+      dependency. Filter coverage is limited — its Options struct only carries
+      Stops, Class, and TripType. Flags for airlines, bags, carry-on, emissions,
+      layover, exclude-basic, show-all-results, and the expanded sort values
+      (top_flights, best, emissions) have no slot to flow through and silently
+      become no-ops. Choose this only when the price-shopping flags above are
+      not required; otherwise port fli's f.req construction instead.
+  - name: punitarani/fli
+    url: https://github.com/punitarani/fli
+    language: python
+    license: MIT
+    integration_mode: subprocess
+    notes: |
+      Reference implementation with full filter parity. FlightSearchFilters.format()
+      in fli/models/google_flights/flights.py builds the protobuf-shaped f.req
+      payload Google's FlightsFrontendService expects, including airlines, bags,
+      carry-on, emissions, layover/max-layover, exclude-basic, show-all-results,
+      and all 7 sort values. Can be invoked as a subprocess (Python runtime
+      required) or — preferably — ported to Go directly. flight-goat in the
+      printing-press-library catalog repo carries a tested Go port at
+      internal/gflights/flights_native.go.
diff --git a/internal/catalog/catalog_test.go b/internal/catalog/catalog_test.go
index cc14be63..bad82ef9 100644
--- a/internal/catalog/catalog_test.go
+++ b/internal/catalog/catalog_test.go
@@ -417,9 +417,11 @@ func TestEmbeddedCatalogParsesWrapperOnlyEntries(t *testing.T) {
 	require.NoError(t, err)
 	assert.True(t, entry.IsWrapperOnly())
 	assert.Equal(t, "travel", entry.Category)
-	require.Len(t, entry.WrapperLibraries, 1)
+	require.Len(t, entry.WrapperLibraries, 2)
 	assert.Equal(t, "krisukox/google-flights-api", entry.WrapperLibraries[0].Name)
 	assert.Equal(t, "native", entry.WrapperLibraries[0].IntegrationMode)
+	assert.Equal(t, "punitarani/fli", entry.WrapperLibraries[1].Name)
+	assert.Equal(t, "subprocess", entry.WrapperLibraries[1].IntegrationMode)
 }
 
 func TestPublicCategoriesExcludeExample(t *testing.T) {
diff --git a/testdata/golden/expected/catalog-list/stdout.txt b/testdata/golden/expected/catalog-list/stdout.txt
index 10d7a026..86be8809 100644
--- a/testdata/golden/expected/catalog-list/stdout.txt
+++ b/testdata/golden/expected/catalog-list/stdout.txt
@@ -41,5 +41,5 @@ social-and-messaging:
   twilio               Communication APIs for SMS, voice, and messaging
 
 travel:
-  google-flights       Flight search via Google Flights. No public API — reached through a community-maintained reverse-engineered wrapper.
+  google-flights       Flight search via Google Flights. No public API — reached through community-maintained reverse-engineered wrappers (krisukox in Go, fli in Python).
 

← 27ad2dda fix(cli): skip Windows Python Store stub in verify-skill (#1  ·  back to Cli Printing Press  ·  fix(cli): dispatch typed-table upserts on spec resource key, 705bad2d →