letsfg 1.1.1 → 1.4.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.
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
- # LetsFG — Agent-Native Flight Search & Booking (Node.js)
1
+ # LetsFG — Your AI agent just learned to book flights. (Node.js)
2
2
 
3
- Search 400+ airlines at raw airline prices — **$50 cheaper** than Booking.com, Kayak, and other OTAs. Zero dependencies. Built for autonomous AI agents — works with Claude, Cursor, Windsurf, and any MCP-compatible client.
3
+ **195 airlines. Real prices. One function call.** Search 400+ airlines at raw airline prices — **$20–$50 cheaper** than Booking.com, Kayak, and other OTAs. Zero dependencies. Built for AI agents.
4
+
5
+ > **Don't want to install anything?** [**Try it on Messenger**](https://m.me/61579557368989) — search flights instantly, no setup needed.
6
+
7
+ [![GitHub stars](https://img.shields.io/github/stars/LetsFG/LetsFG?style=social)](https://github.com/LetsFG/LetsFG)
8
+ [![npm](https://img.shields.io/npm/v/letsfg)](https://www.npmjs.com/package/letsfg)
9
+
10
+ > ⭐ **[Star the repo](https://github.com/LetsFG/LetsFG) → register → unlimited access forever.** First 1,000 stars only.
4
11
 
5
12
  ## Install
6
13
 
@@ -74,7 +81,7 @@ letsfg book off_xxx -p '{"id":"pas_xxx","given_name":"John",...}' -e john@exampl
74
81
 
75
82
  ### `searchLocal(origin, destination, dateFrom, options?)`
76
83
 
77
- Search 150+ airline connectors locally (no API key needed). Requires Python + `letsfg` installed.
84
+ Search 195 airline connectors locally (no API key needed). Requires Python + `letsfg` installed.
78
85
 
79
86
  ```typescript
80
87
  import { searchLocal } from 'letsfg';
@@ -118,8 +125,11 @@ Or set the `LETSFG_MAX_BROWSERS` environment variable globally.
118
125
 
119
126
  - **MCP Server**: `npx letsfg-mcp` — [npm](https://www.npmjs.com/package/letsfg-mcp)
120
127
  - **Python SDK + CLI**: `pip install letsfg` — [PyPI](https://pypi.org/project/letsfg/)
128
+ - **Try without installing**: [Message us on Messenger](https://m.me/61579557368989)
121
129
  - **GitHub**: [LetsFG/LetsFG](https://github.com/LetsFG/LetsFG)
122
130
 
131
+ > ⭐ **[Star the repo](https://github.com/LetsFG/LetsFG)** to unlock free access. First 1,000 stars only.
132
+
123
133
  ## License
124
134
 
125
135
  MIT
@@ -106,6 +106,12 @@ var ValidationError = class extends LetsFGError {
106
106
  this.name = "ValidationError";
107
107
  }
108
108
  };
109
+ var StarRequiredError = class extends LetsFGError {
110
+ constructor(message = "GitHub star required. Run: letsfg star --github <your-username>") {
111
+ super(message, 403, {}, "STAR_REQUIRED");
112
+ this.name = "StarRequiredError";
113
+ }
114
+ };
109
115
  function routeStr(route) {
110
116
  if (!route.segments.length) return "";
111
117
  const codes = [route.segments[0].origin, ...route.segments.map((s) => s.destination)];
@@ -156,8 +162,13 @@ async function searchLocal(origin, destination, dateFrom, options = {}) {
156
162
  child.on("close", (code) => {
157
163
  try {
158
164
  const data = JSON.parse(stdout);
159
- if (data.error) reject(new LetsFGError(data.error));
160
- else resolve(data);
165
+ if (data.error) {
166
+ if (data.error.includes("GitHub star required") || data.error.includes("star required")) {
167
+ reject(new StarRequiredError(data.error));
168
+ } else {
169
+ reject(new LetsFGError(data.error));
170
+ }
171
+ } else resolve(data);
161
172
  } catch {
162
173
  reject(new LetsFGError(
163
174
  `Python search failed (code ${code}): ${stdout || stderr}
@@ -459,6 +470,7 @@ export {
459
470
  PaymentRequiredError,
460
471
  OfferExpiredError,
461
472
  ValidationError,
473
+ StarRequiredError,
462
474
  offerSummary,
463
475
  cheapestOffer,
464
476
  searchLocal,
package/dist/cli.js CHANGED
@@ -131,6 +131,12 @@ var ValidationError = class extends LetsFGError {
131
131
  this.name = "ValidationError";
132
132
  }
133
133
  };
134
+ var StarRequiredError = class extends LetsFGError {
135
+ constructor(message = "GitHub star required. Run: letsfg star --github <your-username>") {
136
+ super(message, 403, {}, "STAR_REQUIRED");
137
+ this.name = "StarRequiredError";
138
+ }
139
+ };
134
140
  function routeStr(route) {
135
141
  if (!route.segments.length) return "";
136
142
  const codes = [route.segments[0].origin, ...route.segments.map((s) => s.destination)];
@@ -604,42 +610,44 @@ async function cmdRegister(args) {
604
610
  }
605
611
  async function cmdStar(args) {
606
612
  const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
607
- const apiKey = getFlag(args, "--api-key", "-k");
608
- const baseUrl = getFlag(args, "--base-url");
609
613
  const github = getFlag(args, "--github", "-g");
610
614
  if (!github) {
611
615
  console.error("Usage: letsfg star --github <your-github-username>");
612
616
  process.exit(1);
613
617
  }
614
- const bt = new LetsFG({ apiKey, baseUrl });
615
- const result = await bt.linkGithub(github);
616
- if (jsonOut) {
617
- console.log(JSON.stringify(result, null, 2));
618
- return;
619
- }
620
- const status = result.status;
621
- if (status === "verified") {
622
- console.log(`
623
- \u2713 GitHub star verified! Unlimited access granted.`);
624
- console.log(` Username: ${result.github_username}`);
625
- console.log(`
626
- You're all set \u2014 search, unlock, and book for free.
627
- `);
628
- } else if (status === "already_verified") {
629
- console.log(`
630
- \u2713 Already verified! You have unlimited access.`);
631
- console.log(` Username: ${result.github_username}
632
- `);
633
- } else if (status === "star_required") {
634
- console.log(`
635
- \u2717 Star not found for '${github}'.`);
636
- console.log(` 1. Star the repo: https://github.com/LetsFG/LetsFG`);
637
- console.log(` 2. Run this command again.
638
- `);
639
- } else {
640
- console.error(` \u2717 Unexpected status: ${status}`);
641
- process.exit(1);
642
- }
618
+ const { spawn } = await import("child_process");
619
+ const pythonCmd = process.platform === "win32" ? "python" : "python3";
620
+ return new Promise((resolve, reject) => {
621
+ const child = spawn(pythonCmd, ["-m", "letsfg.cli", "star", "--github", github], {
622
+ stdio: ["inherit", "pipe", "pipe"]
623
+ });
624
+ let stdout = "";
625
+ let stderr = "";
626
+ child.stdout.on("data", (d) => {
627
+ stdout += d.toString();
628
+ });
629
+ child.stderr.on("data", (d) => {
630
+ stderr += d.toString();
631
+ });
632
+ child.on("close", (code) => {
633
+ if (jsonOut) {
634
+ const verified = code === 0;
635
+ console.log(JSON.stringify({ status: verified ? "verified" : "star_required", github_username: github }));
636
+ } else {
637
+ if (stdout) console.log(stdout);
638
+ if (stderr && code !== 0) console.error(stderr);
639
+ }
640
+ if (code !== 0) {
641
+ process.exit(1);
642
+ }
643
+ resolve();
644
+ });
645
+ child.on("error", (err) => {
646
+ console.error(`Cannot start Python: ${err.message}`);
647
+ console.error("Install: pip install letsfg");
648
+ process.exit(1);
649
+ });
650
+ });
643
651
  }
644
652
  async function cmdSetupPayment(args) {
645
653
  const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
@@ -697,16 +705,19 @@ var HELP = `
697
705
  LetsFG \u2014 Agent-native flight search & booking.
698
706
 
699
707
  Search 400+ airlines at raw airline prices \u2014 $20-50 cheaper than OTAs.
700
- 100% FREE \u2014 just star our GitHub repo for unlimited access.
708
+
709
+ **GitHub Star Required!**
710
+ Before using, you must:
711
+ 1. Star https://github.com/LetsFG/LetsFG
712
+ 2. Run: letsfg star --github <your-username>
701
713
 
702
714
  Commands:
703
- search <origin> <dest> <date> Search for flights (FREE)
715
+ star --github <username> Verify GitHub star (required first!)
716
+ search <origin> <dest> <date> Search for flights (FREE with star)
704
717
  locations <query> Resolve city name to IATA codes
705
- star --github <username> Link GitHub \u2014 star repo for free access
706
- unlock <offer_id> Unlock offer (FREE with GitHub star)
707
- book <offer_id> --passenger ... Book flight (FREE after unlock)
718
+ unlock <offer_id> Unlock offer (hosted mode only)
719
+ book <offer_id> --passenger ... Book flight
708
720
  register --name ... --email ... Register new agent
709
- setup-payment Legacy payment setup
710
721
  me Show agent profile
711
722
 
712
723
  Options:
@@ -715,7 +726,6 @@ Options:
715
726
  --base-url API URL (default: https://api.letsfg.co)
716
727
 
717
728
  Examples:
718
- letsfg register --name my-agent --email me@example.com
719
729
  letsfg star --github octocat
720
730
  letsfg search GDN BER 2026-03-03 --sort price
721
731
  letsfg unlock off_xxx
@@ -762,6 +772,17 @@ async function main() {
762
772
  process.exit(1);
763
773
  }
764
774
  } catch (e) {
775
+ if (e instanceof StarRequiredError) {
776
+ console.error(`
777
+ \u2B50 GitHub star required to use LetsFG!
778
+ `);
779
+ console.error(` 1. Star the repo: https://github.com/LetsFG/LetsFG`);
780
+ console.error(` 2. Run: letsfg star --github <your-username>
781
+ `);
782
+ console.error(` This is completely FREE \u2014 just a star to help us grow!
783
+ `);
784
+ process.exit(1);
785
+ }
765
786
  if (e instanceof LetsFGError) {
766
787
  console.error(`Error: ${e.message}`);
767
788
  process.exit(1);
package/dist/cli.mjs CHANGED
@@ -2,8 +2,9 @@
2
2
  import {
3
3
  LetsFG,
4
4
  LetsFGError,
5
+ StarRequiredError,
5
6
  offerSummary
6
- } from "./chunk-R2DLDQIL.mjs";
7
+ } from "./chunk-7LYR3CHE.mjs";
7
8
 
8
9
  // src/cli.ts
9
10
  function getFlag(args, flag, alias) {
@@ -225,42 +226,44 @@ async function cmdRegister(args) {
225
226
  }
226
227
  async function cmdStar(args) {
227
228
  const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
228
- const apiKey = getFlag(args, "--api-key", "-k");
229
- const baseUrl = getFlag(args, "--base-url");
230
229
  const github = getFlag(args, "--github", "-g");
231
230
  if (!github) {
232
231
  console.error("Usage: letsfg star --github <your-github-username>");
233
232
  process.exit(1);
234
233
  }
235
- const bt = new LetsFG({ apiKey, baseUrl });
236
- const result = await bt.linkGithub(github);
237
- if (jsonOut) {
238
- console.log(JSON.stringify(result, null, 2));
239
- return;
240
- }
241
- const status = result.status;
242
- if (status === "verified") {
243
- console.log(`
244
- \u2713 GitHub star verified! Unlimited access granted.`);
245
- console.log(` Username: ${result.github_username}`);
246
- console.log(`
247
- You're all set \u2014 search, unlock, and book for free.
248
- `);
249
- } else if (status === "already_verified") {
250
- console.log(`
251
- \u2713 Already verified! You have unlimited access.`);
252
- console.log(` Username: ${result.github_username}
253
- `);
254
- } else if (status === "star_required") {
255
- console.log(`
256
- \u2717 Star not found for '${github}'.`);
257
- console.log(` 1. Star the repo: https://github.com/LetsFG/LetsFG`);
258
- console.log(` 2. Run this command again.
259
- `);
260
- } else {
261
- console.error(` \u2717 Unexpected status: ${status}`);
262
- process.exit(1);
263
- }
234
+ const { spawn } = await import("child_process");
235
+ const pythonCmd = process.platform === "win32" ? "python" : "python3";
236
+ return new Promise((resolve, reject) => {
237
+ const child = spawn(pythonCmd, ["-m", "letsfg.cli", "star", "--github", github], {
238
+ stdio: ["inherit", "pipe", "pipe"]
239
+ });
240
+ let stdout = "";
241
+ let stderr = "";
242
+ child.stdout.on("data", (d) => {
243
+ stdout += d.toString();
244
+ });
245
+ child.stderr.on("data", (d) => {
246
+ stderr += d.toString();
247
+ });
248
+ child.on("close", (code) => {
249
+ if (jsonOut) {
250
+ const verified = code === 0;
251
+ console.log(JSON.stringify({ status: verified ? "verified" : "star_required", github_username: github }));
252
+ } else {
253
+ if (stdout) console.log(stdout);
254
+ if (stderr && code !== 0) console.error(stderr);
255
+ }
256
+ if (code !== 0) {
257
+ process.exit(1);
258
+ }
259
+ resolve();
260
+ });
261
+ child.on("error", (err) => {
262
+ console.error(`Cannot start Python: ${err.message}`);
263
+ console.error("Install: pip install letsfg");
264
+ process.exit(1);
265
+ });
266
+ });
264
267
  }
265
268
  async function cmdSetupPayment(args) {
266
269
  const jsonOut = hasFlag(args, "--json") || hasFlag(args, "-j");
@@ -318,16 +321,19 @@ var HELP = `
318
321
  LetsFG \u2014 Agent-native flight search & booking.
319
322
 
320
323
  Search 400+ airlines at raw airline prices \u2014 $20-50 cheaper than OTAs.
321
- 100% FREE \u2014 just star our GitHub repo for unlimited access.
324
+
325
+ **GitHub Star Required!**
326
+ Before using, you must:
327
+ 1. Star https://github.com/LetsFG/LetsFG
328
+ 2. Run: letsfg star --github <your-username>
322
329
 
323
330
  Commands:
324
- search <origin> <dest> <date> Search for flights (FREE)
331
+ star --github <username> Verify GitHub star (required first!)
332
+ search <origin> <dest> <date> Search for flights (FREE with star)
325
333
  locations <query> Resolve city name to IATA codes
326
- star --github <username> Link GitHub \u2014 star repo for free access
327
- unlock <offer_id> Unlock offer (FREE with GitHub star)
328
- book <offer_id> --passenger ... Book flight (FREE after unlock)
334
+ unlock <offer_id> Unlock offer (hosted mode only)
335
+ book <offer_id> --passenger ... Book flight
329
336
  register --name ... --email ... Register new agent
330
- setup-payment Legacy payment setup
331
337
  me Show agent profile
332
338
 
333
339
  Options:
@@ -336,7 +342,6 @@ Options:
336
342
  --base-url API URL (default: https://api.letsfg.co)
337
343
 
338
344
  Examples:
339
- letsfg register --name my-agent --email me@example.com
340
345
  letsfg star --github octocat
341
346
  letsfg search GDN BER 2026-03-03 --sort price
342
347
  letsfg unlock off_xxx
@@ -383,6 +388,17 @@ async function main() {
383
388
  process.exit(1);
384
389
  }
385
390
  } catch (e) {
391
+ if (e instanceof StarRequiredError) {
392
+ console.error(`
393
+ \u2B50 GitHub star required to use LetsFG!
394
+ `);
395
+ console.error(` 1. Star the repo: https://github.com/LetsFG/LetsFG`);
396
+ console.error(` 2. Run: letsfg star --github <your-username>
397
+ `);
398
+ console.error(` This is completely FREE \u2014 just a star to help us grow!
399
+ `);
400
+ process.exit(1);
401
+ }
386
402
  if (e instanceof LetsFGError) {
387
403
  console.error(`Error: ${e.message}`);
388
404
  process.exit(1);
package/dist/index.d.mts CHANGED
@@ -1,14 +1,19 @@
1
1
  /**
2
2
  * LetsFG — Agent-native flight search & booking SDK for Node.js/TypeScript.
3
3
  *
4
- * 75 airline connectors run locally via Python + backend API for enterprise GDS/NDC sources.
4
+ * 195 airline connectors run locally via Python + backend API for enterprise GDS/NDC sources.
5
5
  * Zero external JS dependencies. Uses native fetch (Node 18+).
6
6
  *
7
+ * **GitHub Star Required!**
8
+ * Before using, you must:
9
+ * 1. Star https://github.com/LetsFG/LetsFG
10
+ * 2. Run: letsfg star --github <your-username>
11
+ *
7
12
  * @example
8
13
  * ```ts
9
14
  * import { LetsFG, searchLocal } from 'letsfg';
10
15
  *
11
- * // Local search — FREE, no API key
16
+ * // Local search — FREE with GitHub star
12
17
  * const local = await searchLocal('SHA', 'CTU', '2026-03-20');
13
18
  *
14
19
  * // Full API — search + unlock + book
@@ -183,12 +188,25 @@ declare class OfferExpiredError extends LetsFGError {
183
188
  declare class ValidationError extends LetsFGError {
184
189
  constructor(message: string, statusCode?: number, response?: Record<string, unknown>, errorCode?: string);
185
190
  }
191
+ /**
192
+ * Thrown when GitHub star verification is required.
193
+ * Users must star https://github.com/LetsFG/LetsFG and run:
194
+ * letsfg star --github <username>
195
+ */
196
+ declare class StarRequiredError extends LetsFGError {
197
+ constructor(message?: string);
198
+ }
186
199
  /** One-line offer summary */
187
200
  declare function offerSummary(offer: FlightOffer): string;
188
201
  /** Get cheapest offer from search results */
189
202
  declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
190
203
  /**
191
- * Search flights using 73 local airline connectors — FREE, no API key needed.
204
+ * Search flights using 195 local airline connectors — FREE with GitHub star!
205
+ *
206
+ * **GitHub Star Required!**
207
+ * Before using, you must:
208
+ * 1. Star https://github.com/LetsFG/LetsFG
209
+ * 2. Run: letsfg star --github <your-username>
192
210
  *
193
211
  * Requires: pip install letsfg && playwright install chromium
194
212
  *
@@ -196,6 +214,7 @@ declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
196
214
  * @param destination - IATA code (e.g., "CTU")
197
215
  * @param dateFrom - Departure date "YYYY-MM-DD"
198
216
  * @param options - Optional: currency, adults, limit, etc.
217
+ * @throws {StarRequiredError} If GitHub star not verified
199
218
  */
200
219
  declare function searchLocal(origin: string, destination: string, dateFrom: string, options?: Partial<SearchOptions>): Promise<FlightSearchResult>;
201
220
  declare class LetsFG {
@@ -282,4 +301,4 @@ declare const BoostedTravel: typeof LetsFG;
282
301
  declare const BoostedTravelError: typeof LetsFGError;
283
302
  type BoostedTravelConfig = LetsFGConfig;
284
303
 
285
- export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type CheckoutProgress, ErrorCategory, type ErrorCategoryType, ErrorCode, type ErrorCodeType, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, LetsFG, type LetsFGConfig, LetsFGError, OfferExpiredError, type Passenger, PaymentRequiredError, type SearchOptions, type UnlockResult, ValidationError, cheapestOffer, LetsFG as default, systemInfo as getSystemInfo, searchLocal as localSearch, offerSummary, searchLocal, systemInfo };
304
+ export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type CheckoutProgress, ErrorCategory, type ErrorCategoryType, ErrorCode, type ErrorCodeType, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, LetsFG, type LetsFGConfig, LetsFGError, OfferExpiredError, type Passenger, PaymentRequiredError, type SearchOptions, StarRequiredError, type UnlockResult, ValidationError, cheapestOffer, LetsFG as default, systemInfo as getSystemInfo, searchLocal as localSearch, offerSummary, searchLocal, systemInfo };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,19 @@
1
1
  /**
2
2
  * LetsFG — Agent-native flight search & booking SDK for Node.js/TypeScript.
3
3
  *
4
- * 75 airline connectors run locally via Python + backend API for enterprise GDS/NDC sources.
4
+ * 195 airline connectors run locally via Python + backend API for enterprise GDS/NDC sources.
5
5
  * Zero external JS dependencies. Uses native fetch (Node 18+).
6
6
  *
7
+ * **GitHub Star Required!**
8
+ * Before using, you must:
9
+ * 1. Star https://github.com/LetsFG/LetsFG
10
+ * 2. Run: letsfg star --github <your-username>
11
+ *
7
12
  * @example
8
13
  * ```ts
9
14
  * import { LetsFG, searchLocal } from 'letsfg';
10
15
  *
11
- * // Local search — FREE, no API key
16
+ * // Local search — FREE with GitHub star
12
17
  * const local = await searchLocal('SHA', 'CTU', '2026-03-20');
13
18
  *
14
19
  * // Full API — search + unlock + book
@@ -183,12 +188,25 @@ declare class OfferExpiredError extends LetsFGError {
183
188
  declare class ValidationError extends LetsFGError {
184
189
  constructor(message: string, statusCode?: number, response?: Record<string, unknown>, errorCode?: string);
185
190
  }
191
+ /**
192
+ * Thrown when GitHub star verification is required.
193
+ * Users must star https://github.com/LetsFG/LetsFG and run:
194
+ * letsfg star --github <username>
195
+ */
196
+ declare class StarRequiredError extends LetsFGError {
197
+ constructor(message?: string);
198
+ }
186
199
  /** One-line offer summary */
187
200
  declare function offerSummary(offer: FlightOffer): string;
188
201
  /** Get cheapest offer from search results */
189
202
  declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
190
203
  /**
191
- * Search flights using 73 local airline connectors — FREE, no API key needed.
204
+ * Search flights using 195 local airline connectors — FREE with GitHub star!
205
+ *
206
+ * **GitHub Star Required!**
207
+ * Before using, you must:
208
+ * 1. Star https://github.com/LetsFG/LetsFG
209
+ * 2. Run: letsfg star --github <your-username>
192
210
  *
193
211
  * Requires: pip install letsfg && playwright install chromium
194
212
  *
@@ -196,6 +214,7 @@ declare function cheapestOffer(result: FlightSearchResult): FlightOffer | null;
196
214
  * @param destination - IATA code (e.g., "CTU")
197
215
  * @param dateFrom - Departure date "YYYY-MM-DD"
198
216
  * @param options - Optional: currency, adults, limit, etc.
217
+ * @throws {StarRequiredError} If GitHub star not verified
199
218
  */
200
219
  declare function searchLocal(origin: string, destination: string, dateFrom: string, options?: Partial<SearchOptions>): Promise<FlightSearchResult>;
201
220
  declare class LetsFG {
@@ -282,4 +301,4 @@ declare const BoostedTravel: typeof LetsFG;
282
301
  declare const BoostedTravelError: typeof LetsFGError;
283
302
  type BoostedTravelConfig = LetsFGConfig;
284
303
 
285
- export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type CheckoutProgress, ErrorCategory, type ErrorCategoryType, ErrorCode, type ErrorCodeType, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, LetsFG, type LetsFGConfig, LetsFGError, OfferExpiredError, type Passenger, PaymentRequiredError, type SearchOptions, type UnlockResult, ValidationError, cheapestOffer, LetsFG as default, systemInfo as getSystemInfo, searchLocal as localSearch, offerSummary, searchLocal, systemInfo };
304
+ export { AuthenticationError, type BookingResult, BoostedTravel, type BoostedTravelConfig, BoostedTravelError, type CheckoutProgress, ErrorCategory, type ErrorCategoryType, ErrorCode, type ErrorCodeType, type FlightOffer, type FlightRoute, type FlightSearchResult, type FlightSegment, LetsFG, type LetsFGConfig, LetsFGError, OfferExpiredError, type Passenger, PaymentRequiredError, type SearchOptions, StarRequiredError, type UnlockResult, ValidationError, cheapestOffer, LetsFG as default, systemInfo as getSystemInfo, searchLocal as localSearch, offerSummary, searchLocal, systemInfo };
package/dist/index.js CHANGED
@@ -39,6 +39,7 @@ __export(index_exports, {
39
39
  LetsFGError: () => LetsFGError,
40
40
  OfferExpiredError: () => OfferExpiredError,
41
41
  PaymentRequiredError: () => PaymentRequiredError,
42
+ StarRequiredError: () => StarRequiredError,
42
43
  ValidationError: () => ValidationError,
43
44
  cheapestOffer: () => cheapestOffer,
44
45
  default: () => index_default,
@@ -156,6 +157,12 @@ var ValidationError = class extends LetsFGError {
156
157
  this.name = "ValidationError";
157
158
  }
158
159
  };
160
+ var StarRequiredError = class extends LetsFGError {
161
+ constructor(message = "GitHub star required. Run: letsfg star --github <your-username>") {
162
+ super(message, 403, {}, "STAR_REQUIRED");
163
+ this.name = "StarRequiredError";
164
+ }
165
+ };
159
166
  function routeStr(route) {
160
167
  if (!route.segments.length) return "";
161
168
  const codes = [route.segments[0].origin, ...route.segments.map((s) => s.destination)];
@@ -206,8 +213,13 @@ async function searchLocal(origin, destination, dateFrom, options = {}) {
206
213
  child.on("close", (code) => {
207
214
  try {
208
215
  const data = JSON.parse(stdout);
209
- if (data.error) reject(new LetsFGError(data.error));
210
- else resolve(data);
216
+ if (data.error) {
217
+ if (data.error.includes("GitHub star required") || data.error.includes("star required")) {
218
+ reject(new StarRequiredError(data.error));
219
+ } else {
220
+ reject(new LetsFGError(data.error));
221
+ }
222
+ } else resolve(data);
211
223
  } catch {
212
224
  reject(new LetsFGError(
213
225
  `Python search failed (code ${code}): ${stdout || stderr}
@@ -511,6 +523,7 @@ var BoostedTravelError = LetsFGError;
511
523
  LetsFGError,
512
524
  OfferExpiredError,
513
525
  PaymentRequiredError,
526
+ StarRequiredError,
514
527
  ValidationError,
515
528
  cheapestOffer,
516
529
  getSystemInfo,
package/dist/index.mjs CHANGED
@@ -8,13 +8,14 @@ import {
8
8
  LetsFGError,
9
9
  OfferExpiredError,
10
10
  PaymentRequiredError,
11
+ StarRequiredError,
11
12
  ValidationError,
12
13
  cheapestOffer,
13
14
  index_default,
14
15
  offerSummary,
15
16
  searchLocal,
16
17
  systemInfo
17
- } from "./chunk-R2DLDQIL.mjs";
18
+ } from "./chunk-7LYR3CHE.mjs";
18
19
  export {
19
20
  AuthenticationError,
20
21
  BoostedTravel,
@@ -25,6 +26,7 @@ export {
25
26
  LetsFGError,
26
27
  OfferExpiredError,
27
28
  PaymentRequiredError,
29
+ StarRequiredError,
28
30
  ValidationError,
29
31
  cheapestOffer,
30
32
  index_default as default,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "letsfg",
3
- "version": "1.1.1",
4
- "description": "Agent-native flight search & booking. 102 airline connectors run locally + enterprise GDS/NDC APIs. Built for autonomous AI agents.",
3
+ "version": "1.4.0",
4
+ "description": "Agent-native flight search & booking. 195 airline connectors run locally + enterprise GDS/NDC APIs. Built for autonomous AI agents.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",