@gojinko/cli 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.
Files changed (87) hide show
  1. package/README.md +66 -10
  2. package/SKILL.md +28 -14
  3. package/dist/commands/agent-pay.d.ts.map +1 -1
  4. package/dist/commands/agent-pay.js +2 -1
  5. package/dist/commands/agent-pay.js.map +1 -1
  6. package/dist/commands/auth/index.d.ts.map +1 -1
  7. package/dist/commands/auth/index.js +51 -83
  8. package/dist/commands/auth/index.js.map +1 -1
  9. package/dist/commands/auth/prompt.d.ts +0 -9
  10. package/dist/commands/auth/prompt.d.ts.map +1 -1
  11. package/dist/commands/auth/prompt.js +0 -18
  12. package/dist/commands/auth/prompt.js.map +1 -1
  13. package/dist/commands/checkout.d.ts.map +1 -1
  14. package/dist/commands/checkout.js +8 -1
  15. package/dist/commands/checkout.js.map +1 -1
  16. package/dist/commands/exchange.d.ts.map +1 -1
  17. package/dist/commands/exchange.js +16 -18
  18. package/dist/commands/exchange.js.map +1 -1
  19. package/dist/commands/find-dates.d.ts.map +1 -1
  20. package/dist/commands/find-dates.js +2 -1
  21. package/dist/commands/find-dates.js.map +1 -1
  22. package/dist/commands/find-destination.d.ts.map +1 -1
  23. package/dist/commands/find-destination.js +2 -1
  24. package/dist/commands/find-destination.js.map +1 -1
  25. package/dist/commands/flight-calendar.d.ts.map +1 -1
  26. package/dist/commands/flight-calendar.js +2 -1
  27. package/dist/commands/flight-calendar.js.map +1 -1
  28. package/dist/commands/flight-search.d.ts +106 -0
  29. package/dist/commands/flight-search.d.ts.map +1 -1
  30. package/dist/commands/flight-search.js +452 -45
  31. package/dist/commands/flight-search.js.map +1 -1
  32. package/dist/commands/get-booking.d.ts.map +1 -1
  33. package/dist/commands/get-booking.js +3 -2
  34. package/dist/commands/get-booking.js.map +1 -1
  35. package/dist/commands/ground-search.d.ts +62 -0
  36. package/dist/commands/ground-search.d.ts.map +1 -0
  37. package/dist/commands/ground-search.js +236 -0
  38. package/dist/commands/ground-search.js.map +1 -0
  39. package/dist/commands/hotel-cancel.d.ts.map +1 -1
  40. package/dist/commands/hotel-cancel.js +3 -2
  41. package/dist/commands/hotel-cancel.js.map +1 -1
  42. package/dist/commands/hotel-search.d.ts +30 -0
  43. package/dist/commands/hotel-search.d.ts.map +1 -1
  44. package/dist/commands/hotel-search.js +83 -47
  45. package/dist/commands/hotel-search.js.map +1 -1
  46. package/dist/commands/lowest-fare.d.ts.map +1 -1
  47. package/dist/commands/lowest-fare.js +2 -1
  48. package/dist/commands/lowest-fare.js.map +1 -1
  49. package/dist/commands/price-monitoring.d.ts.map +1 -1
  50. package/dist/commands/price-monitoring.js +2 -1
  51. package/dist/commands/price-monitoring.js.map +1 -1
  52. package/dist/commands/refund.d.ts +7 -27
  53. package/dist/commands/refund.d.ts.map +1 -1
  54. package/dist/commands/refund.js +17 -52
  55. package/dist/commands/refund.js.map +1 -1
  56. package/dist/commands/schema.d.ts.map +1 -1
  57. package/dist/commands/schema.js +97 -27
  58. package/dist/commands/schema.js.map +1 -1
  59. package/dist/commands/select-ancillaries.d.ts.map +1 -1
  60. package/dist/commands/select-ancillaries.js +2 -1
  61. package/dist/commands/select-ancillaries.js.map +1 -1
  62. package/dist/commands/shared.d.ts +14 -1
  63. package/dist/commands/shared.d.ts.map +1 -1
  64. package/dist/commands/shared.js +24 -2
  65. package/dist/commands/shared.js.map +1 -1
  66. package/dist/commands/trip-status.d.ts.map +1 -1
  67. package/dist/commands/trip-status.js +2 -0
  68. package/dist/commands/trip-status.js.map +1 -1
  69. package/dist/commands/trip.d.ts.map +1 -1
  70. package/dist/commands/trip.js +4 -1
  71. package/dist/commands/trip.js.map +1 -1
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +2 -0
  74. package/dist/index.js.map +1 -1
  75. package/dist/output/formatter.d.ts +19 -7
  76. package/dist/output/formatter.d.ts.map +1 -1
  77. package/dist/output/formatter.js +22 -8
  78. package/dist/output/formatter.js.map +1 -1
  79. package/dist/output/price-change.d.ts +45 -0
  80. package/dist/output/price-change.d.ts.map +1 -0
  81. package/dist/output/price-change.js +86 -0
  82. package/dist/output/price-change.js.map +1 -0
  83. package/dist/output/remedies.d.ts +30 -0
  84. package/dist/output/remedies.d.ts.map +1 -0
  85. package/dist/output/remedies.js +45 -0
  86. package/dist/output/remedies.js.map +1 -0
  87. package/package.json +3 -4
package/README.md CHANGED
@@ -10,21 +10,28 @@ npm install -g @gojinko/cli
10
10
 
11
11
  ## Authentication
12
12
 
13
+ Jinko authenticates with a **tenant API key** (`jnk_...`). Get one from
14
+ **dashboard.gojinko.com → Developers → API keys**.
15
+
13
16
  ```bash
14
- # API key (recommended for agents, CI/CD)
15
- export JINKO_API_KEY=jnk_YOUR_KEY
17
+ # Store an API key (recommended)
18
+ jinko auth login --key jnk_YOUR_KEY
16
19
 
17
- # OAuth (interactive humans — opens a browser)
20
+ # Or interactively — prompts for the key
18
21
  jinko auth login
22
+
23
+ # Or pass it via the environment (agents, CI/CD)
24
+ export JINKO_API_KEY=jnk_YOUR_KEY
19
25
  ```
20
26
 
21
- Create API keys at https://builders.gojinko.com. OAuth tokens auto-refresh.
27
+ > **OAuth sign-in is deprecated** and no longer supported for the data plane.
28
+ > Use an API key.
22
29
 
23
30
  ### Auth commands
24
31
 
25
32
  ```bash
26
- jinko auth login # Interactive login
27
- jinko auth login --key jnk_… # Store an API key
33
+ jinko auth login --key jnk_… # Store an API key (recommended)
34
+ jinko auth login # Interactive — prompts for an API key
28
35
  jinko auth status # Show current method, expiry
29
36
  jinko auth logout # Clear stored credentials
30
37
  ```
@@ -56,10 +63,11 @@ Prod and sandbox keys are stored separately in `~/.jinko/config.yaml`. Resolutio
56
63
 
57
64
  | Command | Description |
58
65
  |---|---|
59
- | `flight-search` | Direct search by route + dates OR price-check an `offer_token`. Returns bookable `trip_item_token`. |
66
+ | `flight-search` | Direct search by route + dates OR price-check an `offer_token`. Returns bookable `trip_item_token`. Carries the full shop filter set (stops, time windows, layovers, fare attributes, alternate airports) and reports which filters the results honor. |
60
67
  | `price-monitoring` | Cache-only price snapshot for a fixed OD + dates — intended for scheduled polling. Semantically distinct from `flight-search` (one-shot live shopping). |
61
68
  | `hotel-search` | Live hotel search by city / query / geo / hotel-ids. Returns hotels with rooms, rates, `htl_*` offer tokens. |
62
69
  | `hotel-details` | Lazy lookup for a specific hotel — images, amenities, location detail. Pairs with `hotel-search` when the user wants the full picture before booking. |
70
+ | `ground-search` | Live rail / coach / ferry search. Each result's `id` is itself the `trip_item_token` — no prefix. |
63
71
  | `trip` | Create/update a trip, add flight or hotel items, set travelers |
64
72
 
65
73
  ### Legacy
@@ -72,10 +80,10 @@ Prod and sandbox keys are stored separately in `~/.jinko/config.yaml`. Resolutio
72
80
  | Command | Description |
73
81
  |---|---|
74
82
  | `checkout` | Finalize a trip → returns `checkout_url` (human pays in a browser) + `agent_spt_params` (agent pays programmatically) + items + total. (`book` is a deprecated alias.) |
75
- | `agent-pay submit` | Pay programmatically with a Shared Payment Token: present `--trip-id` + `--token`; the BFF schedules the agent fulfillment and redeems the SPT. Falls back to `checkout_url` on a 3DS step-up. |
83
+ | `agent-pay submit` | Pay programmatically with a Shared Payment Token: present `--trip-id` + `--token`; the BFF schedules the agent fulfillment and redeems the SPT. Returns the Jinko `booking_ref` (`JNK-…`) once authorized. Falls back to `checkout_url` on a 3DS step-up. |
76
84
  | `get-ancillaries` | List a trip's purchasable ancillaries (bags / seats / meals) without generating a checkout URL |
77
85
  | `select-ancillaries` | Optional: preselect bags / seats / meals before handoff |
78
- | `trip-status` | Full lifecycle state: cart, quote, fulfillment, bookings |
86
+ | `trip-status` | Full lifecycle state: cart, quote, fulfillment, bookings — plus the Jinko `booking_ref` once fulfillment has been scheduled (it can be present before payment completes — read `fulfillment.status` for paid), the value `get-booking` / `hotel-cancel` / `refund` / `exchange` take as `--booking-ref` |
79
87
 
80
88
  ### Post-booking
81
89
 
@@ -113,12 +121,27 @@ Quote is automatic — `checkout` handles it internally. A human pays on the ret
113
121
  # Live flight search by route + dates (returns trip_item_token directly)
114
122
  jinko flight-search --origin PAR --destination NYC --departure-date 2026-06-15
115
123
 
124
+ # Filtered search — non-stop, morning departure, checked bag in the fare
125
+ jinko flight-search --origin JFK --destination CDG --departure-date 2026-09-01 \
126
+ --max-stops 0 --departure-time-range 06:00-11:00 --checked-bag-included
127
+
128
+ # Widen the search to more departure airports (the anchor still decides ranking)
129
+ jinko flight-search --origin JFK --destination CDG --departure-date 2026-09-01 \
130
+ --origin-alternate-airports EWR LGA
131
+
116
132
  # Or price-check an offer_token from flight-calendar
117
133
  jinko flight-search --offer-token <offer_token>
118
134
 
119
135
  # Live hotel search (returns htl_* tokens that plug into trip the same way as flight tokens)
120
136
  jinko hotel-search --city-name "Paris" --country-code FR --checkin 2026-07-15 --checkout 2026-07-18 --adults 2
121
137
 
138
+ # Live ground search — rail, coach, ferry. Codes are ISO-country + city (GBLON), NOT IATA (LON).
139
+ jinko ground-search --departure-city GBLON --arrival-city FRPAR --date 2026-08-28 --adults 2 --currency GBP
140
+ # --currency is currently REQUIRED despite the schema marking it optional:
141
+ # without it the provider rejects the search and you get an unhelpful "Please retry."
142
+ # Each connection's id IS the trip item token — pass it through unmodified:
143
+ jinko trip --trip-item-token <connection_id>
144
+
122
145
  # Multi-domain cart: add flight + hotel to the same trip → one Stripe checkout
123
146
  jinko trip --trip-item-token <flight_token> # returns trip_id
124
147
  jinko trip --trip-id <trip_id> --trip-item-token <htl_*>
@@ -148,11 +171,44 @@ jinko refund check --booking-ref <ref> --pnr <pnr>
148
171
  jinko refund commit --booking-ref <ref> --pnr <pnr> --reason "schedule change"
149
172
 
150
173
  # Hotel cancellations (idempotent — safe to retry)
151
- jinko hotel-cancel --ref <booking_ref> --last-name <name>
174
+ jinko hotel-cancel --booking-ref <booking_ref> --last-name <name>
152
175
  # Or via the authenticated shortcut:
153
176
  jinko hotel-cancel --provider-booking-id <id> --provider nuitee
154
177
  ```
155
178
 
179
+ ## Flight search filters
180
+
181
+ `flight-search` exposes every filter the `POST /v1/flight_search` contract
182
+ accepts, one option per field — run `jinko flight-search --help` for the list.
183
+ Two things are worth knowing before you use them:
184
+
185
+ **The response says which filters were honored.** Every search comes back with
186
+ `applied_filters` (the ones these results DO honor) and `unapplied_filters`
187
+ (the ones they do not, each with a reason). A filter the platform could not
188
+ enforce is a reported outcome, not an error: the call still returns 200 with
189
+ offers. Post-filter them yourself, or tell the user the constraint could not be
190
+ met. `--format table` prints the report under the results; JSON output carries
191
+ both lists as response fields.
192
+
193
+ **Alternate airports widen an airport anchor.** `--origin-alternate-airports`
194
+ and `--destination-alternate-airports` add departure/arrival airports beside
195
+ `--origin` / `--destination` — widening only, so they can add results but never
196
+ remove any. The anchor decides ranking and truncation, which makes the two
197
+ airports NOT interchangeable: put the airport that matters most in `--origin`.
198
+ Against a city anchor (`--origin-type city`, or a code the platform resolves to
199
+ a city) the list is ignored — a city already searches its whole metro area —
200
+ and comes back in `unapplied_filters` under the name `origin` or `destination`,
201
+ never under the option name it was sent with.
202
+
203
+ ```bash
204
+ jinko flight-search --origin PAR --destination NYC --departure-date 2026-06-15 \
205
+ --origin-alternate-airports ORY --format table
206
+ # ...offers...
207
+ #
208
+ # Unapplied filters:
209
+ # origin — <the reason the platform gives for not enforcing it>
210
+ ```
211
+
156
212
  ## Output Formats
157
213
 
158
214
  ```bash
package/SKILL.md CHANGED
@@ -4,21 +4,21 @@ You are using `jinko`, a CLI for the Jinko developer platform. A trip can be pai
4
4
 
5
5
  ## Authentication
6
6
 
7
- ### Option 1: API Key (recommended for agents and CI/CD)
7
+ Jinko authenticates with a **tenant API key** (`jnk_...`). Get one from
8
+ **dashboard.gojinko.com → Developers → API keys**.
8
9
 
9
10
  ```
11
+ # Store the key (recommended)
12
+ jinko auth login --key jnk_...
13
+
14
+ # Or via the environment (agents, CI/CD)
10
15
  export JINKO_API_KEY=jnk_...
11
16
  ```
12
17
 
13
- Create keys at https://builders.gojinko.com.
14
-
15
- ### Option 2: OAuth (interactive humans)
16
-
17
- ```
18
- jinko auth login
19
- ```
18
+ `jinko auth login` (no flag) prompts for the key interactively and stores it in
19
+ `~/.jinko/config.yaml`.
20
20
 
21
- Opens a browser for WorkOS device flow login. Token is stored in `~/.jinko/config.yaml`.
21
+ > OAuth sign-in is deprecated and no longer supported — use an API key.
22
22
 
23
23
  ## Tools
24
24
 
@@ -28,17 +28,20 @@ Opens a browser for WorkOS device flow login. Token is stored in `~/.jinko/confi
28
28
 
29
29
  ### Pricing (live)
30
30
  - `flight-search` — direct search by route + dates OR price-check an `offer_token`. Returns `trip_item_token`.
31
+ Carries the full shop filter set (`--max-stops`, `--departure-time-range`, `--refundable-only`,
32
+ `--checked-bag-included`, `--via-airports`, `--origin-alternate-airports`, …) — run
33
+ `jinko flight-search --help` for the list.
31
34
 
32
35
  ### Trip building
33
36
  - `trip` — create/update a trip (add items, set travelers + contact). Returns `trip_id`.
34
37
 
35
38
  ### Checkout
36
39
  - `checkout` — finalize a trip; returns BOTH `checkout_url` (a human opens it to pay) AND `agent_spt_params` (an agent uses them to pay programmatically), plus items + ancillaries + total. (`book` is a deprecated alias.)
37
- - `agent-pay submit --trip-id <id> --token <spt>` — pay programmatically: mint a Shared Payment Token scoped to `checkout`'s `agent_spt_params`, then submit it; the BFF schedules the agent fulfillment and redeems the token. A 3DS step-up / decline falls back to a `checkout_url`.
40
+ - `agent-pay submit --trip-id <id> --token <spt>` — pay programmatically: mint a Shared Payment Token scoped to `checkout`'s `agent_spt_params`, then submit it; the BFF schedules the agent fulfillment and redeems the token. Returns the Jinko `booking_ref` (`JNK-…`) once authorized. A 3DS step-up / decline falls back to a `checkout_url`.
38
41
  - `select-ancillaries` — (optional) preselect bags/seats/meals before checkout.
39
42
 
40
43
  ### Status
41
- - `trip-status` — full lifecycle state: cart, quote, fulfillment, bookings (PNRs).
44
+ - `trip-status` — full lifecycle state: cart, quote, fulfillment, bookings (PNRs). Once fulfillment has been scheduled it also carries the Jinko `booking_ref` — the value `get-booking` / `hotel-cancel` / `refund` / `exchange` take as `--booking-ref`. It can be present before payment completes (a hosted checkout still in progress, or an `agent-pay submit` that fell back to `checkout_url`), so presence does not mean paid — read `fulfillment.status`. `bookings[].booking_reference` is the supplier's confirmation, not that handle.
42
45
 
43
46
  ### Post-booking
44
47
  - `refund check` / `refund commit`
@@ -49,7 +52,7 @@ Opens a browser for WorkOS device flow login. Token is stored in `~/.jinko/confi
49
52
  ## Canonical Flow
50
53
 
51
54
  ```
52
- 1. jinko flight-search --from PAR --to NYC --date 2026-05-01
55
+ 1. jinko flight-search --origin PAR --destination NYC --departure-date 2026-05-01
53
56
  → each fare has a trip_item_token (live pricing already applied)
54
57
 
55
58
  2. jinko trip \
@@ -67,10 +70,11 @@ Opens a browser for WorkOS device flow login. Token is stored in `~/.jinko/confi
67
70
  5a. Human path: send the user to checkout_url — they complete payment on the Jinko web page.
68
71
  5b. Agent path: mint a Shared Payment Token scoped to agent_spt_params, then
69
72
  jinko agent-pay submit --trip-id <trip_id> --token <spt>
70
- → { status: "processing", payment_verified: true } (or a checkout_url fallback on 3DS)
73
+ → { status: "processing", payment_verified: true, booking_ref: "JNK-…" } (or a checkout_url fallback on 3DS)
71
74
 
72
75
  6. jinko trip-status --trip-id <trip_id>
73
76
  → poll until status = "fulfilled" (or "partially_fulfilled") to get PNRs.
77
+ → booking_ref is the Jinko reference for get-booking / hotel-cancel / refund / exchange (--booking-ref).
74
78
  ```
75
79
 
76
80
  ## Important Notes
@@ -82,4 +86,14 @@ Opens a browser for WorkOS device flow login. Token is stored in `~/.jinko/confi
82
86
  - Dates: YYYY-MM-DD.
83
87
  - Gender: MALE | FEMALE (uppercase).
84
88
  - Passenger types: ADULT | CHILD | INFANT.
85
- - Cabin classes: economy | premium_economy | business | first.
89
+ - Cabin classes: economy | premium_economy | business | first. Cabin is ADVISORY —
90
+ providers may still return other cabins, so read each fare's own `cabin_class`.
91
+ - `flight-search` reports what it enforced: `applied_filters` lists the requested
92
+ filters the results honor, `unapplied_filters` the ones they do not, each with a
93
+ reason. An unapplied filter is not an error — the call still returns 200. Either
94
+ post-filter the offers yourself or tell the user the constraint could not be met.
95
+ - `--origin-alternate-airports` / `--destination-alternate-airports` WIDEN an airport
96
+ anchor: they add airports beside `--origin` / `--destination`, never remove results.
97
+ The anchor decides ranking, so put the airport that matters most in `--origin`.
98
+ Against a city anchor the list is ignored and reported back under `origin` /
99
+ `destination` in `unapplied_filters`.
@@ -1 +1 @@
1
- {"version":3,"file":"agent-pay.d.ts","sourceRoot":"","sources":["../../src/commands/agent-pay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsBnE"}
1
+ {"version":3,"file":"agent-pay.d.ts","sourceRoot":"","sources":["../../src/commands/agent-pay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBnE"}
@@ -1,4 +1,4 @@
1
- import { withClient, output } from './shared.js';
1
+ import { withClient, output, userIntentOption } from './shared.js';
2
2
  export function registerAgentPaymentCommands(program) {
3
3
  const agent = program
4
4
  .command('agent-pay')
@@ -10,6 +10,7 @@ export function registerAgentPaymentCommands(program) {
10
10
  .description('Present a trip ID and a Shared Payment Token: the BFF schedules the agent fulfillment and redeems the token to authorize the booking server-side, advancing it to fulfillment. If the issuer requires customer action (3DS) the response carries a checkout_url fallback instead of confirming.')
11
11
  .requiredOption('--trip-id <id>', 'trip ID (from the trip command) [required]')
12
12
  .requiredOption('--token <spt>', 'Shared Payment Token (spt_...) [required]')
13
+ .addOption(userIntentOption())
13
14
  .action(withClient(async (client, globals, opts) => {
14
15
  const response = await client.submitAgentPayment(opts.tripId, opts.token);
15
16
  output(response, { format: globals.format });
@@ -1 +1 @@
1
- {"version":3,"file":"agent-pay.js","sourceRoot":"","sources":["../../src/commands/agent-pay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,UAAU,4BAA4B,CAAC,OAAgB;IAC3D,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,WAAW,CAAC;SACpB,OAAO,CAAC,gFAAgF,CAAC;SACzF,WAAW,CACV,0ZAA0Z,CAC3Z,CAAC;IAEJ,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,OAAO,CAAC,mEAAmE,CAAC;SAC5E,WAAW,CACV,iSAAiS,CAClS;SACA,cAAc,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SAC9E,cAAc,CAAC,eAAe,EAAE,2CAA2C,CAAC;SAC5E,MAAM,CACL,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"agent-pay.js","sourceRoot":"","sources":["../../src/commands/agent-pay.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEnE,MAAM,UAAU,4BAA4B,CAAC,OAAgB;IAC3D,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,WAAW,CAAC;SACpB,OAAO,CAAC,gFAAgF,CAAC;SACzF,WAAW,CACV,0ZAA0Z,CAC3Z,CAAC;IAEJ,KAAK;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,OAAO,CAAC,mEAAmE,CAAC;SAC5E,WAAW,CACV,iSAAiS,CAClS;SACA,cAAc,CAAC,gBAAgB,EAAE,4CAA4C,CAAC;SAC9E,cAAc,CAAC,eAAe,EAAE,2CAA2C,CAAC;SAC5E,SAAS,CAAC,gBAAgB,EAAE,CAAC;SAC7B,MAAM,CACL,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6K3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AA0C5C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+G3D"}
@@ -1,100 +1,66 @@
1
- import { resolveAuth, resolveEnvironment, writeEnvAuth, clearAuthConfig, clearCliSession, readConfigFile, CONFIG_FILE, requestDeviceAuthorization, pollForToken, OAuthError, } from '@gojinko/api-client';
1
+ import { Option } from 'commander';
2
+ import { resolveAuth, resolveEnvironment, writeEnvAuth, clearAuthConfig, clearCliSession, readConfigFile, CONFIG_FILE, } from '@gojinko/api-client';
2
3
  import { output, outputError } from '../shared.js';
3
4
  import { getGlobalOptions } from '../../config/config.js';
4
- import { promptChoice, promptText } from './prompt.js';
5
+ import { promptText } from './prompt.js';
6
+ // The single documented way to authenticate the Jinko data plane. OAuth
7
+ // sign-in was retired, so every "how do I authenticate?" message points here.
8
+ const API_KEY_SOURCE = 'dashboard.gojinko.com → Developers → API keys';
9
+ /**
10
+ * Validate a `jnk_` API key and persist it to the environment's credential
11
+ * slot. Exits with code 3 on a missing/malformed key. `writeEnvAuth` deep-merges
12
+ * a fresh config object, so the on-disk config is replaced, never mutated.
13
+ */
14
+ async function saveApiKey(env, token, globals) {
15
+ if (!token) {
16
+ outputError({ code: 'INVALID_TOKEN', message: `No API key provided. Get one from ${API_KEY_SOURCE}.` }, globals);
17
+ process.exit(3);
18
+ }
19
+ if (!token.startsWith('jnk_')) {
20
+ outputError({ code: 'INVALID_TOKEN', message: `API key must start with "jnk_". Get one from ${API_KEY_SOURCE}.` }, globals);
21
+ process.exit(3);
22
+ }
23
+ await writeEnvAuth(env, { api_key: token });
24
+ output({
25
+ status: 'ok',
26
+ method: 'api_key',
27
+ environment: env,
28
+ message: `API key saved to ${CONFIG_FILE} (environment: ${env})`,
29
+ }, { format: globals.format });
30
+ }
5
31
  export function registerAuthCommands(program) {
6
32
  const auth = program
7
33
  .command('auth')
8
34
  .description('Manage authentication.');
9
35
  auth
10
36
  .command('login')
11
- .description('Authenticate with Jinko (OAuth or API key).')
12
- .option('--key <token>', 'API key (jnk_...) — skip interactive prompt')
37
+ .description(`Authenticate with a Jinko API key (jnk_...). Get one from ${API_KEY_SOURCE}.`)
38
+ .option('--key <token>', 'API key (jnk_...) — skip the interactive prompt')
39
+ // Hidden escape hatch. OAuth sign-in is deprecated and no longer works for
40
+ // the data plane; this flag exists only so anyone reaching for the old flow
41
+ // gets a clear signpost to API keys instead of a cryptic "unknown option".
42
+ .addOption(new Option('--oauth', 'Deprecated — OAuth sign-in is no longer supported').hideHelp())
13
43
  .action(async (opts, cmd) => {
14
44
  const globals = getGlobalOptions(cmd);
15
45
  // Credentials are stored per-environment so prod and sandbox keys coexist.
16
46
  const env = await resolveEnvironment(globals.environment);
17
- // Fast path: --key flag → direct API key save
18
- if (opts['key']) {
19
- const token = opts['key'];
20
- if (!token.startsWith('jnk_')) {
21
- outputError({ code: 'INVALID_TOKEN', message: 'API key must start with "jnk_". Get one from the Jinko developer platform.' }, globals);
22
- process.exit(3);
23
- }
24
- await writeEnvAuth(env, { api_key: token });
25
- output({
26
- status: 'ok',
27
- method: 'api_key',
28
- environment: env,
29
- message: `API key saved to ${CONFIG_FILE} (environment: ${env})`,
30
- }, { format: globals.format });
31
- return;
47
+ // Deprecated OAuth path — do not run the device flow; point at API keys.
48
+ if (opts['oauth']) {
49
+ outputError({
50
+ code: 'OAUTH_DEPRECATED',
51
+ message: `OAuth sign-in is deprecated and no longer supported. Get an API key from ${API_KEY_SOURCE}, then run \`jinko auth login --key jnk_...\`.`,
52
+ }, globals);
53
+ process.exit(3);
32
54
  }
33
- // Interactive: choose auth method
34
- const method = await promptChoice('How would you like to authenticate?', [
35
- { label: 'OAuth — sign in with browser (recommended)', value: 'oauth' },
36
- { label: 'API key — paste a jnk_... token', value: 'api_key' },
37
- ]);
38
- if (method === 'api_key') {
39
- const token = await promptText('Enter your Jinko API key (jnk_...): ');
40
- if (!token) {
41
- outputError({ code: 'INVALID_TOKEN', message: 'No API key provided.' }, globals);
42
- process.exit(3);
43
- }
44
- if (!token.startsWith('jnk_')) {
45
- outputError({ code: 'INVALID_TOKEN', message: 'API key must start with "jnk_". Get one from the Jinko developer platform.' }, globals);
46
- process.exit(3);
47
- }
48
- await writeEnvAuth(env, { api_key: token });
49
- output({
50
- status: 'ok',
51
- method: 'api_key',
52
- environment: env,
53
- message: `API key saved to ${CONFIG_FILE} (environment: ${env})`,
54
- }, { format: globals.format });
55
+ // Fast path: --key flag → save without prompting.
56
+ if (opts['key']) {
57
+ await saveApiKey(env, opts['key'], globals);
55
58
  return;
56
59
  }
57
- // OAuth Device Authorization Flow
58
- try {
59
- console.log('Requesting device authorization...\n');
60
- const device = await requestDeviceAuthorization();
61
- console.log(`Visit this URL to authenticate:\n`);
62
- console.log(` ${device.verification_uri_complete}\n`);
63
- console.log(`Or go to ${device.verification_uri} and enter code: ${device.user_code}\n`);
64
- // Try to open browser automatically
65
- try {
66
- const open = await import('open');
67
- await open.default(device.verification_uri_complete);
68
- }
69
- catch {
70
- // Browser open failed — URL is already printed above
71
- }
72
- console.log('Waiting for approval...');
73
- const tokens = await pollForToken(device.device_code, {
74
- intervalSeconds: device.interval,
75
- expiresIn: device.expires_in,
76
- });
77
- await writeEnvAuth(env, {
78
- oauth: {
79
- access_token: tokens.access_token,
80
- refresh_token: tokens.refresh_token,
81
- expires_at: tokens.expires_at,
82
- },
83
- });
84
- output({
85
- status: 'ok',
86
- method: 'oauth',
87
- environment: env,
88
- message: `Authenticated successfully. Credentials saved to ${CONFIG_FILE} (environment: ${env})`,
89
- }, { format: globals.format });
90
- }
91
- catch (error) {
92
- if (error instanceof OAuthError) {
93
- outputError({ code: 'OAUTH_ERROR', message: error.message }, globals);
94
- process.exit(3);
95
- }
96
- throw error;
97
- }
60
+ // Interactive: API keys are the only supported auth, so prompt for one
61
+ // directly — no method-choice menu.
62
+ const token = await promptText('Enter your Jinko API key (jnk_...): ');
63
+ await saveApiKey(env, token, globals);
98
64
  });
99
65
  auth
100
66
  .command('logout')
@@ -143,7 +109,9 @@ export function registerAuthCommands(program) {
143
109
  token: masked,
144
110
  source,
145
111
  };
146
- // Add expiry info for OAuth — prefer the per-env slot, fall back to legacy top-level.
112
+ // Add expiry info for OAuth — prefer the per-env slot, fall back to legacy
113
+ // top-level. OAuth login is deprecated; this branch only fires for
114
+ // pre-existing OAuth credentials still present in ~/.jinko/config.yaml.
147
115
  if (auth.method === 'oauth' && source === 'config') {
148
116
  const config = await readConfigFile();
149
117
  const oauth = config?.environments?.[env]?.oauth ?? config?.oauth;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,5 @@
1
- interface Choice<T> {
2
- readonly label: string;
3
- readonly value: T;
4
- }
5
- /**
6
- * Interactive numbered-menu prompt. Returns selected value.
7
- */
8
- export declare function promptChoice<T>(question: string, choices: ReadonlyArray<Choice<T>>): Promise<T>;
9
1
  /**
10
2
  * Simple text prompt. Returns trimmed input.
11
3
  */
12
4
  export declare function promptText(question: string): Promise<string>;
13
- export {};
14
5
  //# sourceMappingURL=prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/prompt.ts"],"names":[],"mappings":"AAEA,UAAU,MAAM,CAAC,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAgBrG;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlE"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/prompt.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlE"}
@@ -1,22 +1,4 @@
1
1
  import { createInterface } from 'node:readline';
2
- /**
3
- * Interactive numbered-menu prompt. Returns selected value.
4
- */
5
- export async function promptChoice(question, choices) {
6
- const rl = createInterface({ input: process.stdin, output: process.stdout });
7
- const menu = choices.map((c, i) => ` ${i + 1}) ${c.label}`).join('\n');
8
- return new Promise((resolve, reject) => {
9
- rl.question(`${question}\n${menu}\n\nChoice: `, (answer) => {
10
- rl.close();
11
- const index = parseInt(answer.trim(), 10) - 1;
12
- if (isNaN(index) || index < 0 || index >= choices.length) {
13
- reject(new Error('Invalid choice'));
14
- return;
15
- }
16
- resolve(choices[index].value);
17
- });
18
- });
19
- }
20
2
  /**
21
3
  * Simple text prompt. Returns trimmed input.
22
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/commands/auth/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAOhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,OAAiC;IACvF,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7E,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAExE,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,KAAK,IAAI,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE;YACzD,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACzD,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YACD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAE,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/commands/auth/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QACrC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuB9D"}
1
+ {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6B9D"}
@@ -1,13 +1,18 @@
1
- import { withClient, output } from './shared.js';
1
+ import { withClient, output, userIntentOption } from './shared.js';
2
+ import { printPriceChangeNotices } from '../output/price-change.js';
2
3
  export function registerCheckoutCommand(program) {
3
4
  program
4
5
  .command('checkout')
5
6
  .summary('Checkout a trip — returns a checkout URL the user opens to pay, plus agent payment params')
6
7
  .description('Finalize a finalized trip. Use it once the trip is set and traveler details are filled in, for example after the user picks a Paris to Tokyo round trip and adds a hotel for the stay. The response carries two payment paths: `checkout_url` is what a human opens in a browser to pay, and `agent_spt_params` (max amount, currency, profile) is what an agent uses to mint a Shared Payment Token and pay programmatically via `agent-pay submit`.')
7
8
  .requiredOption('--trip-id <id>', 'trip ID (from trip command) [required]')
9
+ .addOption(userIntentOption())
8
10
  .action(withClient(async (client, globals, opts) => {
9
11
  const response = await client.checkout(opts.tripId);
10
12
  output(response, { format: globals.format });
13
+ // Last thing the user reads before they open checkout_url: the price
14
+ // they are about to pay is not the one they were shown in search.
15
+ printPriceChangeNotices(response);
11
16
  }));
12
17
  // DEPRECATED alias — `book` was renamed to `checkout` (JIN-1131). Kept so
13
18
  // existing scripts keep working; mcp-apps still exposes `book`.
@@ -15,9 +20,11 @@ export function registerCheckoutCommand(program) {
15
20
  .command('book', { hidden: true })
16
21
  .summary('DEPRECATED — use `checkout`. Alias retained for backward compatibility.')
17
22
  .requiredOption('--trip-id <id>', 'trip ID (from trip command) [required]')
23
+ .addOption(userIntentOption())
18
24
  .action(withClient(async (client, globals, opts) => {
19
25
  const response = await client.book(opts.tripId);
20
26
  output(response, { format: globals.format });
27
+ printPriceChangeNotices(response);
21
28
  }));
22
29
  }
23
30
  //# sourceMappingURL=checkout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,OAAO,CAAC,2FAA2F,CAAC;SACpG,WAAW,CACV,ubAAub,CACxb;SACA,cAAc,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAC1E,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,CAAC;IAEN,0EAA0E;IAC1E,gEAAgE;IAChE,OAAO;SACJ,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACjC,OAAO,CAAC,yEAAyE,CAAC;SAClF,cAAc,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAC1E,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
1
+ {"version":3,"file":"checkout.js","sourceRoot":"","sources":["../../src/commands/checkout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,OAAO,CAAC,2FAA2F,CAAC;SACpG,WAAW,CACV,ubAAub,CACxb;SACA,cAAc,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAC1E,SAAS,CAAC,gBAAgB,EAAE,CAAC;SAC7B,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,qEAAqE;QACrE,kEAAkE;QAClE,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC,CAAC;IAEN,0EAA0E;IAC1E,gEAAgE;IAChE,OAAO;SACJ,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACjC,OAAO,CAAC,yEAAyE,CAAC;SAClF,cAAc,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAC1E,SAAS,CAAC,gBAAgB,EAAE,CAAC;SAC7B,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7C,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"exchange.d.ts","sourceRoot":"","sources":["../../src/commands/exchange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuF9D"}
1
+ {"version":3,"file":"exchange.d.ts","sourceRoot":"","sources":["../../src/commands/exchange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqF9D"}