@gojinko/plugin 2.22.1 → 2.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jinko",
3
3
  "description": "Search flights, book trips, and manage bookings with the Jinko Travel API. Connects to the Jinko MCP server for live flight pricing, trip management, and payment.",
4
- "version": "2.22.1",
4
+ "version": "2.24.0",
5
5
  "author": {
6
6
  "name": "Jinko",
7
7
  "url": "https://gojinko.com"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jinko",
3
3
  "description": "Search flights, book trips, and manage bookings with the Jinko Travel API. Connects to the Jinko MCP server for live flight pricing, trip management, and payment.",
4
- "version": "2.22.1",
4
+ "version": "2.24.0",
5
5
  "author": {
6
6
  "name": "Jinko",
7
7
  "url": "https://gojinko.com"
package/README.md CHANGED
@@ -47,10 +47,13 @@ codex plugin install @gojinko/plugin
47
47
 
48
48
  ## Authentication
49
49
 
50
- The plugin supports two auth methods:
50
+ Authenticate with a tenant **API key** (`jnk_*`) — get one from
51
+ **dashboard.gojinko.com → Developers → API keys**:
51
52
 
52
- - **API Key**: Set `JINKO_API_KEY` environment variable with your `jnk_*` key
53
- - **OAuth**: If no API key is set, Codex will auto-discover OAuth and prompt you to sign in via browser
53
+ - Set the `JINKO_API_KEY` environment variable with your `jnk_*` key, or
54
+ - Store it via the CLI: `jinko auth login --key jnk_...`
55
+
56
+ OAuth sign-in is deprecated and no longer supported.
54
57
 
55
58
  ## MCP server
56
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gojinko/plugin",
3
- "version": "2.22.1",
3
+ "version": "2.24.0",
4
4
  "description": "Jinko Travel plugin for Claude Code and OpenAI Codex — flight search, booking, and trip management via MCP",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -14,7 +14,7 @@ Account management is handled through the web dashboard — there are no MCP too
14
14
  1. **Register** — go to [gojinko.com/dashboard](https://gojinko.com/dashboard) and sign up with your email.
15
15
  2. **Create an API key** — in the dashboard, go to API Keys and create a new key. The full key (prefixed `jnk_`) is shown only once — save it immediately.
16
16
  3. **Set your key** — configure your environment:
17
- - CLI: `jinko auth login` (OAuth) or set `JINKO_API_KEY=jnk_...`
17
+ - CLI: `jinko auth login --key jnk_...` (or set `JINKO_API_KEY=jnk_...`)
18
18
  - API client: pass the key when creating the client
19
19
  - MCP: use `Authorization: Bearer jnk_...` header
20
20
 
@@ -33,7 +33,10 @@ Account management is handled through the web dashboard — there are no MCP too
33
33
 
34
34
  ## CLI authentication
35
35
 
36
- The CLI supports two auth methods:
36
+ The CLI authenticates with an **API key** (`jnk_...`):
37
37
 
38
- 1. **OAuth** (recommended): `jinko auth login` — opens a browser for WorkOS login, stores token locally
39
- 2. **API key**: set `JINKO_API_KEY=jnk_...` in your environment — simpler for scripts and CI
38
+ - `jinko auth login --key jnk_...` — stores the key in `~/.jinko/config.yaml`
39
+ - `jinko auth login` (no flag) — prompts for the key interactively
40
+ - `export JINKO_API_KEY=jnk_...` — pass it via the environment (scripts and CI)
41
+
42
+ OAuth sign-in is deprecated and no longer supported.
@@ -28,26 +28,61 @@ Two modes (use exactly one):
28
28
  "departure_date": "2026-06-15",
29
29
  "return_date": "2026-06-22",
30
30
  "cabin_class": "economy",
31
- "direct_only": false
31
+ "max_stops": 1,
32
+ "checked_bag_included": true
32
33
  },
33
- "passengers": { "adults": 1, "children": 0, "infants": 0 }
34
+ "traveler_counts": { "adults": 1, "children": 0, "infants": 0 },
35
+ "currency": "EUR"
34
36
  }
35
37
  ```
36
38
 
39
+ `search` carries the whole shop filter contract. What to reach for:
40
+
41
+ - **Stops:** `max_stops` (0-2) — send `max_stops: 0` when the user says "direct", "non-stop", "no layovers". `direct_only` is its deprecated alias: `true` is folded into `max_stops: 0`, the filter report always names `max_stops`, and sending it beside a non-zero `max_stops` is an error.
42
+ - **Time of day:** `departure_time_range` / `arrival_time_range` filter the OUTBOUND leg, `return_departure_time_range` / `return_arrival_time_range` the RETURN leg. Each is `{ "earliest": "08:00", "latest": "12:00" }`, and either bound may be omitted.
43
+ - **Fares:** `refundable_only`, `changeable_only`, `checked_bag_included`.
44
+ - **Routing:** `single_carrier_only`, `include_carriers` / `exclude_carriers`, `via_airports` / `exclude_via_airports`, `aircraft_types`, `connection_time_min_minutes` / `connection_time_max_minutes`, `max_total_duration_minutes`, `same_connection_airport_only`, `same_origin_airport_only`, `same_turnaround_airport_only`.
45
+ - **Widening:** `origin_alternate_airports` / `destination_alternate_airports`, `nearby_airports`, `date_flexibility_days` (0-3, for "give or take a day" — anything wider is a `flight_calendar` query).
46
+ - **Size and shape:** `multi_fare` defaults to true (the branded fare ladder; set it false for one fare per itinerary and a much smaller response), `limit` is the TOTAL number of flights returned (1-300), not a page size.
47
+ - **`cabin_class` is ADVISORY**, not a filter: it is forwarded to the providers as a preference and they may still return other cabins. It never appears in `applied_filters` — read each fare's own `cabin_class`.
48
+
49
+ **Alternate airports widen an AIRPORT anchor:**
50
+ ```json
51
+ {
52
+ "search": {
53
+ "origin": "JFK",
54
+ "origin_alternate_airports": ["EWR", "LGA"],
55
+ "destination": "CDG",
56
+ "departure_date": "2026-06-15"
57
+ }
58
+ }
59
+ ```
60
+ The anchor is always searched, and it ranks and truncates the result set — so put the airport that matters most to the user in `origin` / `destination`, not in the list. Against a city anchor (`origin_type: "city"`, or a code that resolves to a city) the search still runs and the list is ignored: it comes back in `unapplied_filters`, which is a warning to relay, not an error. On a round trip the whole side is mirrored onto the return leg.
61
+
37
62
  **Price-check** (user has an `offer_token` — e.g. from a prior `flight_calendar` or legacy `find_flight` result):
38
63
  ```json
39
64
  {
40
65
  "price_check": {
41
- "offer_token": "es-abc123..."
66
+ "offer_token": "es-abc123...",
67
+ "direct_only": true,
68
+ "cabin_class": "economy"
42
69
  }
43
70
  }
44
71
  ```
45
72
 
46
- **Response:** Flights with fare options. Each fare includes a `trip_item_token`. If status is `"flight_unavailable"`, show alternatives — do NOT proceed to booking.
73
+ ALWAYS carry forward the filters that were on the call which produced the token — `direct_only`, `cabin_class`, `max_price`, `include_carriers`, `exclude_carriers`. The BFF reshops the closest match, and without them it can return a candidate that violates what the user picked (a stopover after they asked for direct). The wider shop filters (`max_stops`, `refundable_only`, the time ranges, …) belong to `search` only.
74
+
75
+ **Response:** Flights with fare options. Each fare includes a `trip_item_token` plus `refundable` / `changeable` / `checked_bag_included` booleans you can re-check yourself. If status is `"flight_unavailable"`, show alternatives — do NOT proceed to booking.
76
+
77
+ The result also carries `applied_filters` (the filters this result set enforces) and `unapplied_filters` (the ones no provider could enforce, each with a `name` and a `reason`), plus a one-sentence `filters_notice` when something went unapplied. **Anything in `unapplied_filters` was NOT enforced** — the flights are not narrowed by it, so apply it yourself or tell the user the constraint could not be met. Both lists name the leg SIDE for the alternate-airport lists: an `origin_alternate_airports` / `destination_alternate_airports` list is reported as `origin` / `destination`, never under the field name you sent.
47
78
 
48
79
  **Rules:**
80
+ - Exactly one of `search` or `price_check` per call
49
81
  - Origin and destination must differ
50
- - Departure date must be in the future
82
+ - Departure date must be in the future, and `return_date` on or after `departure_date`
83
+ - Single dates only — no arrays, no ranges (bounded flexibility goes in `date_flexibility_days`)
84
+ - `connection_time_min_minutes` must not exceed `connection_time_max_minutes`; `include_carriers` must not overlap `exclude_carriers`, nor `via_airports` overlap `exclude_via_airports`
85
+ - Traveler counts: adults 1-9, children 0-8, infants 0-4
51
86
  - Infants cannot exceed adults
52
87
  - Total passengers max 9
53
88
 
@@ -138,7 +173,9 @@ Categories: `BAGGAGE`, `SEAT`, `MEAL`, etc.
138
173
 
139
174
  Single synchronous call. The BFF schedules the quote, polls until it completes, schedules fulfillment, and returns a canonical Jinko-hosted checkout URL of the form `https://app.gojinko.com/checkout?sid=<cart_id>`. The user opens this URL in a browser; the Jinko `/checkout` page collects any remaining info and triggers the right Stripe flow (embedded Elements or Hosted Checkout) at Pay-button click. Stripe webhooks finalize the booking automatically — no client-side confirm step is required.
140
175
 
141
- **Response includes:** `checkout_url`, `session_id`, `total_amount`, `items`.
176
+ **Response includes:** `checkout_url`, `session_id`, `total_amount`, `items`, and on any item the provider re-priced between search and quote, `price_change`.
177
+
178
+ `price_change` carries `original` (the price shown at search), `current` (the price about to be charged) and `delta` (`current` minus `original`, signed); it is absent when the two prices are the same. Checkout proceeds at `current` — tell the user the new price before they open the checkout URL.
142
179
 
143
180
  ## Optional: Check trip status — `get_trip`
144
181
 
@@ -150,6 +187,8 @@ Single synchronous call. The BFF schedules the quote, polls until it completes,
150
187
 
151
188
  Returns the full trip lifecycle state: cart contents, travelers, quote status, fulfillment status, booking references. Use after booking to verify confirmation or anytime to inspect the trip.
152
189
 
190
+ Once fulfillment has been scheduled the response carries a top-level `booking_ref` (`JNK-…`): the Jinko booking reference, which is the `booking_ref` that `get_booking`, hotel cancel, refund and exchange take. It can be present before payment completes (a hosted checkout still in progress, or an agent submit that fell back to `checkout_url`, leaves the cart `awaiting_payment`), so presence does not mean paid — read `fulfillment.status`. `bookings[].booking_reference` is the supplier's own confirmation (airline record locator, hotel confirmation number), not that handle. An agent paying with a Shared Payment Token never sees the checkout page, so `submit_agent_payment` returns the same `booking_ref` once the token is authorized.
191
+
153
192
  ## Important rules
154
193
 
155
194
  - **Never skip steps** — each depends on the previous
@@ -10,14 +10,14 @@ Command-line tool for the Jinko Travel platform. Same capabilities as the MCP to
10
10
  ## Install + auth
11
11
 
12
12
  ```bash
13
- npm install -g @gojinko/cli # one-time install
14
- jinko auth login # OAuth device flow → browser login
15
- jinko auth status # verify
13
+ npm install -g @gojinko/cli # one-time install
14
+ jinko auth login --key jnk_xxx # store your API key (from dashboard.gojinko.com → Developers → API keys)
15
+ jinko auth status # verify
16
16
  ```
17
17
 
18
18
  Auth alternatives:
19
- - **API key** (for scripts / CI): `jinko --api-key jnk_xxx <command>` or `export JINKO_API_KEY=jnk_xxx`.
20
- - **OAuth (human)**: `jinko auth login` opens a browser, stores token in `~/.jinko/config.yaml`. Auto-refresh is built in. `jinko auth logout` to clear.
19
+ - **API key** (recommended): `jinko auth login --key jnk_xxx`, or per-command `jinko --api-key jnk_xxx <command>`, or `export JINKO_API_KEY=jnk_xxx`. `jinko auth login` with no flag prompts for the key interactively and stores it in `~/.jinko/config.yaml`. `jinko auth logout` to clear.
20
+ - **OAuth**: deprecated and no longer supported — use an API key.
21
21
 
22
22
  ## Environments (prod / sandbox)
23
23
 
@@ -45,14 +45,14 @@ Prod and sandbox keys are stored separately in `~/.jinko/config.yaml`. Precedenc
45
45
  | `auth login / logout / status` | Credentials |
46
46
  | `find-destination` | Discover destinations from origin(s) — inspiration |
47
47
  | `flight-calendar` | Cheapest prices across a date range for a specific route |
48
- | `flight-search` | Live pricing — direct search by route + dates, or `--offer-token` price-check (returns bookable `trip_item_token`) |
48
+ | `flight-search` | Live pricing — direct search by route + dates, or `--offer-token` price-check (returns bookable `trip_item_token`). Full shop filter set: `--max-stops`, `--departure-time-range`, `--connection-time-*-minutes`, `--refundable-only`, `--checked-bag-included`, `--via-airports`, `--origin-alternate-airports`, … |
49
49
  | `hotel-search` | Live hotel search by city/query/geo/hotel-ids |
50
50
  | `hotel-details` | Rich metadata (gallery, facilities, policies, per-room details) for a single hotel |
51
51
  | `trip` | Create / update a trip: add items, remove items, set travelers + contact |
52
52
  | `select-ancillaries` | Add baggage / seats / meals to a trip item |
53
53
  | `checkout` | Finalize a trip → returns `checkout_url` (human pays in browser) + `agent_spt_params` (agent pays programmatically). `book` is a deprecated alias. |
54
- | `agent-pay submit` | Pay programmatically with a Shared Payment Token (`--trip-id` + `--token`); 3DS step-up falls back to `checkout_url` |
55
- | `trip-status` | Full status: cart, quote, fulfillment, bookings |
54
+ | `agent-pay submit` | Pay programmatically with a Shared Payment Token (`--trip-id` + `--token`); returns the Jinko `booking_ref` once authorized; 3DS step-up falls back to `checkout_url` |
55
+ | `trip-status` | Full status: cart, quote, fulfillment, bookings, and the Jinko `booking_ref` once fulfillment has been scheduled — it can be present before payment completes, so read `fulfillment.status` for paid (the `--booking-ref` for `get-booking` / `hotel-cancel` / `refund`) |
56
56
  | `get-booking` | Retrieve a booking by `JNK-*` ref + last name (guest access). |
57
57
  | `refund check / commit / status` | Voluntary refund flow |
58
58
  | `schema <command>` | Print request/response schema for a command |
@@ -64,7 +64,8 @@ Run `jinko <command> --help` for flags on any command.
64
64
 
65
65
  ```bash
66
66
  # 1. Find a flight (live pricing, gives trip_item_token)
67
- jinko flight-search --from PAR --to NYC --date 2026-06-15 --return 2026-06-22 --passengers 2
67
+ jinko flight-search --origin PAR --destination NYC \
68
+ --departure-date 2026-06-15 --return-date 2026-06-22 --adults 2
68
69
 
69
70
  # 2. Create a trip with that item
70
71
  jinko trip --trip-item-token "offer_xxx:fare_yyy"
@@ -87,11 +88,14 @@ jinko checkout --trip-id tr_ABC
87
88
  # 5b. Agent path: mint a Shared Payment Token scoped to agent_spt_params,
88
89
  # then pay programmatically (no browser):
89
90
  jinko agent-pay submit --trip-id tr_ABC --token spt_xxx
90
- # → { status: "processing", payment_verified: true }
91
- # On a 3DS step-up / decline, the response carries a checkout_url fallback.
91
+ # → { status: "processing", payment_verified: true, booking_ref: "JNK-XEVGW5" }
92
+ # On a 3DS step-up / decline, the response carries a checkout_url fallback (no booking_ref).
92
93
 
93
94
  # 6. Poll status
94
95
  jinko trip-status --trip-id tr_ABC
96
+ # → booking_ref (JNK-…) is the Jinko reference — pass it as --booking-ref to
97
+ # get-booking / hotel-cancel / refund. bookings[].booking_reference is the
98
+ # supplier's confirmation, not that handle.
95
99
  ```
96
100
 
97
101
  ## Hotel flow
@@ -146,8 +150,10 @@ jinko refund status --ref JNK-A7B3X9 --last-name Doe
146
150
 
147
151
  ## Common pitfalls
148
152
 
149
- - **Two auth systems.** CLI OAuth tokens (WorkOS device flow, stored in `~/.jinko/config.yaml`) are NOT interchangeable with MCP OAuth tokens (DCR, different issuer). Don't paste a CLI token into an MCP Bearer header — it will fail with issuer mismatch. Use an API key (`jnk_*`) for cross-surface programmatic access.
150
- - **IATA codes**: `--from PAR` uses a CITY code (matches CDG + ORY + BVA); `--from CDG` uses an airport. `flight-search` has `--origin-type city|airport` to disambiguate.
153
+ - **Use an API key everywhere.** A tenant API key (`jnk_*`) works across the CLI, the SDK, and MCP Bearer headers — it's the one credential to carry. (OAuth sign-in is deprecated; any legacy WorkOS CLI token in `~/.jinko/config.yaml` is NOT interchangeable with an MCP OAuth token and will fail with an issuer mismatch if pasted into an MCP Bearer header.)
154
+ - **IATA codes**: `--origin PAR` uses a CITY code (matches CDG + ORY + BVA); `--origin CDG` uses an airport. `flight-search` has `--origin-type city|airport` to disambiguate — omit it and the platform classifies the code itself, which is the safest choice.
155
+ - **Filters are requests, not guarantees**: `flight-search` answers with `applied_filters` and `unapplied_filters` (name + reason). An unapplied filter still returns 200 with offers — post-filter them yourself or tell the user the constraint could not be met. `--format table` prints the report under the results.
156
+ - **Alternate airports widen an AIRPORT anchor**: `--origin-alternate-airports EWR LGA` adds airports beside `--origin`, never removes results, and the anchor decides ranking — so put the airport that matters most in `--origin`. Against a city anchor the list is ignored and comes back in `unapplied_filters` as `origin` / `destination`.
151
157
  - **trip_item_token format**: `offer_xxx:fare_yyy` (flight) or `htl_xxx:rate_yyy` (hotel). Always the offer ID + fare/rate ID joined by colon.
152
158
  - **Token expiry**: offers cached ~30 min. If `checkout` returns a quote failure, re-run `flight-search`/`hotel-search` to get a fresh token.
153
159
  - **Script use**: set `JINKO_API_KEY` env var and use `--format json` so output parses cleanly.
@@ -18,6 +18,8 @@ Use `get_booking` to retrieve a booking by its Jinko reference and the traveler'
18
18
  }
19
19
  ```
20
20
 
21
+ `booking_ref` is the top-level `booking_ref` that `get_trip` returns once fulfillment has been scheduled (it can precede payment — read `fulfillment.status` for paid), and that `submit_agent_payment` returns once the token is authorized — not the per-item `booking_reference` (the supplier's PNR / confirmation number).
22
+
21
23
  **Response includes:**
22
24
  - `booking_reference`: the Jinko booking reference
23
25
  - `status`: current booking status (completed, processing, etc.)