@bowmark/web 1.8.0 → 1.10.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.
@@ -5,8 +5,8 @@
5
5
  // rather than imported. An `import` or `export` at the top level of this file would
6
6
  // turn it into a module and every declaration below would stop being global.
7
7
  //
8
- // Manifest version: b71c060db620c119ab92eac724aab2d9670d3d22f342f754075e353929634db2
9
- // 9 capabilities, 121 providers, 380 typed functions, 20 refused.
8
+ // Manifest version: cad629ad449ffa7b6e12b0299082209643912c130193213d154764eeb434951f
9
+ // 10 capabilities, 155 providers, 457 typed functions, 20 refused.
10
10
  // 51,715 family members, sharing 2 interface(s) — declared once and pointed at, never repeated per member.
11
11
  //
12
12
  // REFUSED — these functions are real and callable, and their declared arguments
@@ -102,7 +102,10 @@ type CallOptions = {
102
102
  * IATA codes and a city name would come back as an empty list an agent would misread as "no
103
103
  * cars available". `warnings` is always present and names anything dropped or clamped —
104
104
  * INCLUDING a site that timed out or failed, which quoted nothing and is not the same as an
105
- * airport with no availability. `options.timeoutMs` sets the per-site budget (default 30000).
105
+ * airport with no availability. And when NO site answered at all this THROWS rather than
106
+ * returning `cars: []`, because those two are the same value and only one of them means there
107
+ * are no cars: a list you receive is always a list a site actually gave. `options.timeoutMs`
108
+ * sets the per-site budget (default 30000).
106
109
  */
107
110
  search(query: CarQuery, limit?: number, options?: CallOptions): Promise<CarSearchResult>;
108
111
  }
@@ -315,9 +318,11 @@ type FlightStatusResult = {
315
318
  * completely different fact from a site that was never reached, so coverage is NOT inferable
316
319
  * from the rows. Read `warnings` before treating them as the whole market: a dropped site
317
320
  * means the real cheapest fare may not be here at all. Three of the four sites run one shared
318
- * engine, so they tend to fail together. `options.timeoutMs` sets the per-site budget (default
319
- * 30000) a site slower than that is dropped and named, so the answer arrives inside the
320
- * calling client's own tool-call limit rather than not at all.
321
+ * engine, so they tend to fail together and when ALL FOUR are gone this THROWS instead of
322
+ * returning `flights: []`, since an empty list would otherwise be indistinguishable from a
323
+ * route nobody flies. `options.timeoutMs` sets the per-site budget (default 30000) a site
324
+ * slower than that is dropped and named, so the answer arrives inside the calling client's own
325
+ * tool-call limit rather than not at all.
321
326
  */
322
327
  search(query: FlightQuery, options?: CallOptions): Promise<FlightSearchResult>;
323
328
 
@@ -424,8 +429,10 @@ type CallOptions = {
424
429
  * multiplying `nightPrice` by the night count on a multi-room search is out by a factor of
425
430
  * `rooms`; compare on `price`. `warnings` is always present and names anything dropped or
426
431
  * clamped — INCLUDING a site that timed out or failed, which returned nothing and is not the
427
- * same as a sold-out destination. This route drives a real browser and is the slowest thing in
428
- * the library: 21-26s measured, against `options.timeoutMs`'s 30000 default. RAISE that budget
432
+ * same as a sold-out destination. And when NO site answered at all this THROWS rather than
433
+ * returning `hotels: []`, because those two are the same value and only one of them means
434
+ * there is nowhere to stay. This route drives a real browser and is the slowest thing in the
435
+ * library: 21-26s measured, against `options.timeoutMs`'s 30000 default. RAISE that budget
429
436
  * rather than lowering it if you batch several searches into one call.
430
437
  */
431
438
  search(query: HotelQuery, limit?: number, options?: CallOptions): Promise<HotelSearchResult>;
@@ -577,8 +584,9 @@ type CallOptions = {
577
584
  * would otherwise return a list an agent would misread. `reportCategories` says which
578
585
  * regulator reports exist for a carrier, NOT which lines it writes. `warnings` is always
579
586
  * present, and a source that timed out or failed is NAMED there — read it before treating an
580
- * empty list as "no carrier is licensed there". `options.timeoutMs` sets the per-source budget
581
- * (default 30000).
587
+ * empty list as "no carrier is licensed there". When NO source answered at all this THROWS
588
+ * instead of returning an empty list, so that misreading is not available. `options.timeoutMs`
589
+ * sets the per-source budget (default 30000).
582
590
  */
583
591
  searchCarriers(query: CarrierQuery, limit?: number, options?: CallOptions): Promise<CarrierSearchResult>;
584
592
 
@@ -595,7 +603,9 @@ type CallOptions = {
595
603
  * only when the query carries neither a zip nor a city+state — one carrier alone is a complete
596
604
  * query, not a partial one. `warnings` is always present: a carrier the query lacked input
597
605
  * for, or one that timed out or failed, is NAMED there — read it before treating a short list
598
- * as the whole answer. `options.timeoutMs` sets the per-carrier budget (default 30000).
606
+ * as the whole answer. When every carrier the query DID reach for failed, this THROWS rather
607
+ * than returning an empty list, which would otherwise read as "no agent near you".
608
+ * `options.timeoutMs` sets the per-carrier budget (default 30000).
599
609
  */
600
610
  findAgent(query: AgentLocatorQuery, limit?: number, options?: CallOptions): Promise<AgentSearchResult>;
601
611
 
@@ -637,8 +647,9 @@ type CallOptions = {
637
647
  * answered: this is a published directory with no legitimate empty case, so a missing section
638
648
  * or a changed page throws at the provider rather than under-reporting who underwrites the
639
649
  * policy. `warnings` is always present and names a source that timed out or failed — with one
640
- * source today, read it before trusting a short list is the whole directory.
641
- * `options.timeoutMs` sets the per-source budget (default 30000).
650
+ * source today, read it before trusting a short list is the whole directory. When no source
651
+ * answered at all this THROWS, so an outage is never handed back as a directory with nothing
652
+ * in it. `options.timeoutMs` sets the per-source budget (default 30000).
642
653
  */
643
654
  listReferralCarriers(query?: ReferralCarrierQuery, options?: CallOptions): Promise<ReferralCarrierListResult>;
644
655
  }
@@ -697,8 +708,10 @@ type MusicTrackResult = {
697
708
  * synthwave") and returns up to `limit` normalized tracks (default 20, max 200), most-played
698
709
  * first. Tracks with no reported play count sort last rather than as zero. `warnings` is
699
710
  * always present and names anything dropped — INCLUDING a catalogue that timed out or failed,
700
- * which returned nothing and is not the same as a query with no matches. `options.timeoutMs`
701
- * sets the per-catalogue budget (default 30000).
711
+ * which returned nothing and is not the same as a query with no matches. And when NO catalogue
712
+ * answered at all this THROWS rather than returning `tracks: []`, because those two are the
713
+ * same value and only one of them means nothing matched. `options.timeoutMs` sets the
714
+ * per-catalogue budget (default 30000).
702
715
  */
703
716
  search(query: string, limit?: number, options?: CallOptions): Promise<MusicSearchResult>;
704
717
 
@@ -783,8 +796,9 @@ type ProductResult = {
783
796
  * price-sorted (cheapest first), each tagged with its `store`. A store that is genuinely empty
784
797
  * contributes nothing and says nothing; a store that TIMED OUT or FAILED is named in
785
798
  * `warnings`, and the two are not the same fact — "the cheapest of three stores" is a wrong
786
- * claim when one of them never answered. `options.timeoutMs` sets the per-store budget
787
- * (default 30000).
799
+ * claim when one of them never answered. When ALL THREE never answered this THROWS rather than
800
+ * returning `offers: []`, because that empty list is the same value as a part nobody stocks.
801
+ * `options.timeoutMs` sets the per-store budget (default 30000).
788
802
  */
789
803
  search(query: string, options?: CallOptions): Promise<OfferSearchResult>;
790
804
 
@@ -861,6 +875,80 @@ type ReadResult = {
861
875
  }
862
876
  }
863
877
 
878
+ declare namespace BowmarkCapability_search {
879
+ // ── Web search — the unit's own declarations, verbatim ──
880
+ type SearchResult = {
881
+ source: string // which ENGINE produced this row ("bing")
882
+ rank: number // 1-based, in that engine's own ranking
883
+ title: string
884
+ url: string // the destination page, already unwrapped from any
885
+ // click-tracker — pass it straight to read.page
886
+ snippet: string | null // the engine's blurb; null when it published none
887
+ published: string | null // ISO. On `web` this is often the engine's CRAWL
888
+ // date, not the page's — do not report it as one
889
+ }
890
+ type SearchWebResult = {
891
+ query: string
892
+ engine: string // who actually answered. With a fallback chain this
893
+ // is the difference between the primary engine's
894
+ // ranking and the standby's
895
+ results: SearchResult[]
896
+ warnings: string[] // always present. Names every engine tried and
897
+ // FAILED before the one that answered
898
+ }
899
+
900
+ // news adds the two things a news index has and a web index does not
901
+ type NewsResult = SearchResult & {
902
+ publisher: string | null // the outlet
903
+ imageUrl: string | null // usually the engine's cached thumbnail
904
+ }
905
+ type SearchNewsResult = {
906
+ query: string
907
+ engine: string
908
+ results: NewsResult[]
909
+ warnings: string[]
910
+ }
911
+
912
+ type CallOptions = {
913
+ timeoutMs?: number // per-provider budget in ms, default 30000, clamped to 1000-55000.
914
+ // A provider slower than this is DROPPED from the results and
915
+ // NAMED in warnings — never silently absent
916
+ }
917
+
918
+ /**
919
+ * Find pages on the web when you do not already know the URL — the step before read.page.
920
+ * Returns ranked results with title, destination URL and snippet. `news` is the same read over
921
+ * news coverage, with real publication dates and the outlet's name. ONE ENGINE TODAY (Bing),
922
+ * so if it is down this fails rather than degrading — it throws, and never reports an outage
923
+ * as zero results. Two things that engine cannot do, measured on `web`: it never returns an
924
+ * empty list even when nothing matches, and it ignores search operators like site:.
925
+ */
926
+ interface Unit {
927
+ /**
928
+ * Searches the web and returns ranked results — title, destination URL, snippet — from the
929
+ * first engine in the chain that answers. `engine` names which one that was, and `warnings`
930
+ * names any that were tried and failed first. Feed a result's `url` straight to
931
+ * bowmark.read.page to actually read it. TWO THINGS TO KNOW BEFORE YOU TRUST THE ROWS: the
932
+ * engine NEVER returns an empty list, so results are its best offer rather than proof anything
933
+ * matched, and it IGNORES operators — a `site:example.com` query is not scoped to that site.
934
+ * When every engine fails this THROWS rather than returning zero rows, because no engine
935
+ * reached is not the same as nothing found.
936
+ */
937
+ web(query: string | { query: string, limit?: number }, limit?: number, options?: CallOptions): Promise<SearchWebResult>;
938
+
939
+ /**
940
+ * Searches news coverage and returns stories with the headline, the outlet's own article URL,
941
+ * a summary, the publisher's name and a real publication timestamp. Use this rather than `web`
942
+ * whenever the question is about what happened or when — `web`'s dates are commonly the
943
+ * engine's crawl stamp, and these are the story's own. NOT MEASURED on the two limits `web`
944
+ * declares: nobody has checked whether this feed returns an empty list for a query with no
945
+ * coverage, or whether it honours operators. Treat both as unknown rather than as working —
946
+ * `web`'s answers are the ones with fixtures behind them.
947
+ */
948
+ news(query: string | { query: string, limit?: number }, limit?: number, options?: CallOptions): Promise<SearchNewsResult>;
949
+ }
950
+ }
951
+
864
952
  declare namespace BowmarkCapability_sheds {
865
953
  // ── Sheds and portable buildings (configure and price) — the unit's own declarations, verbatim ──
866
954
  type ShedSize = {
@@ -958,7 +1046,9 @@ type CallOptions = {
958
1046
  * as well as costing it — a real product image, the roof line and roofing material, the
959
1047
  * maker's own wall-height spec — and carries `orderUrl`, their own page to go order that
960
1048
  * build. `warnings` is always present and names a maker that failed, styles that do not build
961
- * the size, and a capped fan. `options.timeoutMs` sets the per-maker budget (default 30000).
1049
+ * the size, and a capped fan. When NO maker answered at all this THROWS rather than returning
1050
+ * an empty list — "nobody builds a 12x20" and "nobody could be reached" are otherwise the same
1051
+ * result. `options.timeoutMs` sets the per-maker budget (default 30000).
962
1052
  */
963
1053
  quote(request: ShedQuoteRequest, options?: CallOptions): Promise<ShedQuoteResult>;
964
1054
 
@@ -967,7 +1057,9 @@ type CallOptions = {
967
1057
  * it can be built in, every real buildable size in FEET, and what the building IS (a real
968
1058
  * product image, the roof line and roofing material, the maker's own wall-height spec). Use it
969
1059
  * to see what exists before pricing, or to answer "what sizes do they even make". `warnings`
970
- * names any maker that returned nothing, which is not the same as a maker with no styles.
1060
+ * names any maker that returned nothing, which is not the same as a maker with no styles. When
1061
+ * NO maker answered at all this THROWS rather than returning an empty list, because an empty
1062
+ * catalogue and an unreachable one are otherwise the same value.
971
1063
  */
972
1064
  listStyles(options?: CallOptions): Promise<ShedStylesResult>;
973
1065
 
@@ -975,7 +1067,9 @@ type CallOptions = {
975
1067
  * Looks up the real places that sell a maker's buildings in one US state or Canadian province
976
1068
  * — full name ("Tennessee") or abbreviation ("TN") — with name, city, phone and the dealer's
977
1069
  * own page, for handing a priced configuration to somebody who can actually build it. `phone`
978
- * is null when the directory lists none, never an empty string.
1070
+ * is null when the directory lists none, never an empty string. `warnings` names any maker
1071
+ * whose directory could not be read, and when NO directory could be read at all this THROWS
1072
+ * rather than returning an empty list, which would read as "no dealers in that state".
979
1073
  */
980
1074
  findDealers(state: string, options?: CallOptions): Promise<ShedDealerResult>;
981
1075
  }
@@ -1646,6 +1740,123 @@ interface AshleyFurnitureStore {
1646
1740
  }
1647
1741
  }
1648
1742
 
1743
+ declare namespace BowmarkProvider_asppoolco {
1744
+ // ── ASP - America's Swimming Pool Company — the unit's own declarations, verbatim ──
1745
+ // ASP's OWN shapes — not a capability contract.
1746
+
1747
+ interface AspLocation {
1748
+ name: string; // e.g. "ASP - America's Swimming Pool Company of Baldwin County"
1749
+ state: string; // two-letter state code
1750
+ url: string; // the location's own site
1751
+ requestServiceUrl: string; // handoff URL — ASP's own per-location request form
1752
+ phone: string;
1753
+ coverageZips: string[]; // every zip this location's page declares covering
1754
+ }
1755
+
1756
+ interface AspZipMatch {
1757
+ zip: string;
1758
+ covered: boolean; // false = no published ASP location covers this zip yet
1759
+ location: AspLocation | null;
1760
+ }
1761
+
1762
+ /**
1763
+ * ASP - America's Swimming Pool Company's own 257-location franchise directory — match a zip
1764
+ * code to the exact local ASP franchise that services it (name, phone, coverage) and hand back
1765
+ * that location's own Request Service form URL, the same match/route step ASP's site itself
1766
+ * performs before a homeowner can request service.
1767
+ */
1768
+ interface Unit {
1769
+ /**
1770
+ * Matches a 5-digit US zip code against ASP's 257-location franchise network and returns the
1771
+ * ONE local franchise that services it — name, phone, coverage zips, and its own Request
1772
+ * Service form URL to hand the shopper to. `covered: false` means no published ASP location
1773
+ * covers that zip yet, a real answer, not a failure.
1774
+ */
1775
+ findLocationByZip(zip: string): Promise<AspZipMatch>;
1776
+
1777
+ /**
1778
+ * Lists every ASP franchise location on the public directory — name, state, phone, coverage
1779
+ * zips, site URL and Request Service URL. `state` (optional, two-letter code, e.g. "GA")
1780
+ * narrows to that state.
1781
+ */
1782
+ listLocations(state?: string): Promise<AspLocation[]>;
1783
+ }
1784
+ }
1785
+
1786
+ declare namespace BowmarkProvider_atlasoceanvoyages {
1787
+ // ── Atlas Ocean Voyages — the unit's own declarations, verbatim ──
1788
+ // Atlas Ocean Voyages' OWN shapes — not a capability contract.
1789
+
1790
+ interface AtlasVoyageSummary {
1791
+ code: string; // the site's own itinerary code, e.g. "WVO260815"
1792
+ slug: string; // the key getVoyage takes
1793
+ title: string;
1794
+ destinations: string[];
1795
+ ship: string;
1796
+ durationNights: number;
1797
+ departDate: string; // "2026-08-15"
1798
+ endDate: string;
1799
+ startingPrice: number | null; // null = call-for-fares, not a read failure
1800
+ startingPriceFormatted: string | null;
1801
+ detailUrl: string;
1802
+ }
1803
+
1804
+ interface AtlasVoyageSearchResult { voyages: AtlasVoyageSummary[]; totalMatched: number }
1805
+
1806
+ interface AtlasPortStop { name: string; code: string; arriving: string | null; departing: string | null; atSea: boolean }
1807
+
1808
+ interface AtlasCabinPrice { code: string; name: string; totalPrice: number; totalPriceFormatted: string }
1809
+
1810
+ interface AtlasVoyageDetail {
1811
+ code: string;
1812
+ slug: string;
1813
+ title: string;
1814
+ heroTitle: string | null;
1815
+ summary: string | null;
1816
+ ship: string;
1817
+ durationNights: number;
1818
+ departDate: string;
1819
+ endDate: string;
1820
+ ports: AtlasPortStop[];
1821
+ cabinPrices: AtlasCabinPrice[]; // only the categories THIS sailing has live pricing for
1822
+ startingPrice: number | null;
1823
+ startingPriceFormatted: string | null;
1824
+ bookingUrl: string; // bookings.atlasoceanvoyages.com — the real handoff
1825
+ detailUrl: string;
1826
+ }
1827
+
1828
+ /**
1829
+ * Luxury expedition cruise voyage search from Atlas Ocean Voyages — filter the site's own 180
1830
+ * live itineraries by destination, ship, duration and departure date with real starting
1831
+ * prices, then read one voyage's full port-by-port day itinerary, every cabin category the
1832
+ * site has actually priced for that sailing, and the itinerary-code-keyed handoff URL into the
1833
+ * real booking engine.
1834
+ */
1835
+ interface Unit {
1836
+ /**
1837
+ * Runs the /search voyage finder over all 180 currently-published itineraries, filtered by
1838
+ * destination (substring, e.g. "Antarctica"), ship (substring, e.g. "World Voyager"), duration
1839
+ * bounds, departure-date bounds and a free-text title match, sorted by departure date. Takes
1840
+ * no argument for the full unfiltered list (capped at `limit`, default 20, max 50).
1841
+ * `totalMatched` is the count BEFORE the cap, so a caller can tell "20 of 20" from "20 of 61".
1842
+ * `startingPrice` is null on a genuine call-for-fares sailing, never omitted — filter on it
1843
+ * explicitly rather than assuming presence.
1844
+ */
1845
+ searchVoyages(args?: { destination?: string; ship?: string; minDurationNights?: number; maxDurationNights?: number; departAfter?: string; departBefore?: string; query?: string; limit?: number }): Promise<AtlasVoyageSearchResult>;
1846
+
1847
+ /**
1848
+ * Reads one voyage's full detail page: the port-by-port day-by-day schedule (arrival/departure
1849
+ * times, or `atSea: true` for a scenic-cruising leg with no landing), every cabin category the
1850
+ * site has ACTUALLY priced for this specific sailing — never the ship's full rate card, since
1851
+ * a sailing sells out of most categories long before departure — and `bookingUrl`, the
1852
+ * itinerary-code-keyed handoff into bookings.atlasoceanvoyages.com where a caller actually
1853
+ * holds or pays for a cabin. `slug` comes from searchVoyages(). THROWS on an unknown slug,
1854
+ * naming searchVoyages() as the way to find current ones.
1855
+ */
1856
+ getVoyage(slug: string): Promise<AtlasVoyageDetail>;
1857
+ }
1858
+ }
1859
+
1649
1860
  declare namespace BowmarkProvider_atlasseniorliving {
1650
1861
  // ── Atlas Senior Living — the unit's own declarations, verbatim ──
1651
1862
  type AtlasCareType = "assisted_living" | "independent_living" | "memory_care" | "respite_care";
@@ -2081,6 +2292,66 @@ interface BigrentzCategoryRow {
2081
2292
  }
2082
2293
  }
2083
2294
 
2295
+ declare namespace BowmarkProvider_bing {
2296
+ // ── Bing — the unit's own declarations, verbatim ──
2297
+ interface BingWebResult {
2298
+ source: "bing";
2299
+ rank: number;
2300
+ title: string;
2301
+ url: string;
2302
+ snippet: string | null;
2303
+ published: string | null;
2304
+ }
2305
+
2306
+ interface BingNewsResult {
2307
+ source: "bing";
2308
+ rank: number;
2309
+ title: string;
2310
+ url: string;
2311
+ snippet: string | null;
2312
+ published: string | null;
2313
+ publisher: string | null;
2314
+ imageUrl: string | null;
2315
+ }
2316
+
2317
+ interface BingSearchResult {
2318
+ query: string;
2319
+ results: BingWebResult[];
2320
+ warnings: string[];
2321
+ }
2322
+
2323
+ interface BingNewsSearchResult {
2324
+ query: string;
2325
+ results: BingNewsResult[];
2326
+ warnings: string[];
2327
+ }
2328
+
2329
+ /**
2330
+ * General web and news search over Bing's index, read off Bing's own RSS output — ten ranked
2331
+ * results per query with title, destination URL, snippet and date. Keyless, browserless, ~5 KB
2332
+ * a call. It never reports 'no matches' and it ignores search operators like site: — both
2333
+ * measured, both declared.
2334
+ */
2335
+ interface Unit {
2336
+ /**
2337
+ * Searches the web and returns the ten results Bing ranked first, with title, destination URL,
2338
+ * snippet and date. TWO LIMITS, neither visible in the response: it NEVER returns an empty
2339
+ * list — a query of three invented words came back with ten confident, unrelated rows — and it
2340
+ * IGNORES search operators, so `site:reddit.com …` is not scoped to reddit. Treat the rows as
2341
+ * Bing's best offer rather than as proof anything matched.
2342
+ */
2343
+ searchWeb(args: { query: string, limit?: number }): Promise<BingSearchResult>;
2344
+
2345
+ /**
2346
+ * Searches news coverage and returns stories with the headline, the outlet's own article URL,
2347
+ * a summary, a real publication timestamp, the publisher name and a thumbnail. Use this rather
2348
+ * than searchWeb when the question is 'what happened' — the web feed's dates are Bing's crawl
2349
+ * stamps, this feed's are the story's.
2350
+ */
2351
+ searchNews(args: { query: string, limit?: number }): Promise<BingNewsSearchResult>;
2352
+ }
2353
+ }
2354
+
2084
2355
  declare namespace BowmarkProvider_blenderseyewear {
2085
2356
  // ── Blenders Eyewear — the unit's own declarations, verbatim ──
2086
2357
  // Blenders Eyewear's OWN shapes — not a capability contract.
@@ -2460,6 +2731,89 @@ interface Boydsleep6ZoneResult {
2460
2731
  }
2461
2732
  }
2462
2733
 
2734
+ declare namespace BowmarkProvider_brixton {
2735
+ // ── Brixton — the unit's own declarations, verbatim ──
2736
+ interface BrixtonVariant {
2737
+ /** Shopify's numeric variant id as a string. */
2738
+ id: string;
2739
+ /** The variant's own label, e.g. "M" or "Black / M" on multi-option products. */
2740
+ title: string;
2741
+ /** String verbatim from the storefront — "30.00" (dollars) on /products.json, "10900" (cents) on /products/<h>.js. */
2742
+ price: string;
2743
+ /** Same scale as price. Null when the variant is not on sale. */
2744
+ compareAtPrice: string | null;
2745
+ /** The store's own SKU. Null on a variant without one. */
2746
+ sku: string | null;
2747
+ /** Whether the variant is purchasable right now. */
2748
+ available: boolean;
2749
+ /** e.g. ["M"] or ["Black", "M"]. */
2750
+ options: string[];
2751
+ }
2752
+ interface BrixtonProduct {
2753
+ /** The handle is the only stable identifier across the catalogue. */
2754
+ handle: string;
2755
+ title: string;
2756
+ vendor: string;
2757
+ productType: string;
2758
+ url: string;
2759
+ descriptionHtml: string | null;
2760
+ optionNames: string[];
2761
+ variants: BrixtonVariant[];
2762
+ /** Same scale as variants — see BrixtonVariant.price. */
2763
+ priceRange: { min: string; max: string } | null;
2764
+ /** True if ANY variant is purchasable. */
2765
+ inStock: boolean;
2766
+ tags: string[];
2767
+ /** Brixton's own images, in the order the storefront publishes them. */
2768
+ images: string[];
2769
+ }
2770
+ interface BrixtonCatalogue {
2771
+ /** All matching products, in-stock first, then by handle. */
2772
+ products: BrixtonProduct[];
2773
+ /** What the filter DROPPED, in the same register the rest of the library uses. */
2774
+ warnings: string[];
2775
+ }
2776
+ interface BrixtonCheckoutLink {
2777
+ /** Shopify's own cart-permalink URL — a GET that adds the line item and redirects into the cart. */
2778
+ url: string;
2779
+ /** The exact variant the link resolved to, read live off the storefront. */
2780
+ variant: BrixtonVariant;
2781
+ /** The product the variant belongs to. */
2782
+ product: BrixtonProduct;
2783
+ }
2784
+
2785
+ /**
2786
+ * Brixton apparel and headwear catalogue — every product, its size/color variants, real prices
2787
+ * and stock — read off the live Shopify storefront, plus a live-validated checkout handoff
2788
+ * link.
2789
+ */
2790
+ interface Unit {
2791
+ /**
2792
+ * Reads the live Brixton catalogue as the storefront publishes it — every product, its handle,
2793
+ * title, vendor, description, tags, images and the per-variant price the storefront is quoting
2794
+ * right now. Returns [] on a transport failure. The catalog page is the line and the parse is
2795
+ * the unit of work.
2796
+ */
2797
+ listBrixtonProducts(opts?: { limit?: number }): Promise<BrixtonProduct[]>;
2798
+
2799
+ /**
2800
+ * Reads one product by its handle — every size/color variant, its exact price and whether that
2801
+ * specific variant is purchasable right now. Takes the handle listBrixtonProducts returns.
2802
+ * THROWS on an unknown handle (the store answers a real 404).
2803
+ */
2804
+ getBrixtonProduct(handle: string): Promise<BrixtonProduct>;
2805
+
2806
+ /**
2807
+ * Resolves a product handle + a variant match (either the exact variant title like "M", or a
2808
+ * substring of it) to a real Shopify cart-permalink URL, validated live against the
2809
+ * storefront. THROWS if the handle is unknown, if no variant matches, if the match is
2810
+ * ambiguous (matches more than one variant), or if the matched variant is not currently
2811
+ * available — the error names the candidate or in-stock options so the caller can retry.
2812
+ */
2813
+ getBrixtonCheckoutLink(handle: string, variantTitleOrOptions: string, opts?: { quantity?: number }): Promise<BrixtonCheckoutLink>;
2814
+ }
2815
+ }
2816
+
2463
2817
  declare namespace BowmarkProvider_bykoket {
2464
2818
  // ── KOKET — the unit's own declarations, verbatim ──
2465
2819
  interface KoketProductSummary {
@@ -2831,6 +3185,59 @@ interface carsVehicleValue {
2831
3185
  }
2832
3186
  }
2833
3187
 
3188
+ declare namespace BowmarkProvider_chantecaille {
3189
+ // ── Chantecaille — the unit's own declarations, verbatim ──
3190
+ // Chantecaille's OWN shapes — not a capability contract.
3191
+
3192
+ interface QuizQuestion {
3193
+ id: string;
3194
+ code: string; // e.g. "undertone", "tone", "look", "benefits", "coverage"
3195
+ name: string; // e.g. "Undertone"
3196
+ question: string; // the site's own prompt text
3197
+ answers: { id: string; code: string; name: string }[];
3198
+ }
3199
+
3200
+ interface FoundationSelections {
3201
+ undertone: string; // e.g. "Cool" — code or name, from getFoundationQuizTaxonomy()
3202
+ skinTone: string; // e.g. "Medium Deep"
3203
+ skinLook: string; // e.g. "Smooth and flawless"
3204
+ benefits: string[]; // e.g. ["Hydration"] — [] answers the site's own "Skip"
3205
+ coverage: string; // e.g. "Light" | "Medium" | "Full"
3206
+ }
3207
+
3208
+ interface FoundationMatch {
3209
+ name: string; // e.g. "Future Skin - Maple"
3210
+ score: number; // the site's own computed match score
3211
+ price: string;
3212
+ displayPrice: string; // e.g. "$95.00"
3213
+ productUrl: string; // real product page, this exact shade preselected
3214
+ productImageUrl: string;
3215
+ description: string;
3216
+ }
3217
+
3218
+ /**
3219
+ * Chantecaille's own Foundation Shade Match Quiz, reimplemented over its real Cartful
3220
+ * Solutions scoring engine: read the real live question taxonomy, and get real ranked
3221
+ * foundation matches — name, price, product page — computed by the site's own engine for a
3222
+ * stated undertone, skin tone, finish, skincare benefits and coverage.
3223
+ */
3224
+ interface Unit {
3225
+ /**
3226
+ * Reads Chantecaille's real, live Foundation Shade Match Quiz question and answer taxonomy off
3227
+ * its own Cartful Solutions bundle — the real option names to pass to matchFoundation.
3228
+ */
3229
+ getFoundationQuizTaxonomy(): Promise<QuizQuestion[]>;
3230
+
3231
+ /**
3232
+ * Chantecaille's own Foundation Shade Match Quiz, run for real: posts the caller's selections
3233
+ * to the site's own scoring engine and returns the real ranked foundation matches, highest
3234
+ * score first. THROWS naming the real options when a selection does not match the live
3235
+ * taxonomy.
3236
+ */
3237
+ matchFoundation(selections: FoundationSelections): Promise<FoundationMatch[]>;
3238
+ }
3239
+ }
3240
+
2834
3241
  declare namespace BowmarkProvider_cheapflights {
2835
3242
  // ── Cheapflights — the unit's own declarations, verbatim ──
2836
3243
  interface KayakQuery {
@@ -3509,6 +3916,120 @@ interface CyberpowerpcPriceResult {
3509
3916
  }
3510
3917
  }
3511
3918
 
3919
+ declare namespace BowmarkProvider_davidsonhomes {
3920
+ // ── Davidson Homes — the unit's own declarations, verbatim ──
3921
+ // Davidson Homes' OWN shapes — not a capability contract.
3922
+
3923
+ interface DavidsonhomesRange { lowest: number | null; highest: number | null }
3924
+
3925
+ interface DavidsonhomesRegionSummary {
3926
+ id: string;
3927
+ title: string;
3928
+ path: string; // the key getRegion takes
3929
+ state: string;
3930
+ homesCount: number;
3931
+ communitiesCount: number;
3932
+ priceRange: DavidsonhomesRange;
3933
+ }
3934
+
3935
+ interface DavidsonhomesCommunitySummary {
3936
+ id: string;
3937
+ title: string;
3938
+ path: string; // the key getCommunity takes
3939
+ city: string;
3940
+ state: string;
3941
+ status: string; // e.g. "Move-In Ready Homes", "Now Selling"
3942
+ bedRange: DavidsonhomesRange;
3943
+ priceRange: DavidsonhomesRange;
3944
+ sqftRange: DavidsonhomesRange;
3945
+ homesCount: number;
3946
+ plansCount: number;
3947
+ }
3948
+
3949
+ interface DavidsonhomesRegionDetail {
3950
+ title: string;
3951
+ path: string;
3952
+ state: string; // this region's URL grouping, per the site's own nav
3953
+ stateAbbreviation: string;
3954
+ communities: DavidsonhomesCommunitySummary[];
3955
+ }
3956
+
3957
+ interface DavidsonhomesHomeSummary {
3958
+ id: string;
3959
+ title: string; // real street address, e.g. "28 Aurora Circle"
3960
+ path: string; // the key getHome takes
3961
+ price: number;
3962
+ oldPrice: number | null;
3963
+ sqft: number;
3964
+ beds: number;
3965
+ baths: number;
3966
+ halfBaths: number;
3967
+ status: string; // e.g. "Active", "Pending"
3968
+ estCompletionMonth: string | null;
3969
+ floorPlanName: string | null;
3970
+ }
3971
+
3972
+ interface DavidsonhomesCommunityDetail {
3973
+ title: string;
3974
+ path: string;
3975
+ status: string;
3976
+ priceRange: DavidsonhomesRange;
3977
+ sqftRange: DavidsonhomesRange;
3978
+ phone: string | null;
3979
+ plansCount: number;
3980
+ availableHomes: DavidsonhomesHomeSummary[];
3981
+ }
3982
+
3983
+ interface DavidsonhomesHomeDetail extends DavidsonhomesHomeSummary {
3984
+ description: string | null;
3985
+ garage: number | null;
3986
+ coordinates: { lat: number; lng: number } | null;
3987
+ communityTitle: string;
3988
+ communityPath: string; // the key getCommunity takes
3989
+ }
3990
+
3991
+ /**
3992
+ * Reads Davidson Homes' own 'Find Your Home' search — all live market regions, one region's
3993
+ * communities with real price/bed/sqft ranges and availability status, one community's actual
3994
+ * move-in-ready homes with real street addresses and prices, and one home's full listing
3995
+ * detail — the way the live site's own search would show it.
3996
+ */
3997
+ interface Unit {
3998
+ /**
3999
+ * Lists every market region Davidson Homes currently builds in (state/metro area), each with
4000
+ * its own live homes count, communities count and starting price. The entry point: every
4001
+ * region's `path` is what `getRegion` takes.
4002
+ */
4003
+ listRegions(): Promise<DavidsonhomesRegionSummary[]>;
4004
+
4005
+ /**
4006
+ * Reads one region's own page: every community in it with a real live price/bed/sqft range and
4007
+ * status ("Move-In Ready Homes", "Now Selling", etc). `path` comes from `listRegions()`, e.g.
4008
+ * "states/alabama/huntsville-market-area". THROWS on an unknown path, naming `listRegions()`
4009
+ * as the way to find current ones.
4010
+ */
4011
+ getRegion(path: string): Promise<DavidsonhomesRegionDetail>;
4012
+
4013
+ /**
4014
+ * Reads one community's own page: its ACTUAL available homes right now, each with a real
4015
+ * street address, real price, real sqft/bed/bath count and per-home status ("Active",
4016
+ * "Pending") — never a floor-plan brochure. `path` comes from `getRegion()`, e.g.
4017
+ * "states/alabama/huntsville-market-area/fayetteville/bailey-park". THROWS on an unknown path,
4018
+ * naming `getRegion()` as the way to find current ones.
4019
+ */
4020
+ getCommunity(path: string): Promise<DavidsonhomesCommunityDetail>;
4021
+
4022
+ /**
4023
+ * Reads one specific home's own listing page: address, price, sqft, bed/bath count, status,
4024
+ * garage, coordinates and the site's own listing description. `path` comes from
4025
+ * `getCommunity()` or `getRegion()`'s community list, e.g.
4026
+ * "…/bailey-park/available-homes/28-aurora-circle". THROWS on an unknown path, naming
4027
+ * `getCommunity()` as the way to find current ones.
4028
+ */
4029
+ getHome(path: string): Promise<DavidsonhomesHomeDetail>;
4030
+ }
4031
+ }
4032
+
3512
4033
  declare namespace BowmarkProvider_decked {
3513
4034
  // ── DECKED — the unit's own declarations, verbatim ──
3514
4035
  // DECKED's OWN shapes — not a capability contract.
@@ -4288,6 +4809,42 @@ interface EventSourceInquiryContact {
4288
4809
  }
4289
4810
  }
4290
4811
 
4812
+ declare namespace BowmarkProvider_evolutionofsmooth {
4813
+ // ── eos Products — the unit's own declarations, verbatim ──
4814
+ interface ShadeQuizOption { optionId: string; text: string }
4815
+ interface ShadeQuizQuestion { questionPageId: string; questionId: string; title: string; options: ShadeQuizOption[] }
4816
+ interface ShadeResult {
4817
+ shadeName: string; price: number; priceFormatted: string;
4818
+ productUrl: string; productId: string; variantId: string; description: string;
4819
+ }
4820
+ type ShadeQuizAnswerResult =
4821
+ | { done: false; question: ShadeQuizQuestion }
4822
+ | { done: true; result: ShadeResult };
4823
+
4824
+ /**
4825
+ * eos's Dewy Lip Shine Shade Finder quiz (Octane AI) — walks the site's real 5-question quiz
4826
+ * and returns the personalized shade result: name, Shopify product/variant id, price and
4827
+ * product URL, ready for a cart handoff.
4828
+ */
4829
+ interface Unit {
4830
+ /**
4831
+ * Starts eos's Dewy Lip Shine Shade Finder quiz (walking past the site's own unanswerable
4832
+ * intro page automatically) and returns the first real question, with the `quizResponseId`
4833
+ * every following `answerShadeQuizQuestion` call takes.
4834
+ */
4835
+ startShadeQuiz(): Promise<{ quizResponseId: string; question: ShadeQuizQuestion }>;
4836
+
4837
+ /**
4838
+ * Submits one answer (the `questionPageId`/`questionId` from the question just answered, and
4839
+ * the `optionId` of the chosen option) and returns either the next question, or — once all 5
4840
+ * real questions are answered — `{ done: true, result }` with the personalized Dewy Lip Shine
4841
+ * shade: name, Shopify product/variant id, price and product URL. The site's own email-capture
4842
+ * page is skipped automatically.
4843
+ */
4844
+ answerShadeQuizQuestion(quizResponseId: string, questionPageId: string, questionId: string, optionId: string): Promise<ShadeQuizAnswerResult>;
4845
+ }
4846
+ }
4847
+
4291
4848
  declare namespace BowmarkProvider_extraspace {
4292
4849
  // ── Extra Space Storage — the unit's own declarations, verbatim ──
4293
4850
  interface ExtraspaceSearchResult {
@@ -4580,6 +5137,58 @@ interface FirstdibsListing {
4580
5137
  }
4581
5138
  }
4582
5139
 
5140
+ declare namespace BowmarkProvider_fivestarbathsolutions {
5141
+ // ── Five Star Bath Solutions — the unit's own declarations, verbatim ──
5142
+ interface FivestarLocation {
5143
+ id: string;
5144
+ title: string;
5145
+ ownerName: string;
5146
+ phone: string;
5147
+ address: string;
5148
+ state: string;
5149
+ latitude: number;
5150
+ longitude: number;
5151
+ url: string;
5152
+ }
5153
+
5154
+ interface FivestarDaySlots {
5155
+ date: string;
5156
+ dayOfWeek: string;
5157
+ times: string[];
5158
+ }
5159
+
5160
+ interface GetAvailableSlotsResult {
5161
+ region: string;
5162
+ usingRegionSlots: boolean;
5163
+ days: FivestarDaySlots[];
5164
+ }
5165
+
5166
+ /**
5167
+ * National bath/kitchen remodeling franchise (walk-in tubs, shower/tub conversions).
5168
+ * listLocations and getAvailableSlots are live — listLocations reads the site's own
5169
+ * 176-territory location directory, getAvailableSlots checks a region's real free
5170
+ * design-consultation scheduler and returns the actual open days/times. bookAppointment (the
5171
+ * final booking submit) is a stub — see its notImplemented reason.
5172
+ */
5173
+ interface Unit {
5174
+ /**
5175
+ * Returns every Five Star Bath Solutions franchise territory from the site's own
5176
+ * location-finder directory — geo slug (`id`, what `getAvailableSlots`' `region` argument
5177
+ * takes), title, owner, phone, mailing address, state and lat/long. No arguments.
5178
+ */
5179
+ listLocations(): Promise<FivestarLocation[]>;
5180
+
5181
+ /**
5182
+ * Checks one franchise region's real free design-consultation scheduler and returns the actual
5183
+ * open appointment days and times over the site's own 3-week booking window. Pass `region`
5184
+ * (the geo slug from `listLocations`' `id` field, e.g. "livonia-mi"). Returns whether the
5185
+ * region has its own configured slot table (`usingRegionSlots`) or fell back to the site's
5186
+ * Mon-Sat default, plus the day-by-day list of open times.
5187
+ */
5188
+ getAvailableSlots(args: object): Promise<GetAvailableSlotsResult>;
5189
+ }
5190
+ }
5191
+
4583
5192
  declare namespace BowmarkProvider_flightradar24 {
4584
5193
  // ── Flightradar24 — the unit's own declarations, verbatim ──
4585
5194
  interface flightradar24Airline {
@@ -4975,6 +5584,78 @@ interface fordVehicleRecalls {
4975
5584
  }
4976
5585
  }
4977
5586
 
5587
+ declare namespace BowmarkProvider_fourseasonsyachts {
5588
+ // ── Four Seasons Yachts — the unit's own declarations, verbatim ──
5589
+ interface FourseasonsyachtsVoyage {
5590
+ /** The site's own stable identifier for a sailing — what getVoyageSailing takes. */
5591
+ voyageCode: string;
5592
+ title: string;
5593
+ /** The path segment on fourseasonsyachts.com/voyages/<slug>. */
5594
+ slug: string;
5595
+ /** The site's own free-text category label, e.g. "Grand Mediterranean". */
5596
+ category: string;
5597
+ /** The resolved destination entry's title, when the link resolved; falls back to category. */
5598
+ destination: string;
5599
+ vessel: string;
5600
+ body: string;
5601
+ images: string[];
5602
+ url: string;
5603
+ }
5604
+ interface FourseasonsyachtsSuite {
5605
+ description: string;
5606
+ totalCabins: number;
5607
+ availableCabins: number;
5608
+ price: number;
5609
+ currency: string;
5610
+ }
5611
+ interface FourseasonsyachtsSailing {
5612
+ voyageCode: string;
5613
+ sailDays: number;
5614
+ fromPort: string;
5615
+ fromDateTime: string;
5616
+ toPort: string;
5617
+ toDateTime: string;
5618
+ ship: string;
5619
+ suites: FourseasonsyachtsSuite[];
5620
+ }
5621
+ interface FourseasonsyachtsSearchResult {
5622
+ voyages: FourseasonsyachtsVoyage[];
5623
+ /** What the filter DROPPED, in the same register the rest of the library uses. */
5624
+ warnings: string[];
5625
+ }
5626
+
5627
+ /**
5628
+ * Four Seasons Yachts' live Voyage Finder — every published sailing, its region and vessel,
5629
+ * plus the real scheduled departure with per-suite pricing and cabin availability, read off
5630
+ * the site's own booking-engine endpoints.
5631
+ */
5632
+ interface Unit {
5633
+ /**
5634
+ * Reads the live Voyage Finder inventory (50 published itineraries) and filters locally by
5635
+ * region, vessel and/or a free-text keyword against the title/body. Returns real voyageCodes
5636
+ * and slugs — the entry point every other function takes its identifier from. The site
5637
+ * publishes no query/filter endpoint of its own, so the divide is what this function does with
5638
+ * the listing, not how it gets there.
5639
+ */
5640
+ searchVoyages(filters?: { region?: string; vessel?: string; keyword?: string }): Promise<FourseasonsyachtsSearchResult>;
5641
+
5642
+ /**
5643
+ * Reads one voyage's itinerary — its day-by-day description, region, vessel and images — by
5644
+ * voyageCode (server-side filtered, cheap) or by slug (matched locally against the full
5645
+ * listing). THROWS when neither matches.
5646
+ */
5647
+ getVoyage(voyageCodeOrSlug: string): Promise<FourseasonsyachtsVoyage>;
5648
+
5649
+ /**
5650
+ * Reads the REAL scheduled departure for one voyageCode — exact embark/disembark ports and
5651
+ * dates, the ship, and every suite category's live price and cabin availability, straight off
5652
+ * the site's own booking engine. Returns null when the site currently has no scheduled
5653
+ * departure for that voyageCode (an honest empty answer, not a failure).
5654
+ */
5655
+ getVoyageSailing(voyageCode: string): Promise<FourseasonsyachtsSailing | null>;
5656
+ }
5657
+ }
5658
+
4978
5659
  declare namespace BowmarkProvider_framebridge {
4979
5660
  // ── Framebridge — the unit's own declarations, verbatim ──
4980
5661
  // Framebridge's OWN shapes — not a capability contract.
@@ -5902,6 +6583,43 @@ interface HandyproCategorySearch {
5902
6583
  }
5903
6584
  }
5904
6585
 
6586
+ declare namespace BowmarkProvider_hansons {
6587
+ // ── Hansons — the unit's own declarations, verbatim ──
6588
+ interface HansonsSlot {
6589
+ timeSlotID: number;
6590
+ appointmentDate: string;
6591
+ timeSlot: string;
6592
+ virtual: boolean;
6593
+ }
6594
+
6595
+ interface CheckAvailabilityResult {
6596
+ inServiceArea: boolean;
6597
+ showInHomeFlow: boolean;
6598
+ showVirtualFlow: boolean;
6599
+ message: string;
6600
+ slots: HansonsSlot[];
6601
+ }
6602
+
6603
+ /**
6604
+ * Regional home-exterior remodeler (windows/roofing/siding/gutters/bath). checkAvailability is
6605
+ * live — checks a ZIP against Hansons' real Free Estimate scheduler and returns the actual
6606
+ * bookable at-home/virtual slots. bookEstimate (the final booking submit) is a stub — see its
6607
+ * notImplemented reason.
6608
+ */
6609
+ interface Unit {
6610
+ /**
6611
+ * Checks a 5-digit US ZIP (`zipcode`, e.g. "48104") against Hansons' real Free Estimate
6612
+ * scheduler and returns the actual open appointment slots for an at-home or virtual
6613
+ * consultation — the same ZIP-gated availability check the site's own scheduler performs
6614
+ * before it will show a single bookable date. Pass `virtual: true`/`false` to filter to one
6615
+ * consultation type; omit it to get both. Returns whether the ZIP is even in Hansons' service
6616
+ * area, whether each consultation type is currently offered, the site's own status message,
6617
+ * and the slot list (date, display time, and the site's own slot id).
6618
+ */
6619
+ checkAvailability(args: object): Promise<CheckAvailabilityResult>;
6620
+ }
6621
+ }
6622
+
5905
6623
  declare namespace BowmarkProvider_harmar {
5906
6624
  // ── Harmar Mobility — the unit's own declarations, verbatim ──
5907
6625
  interface HarmarVehicleModel {
@@ -6046,6 +6764,67 @@ interface HauslabsShadeMatch {
6046
6764
  }
6047
6765
  }
6048
6766
 
6767
+ declare namespace BowmarkProvider_haydenhomes {
6768
+ // ── Hayden Homes — the unit's own declarations, verbatim ──
6769
+ // Hayden Homes' OWN shapes — not a capability contract.
6770
+
6771
+ interface HaydenhomesQuickMoveIn {
6772
+ id: number;
6773
+ planName: string;
6774
+ address: string;
6775
+ city: string;
6776
+ state: string;
6777
+ communityName: string;
6778
+ communityUrl: string;
6779
+ price: number;
6780
+ priceFormatted: string;
6781
+ monthlyPayment: string | null;
6782
+ beds: number | null;
6783
+ baths: number | null;
6784
+ sqft: number | null;
6785
+ stories: number | null;
6786
+ garage: string | null;
6787
+ lot: string | null;
6788
+ status: string; // "available" | "reserved", the site's own value
6789
+ availabilityLabel: string; // e.g. "Move-in Now", "Move-in Fall"
6790
+ availabilityDate: string | null;
6791
+ incentive: string | null;
6792
+ imageUrl: string | null;
6793
+ url: string; // the listing page — the real next step (tour / contact) lives here
6794
+ canScheduleAppointment: boolean;
6795
+ latitude: number | null;
6796
+ longitude: number | null;
6797
+ }
6798
+
6799
+ interface HaydenhomesSearchFilters {
6800
+ state?: string; // two-letter code, e.g. "OR"
6801
+ city?: string; // fuzzy substring match
6802
+ community?: string; // fuzzy substring match
6803
+ minBeds?: number;
6804
+ minBaths?: number;
6805
+ minSqft?: number;
6806
+ minPrice?: number;
6807
+ maxPrice?: number;
6808
+ availableOnly?: boolean; // default true
6809
+ }
6810
+
6811
+ /**
6812
+ * Hayden Homes' live quick move-in inventory search across Oregon, Washington, Idaho and
6813
+ * Montana — filterable by state, city, community, beds/baths/sqft and price, off the search
6814
+ * page's own server-rendered listing rather than a third-party aggregator's stale mirror.
6815
+ */
6816
+ interface Unit {
6817
+ /**
6818
+ * Runs Hayden Homes' quick move-in search against the site's own live inventory — every home
6819
+ * currently listed across OR/WA/ID/MT, with real address, price, beds/baths/sqft, community
6820
+ * and a listing URL to schedule a tour or contact a sales team. `filters` (all optional):
6821
+ * `state` (e.g. "OR"), `city`, `community`, `minBeds`, `minBaths`, `minSqft`, `minPrice`,
6822
+ * `maxPrice`, `availableOnly` (default true — excludes homes the site has marked reserved).
6823
+ */
6824
+ searchQuickMoveIns(filters?: HaydenhomesSearchFilters): Promise<HaydenhomesQuickMoveIn[]>;
6825
+ }
6826
+ }
6827
+
6049
6828
  declare namespace BowmarkProvider_healthcare_gov {
6050
6829
  // ── HealthCare.gov — the unit's own declarations, verbatim ──
6051
6830
  interface healthcare_govPlan {
@@ -7007,6 +7786,71 @@ interface HobieLocalAvailability {
7007
7786
  }
7008
7787
  }
7009
7788
 
7789
+ declare namespace BowmarkProvider_holidaybuilders {
7790
+ // ── Holiday Builders — the unit's own declarations, verbatim ──
7791
+ // Holiday Builders' OWN shapes — not a capability contract.
7792
+
7793
+ interface HolidaybuildersHome {
7794
+ planName: string;
7795
+ location: string; // the community/city, e.g. "Palm Bay"
7796
+ collection: string; // e.g. "inspire", "value", "cornerstone"
7797
+ address: string;
7798
+ price: number;
7799
+ priceFormatted: string;
7800
+ sqft: number;
7801
+ beds: number;
7802
+ baths: number;
7803
+ plan: string;
7804
+ status: string; // "Move-in Ready" | "Coming Soon", the site's own label
7805
+ imageUrl: string | null;
7806
+ url: string; // the listing page — Request a Tour / Contact Us Today live here
7807
+ }
7808
+
7809
+ interface HolidaybuildersHomeDetail extends Omit<HolidaybuildersHome, "url"> {
7810
+ url: string;
7811
+ description: string;
7812
+ garage: number | null;
7813
+ coordinates: { lat: number; lng: number } | null;
7814
+ contactUsUrl: string | null;
7815
+ requestTourUrl: string | null; // the WRITE handoff this provider never performs
7816
+ }
7817
+
7818
+ interface HolidaybuildersSearchFilters {
7819
+ location?: string; // fuzzy substring match
7820
+ collection?: string; // exact, case-insensitive
7821
+ minBeds?: number;
7822
+ minBaths?: number;
7823
+ minSqft?: number;
7824
+ minPrice?: number;
7825
+ maxPrice?: number;
7826
+ moveInReadyOnly?: boolean; // default true
7827
+ }
7828
+
7829
+ /**
7830
+ * Holiday Builders' live Available Homes inventory across every Florida community — filterable
7831
+ * by location, collection, beds/baths/sqft and price, off the search page's own
7832
+ * server-rendered listing rather than a third-party aggregator's stale mirror — plus one
7833
+ * listing's own full detail and Request-a-Tour handoff.
7834
+ */
7835
+ interface Unit {
7836
+ /**
7837
+ * Runs Holiday Builders' site-wide Available Homes search — every home currently listed across
7838
+ * all Florida communities, with real address, price, beds/baths/sqft, collection and status,
7839
+ * and a listing URL to view details or request a tour. `filters` (all optional): `location`,
7840
+ * `collection`, `minBeds`, `minBaths`, `minSqft`, `minPrice`, `maxPrice`, `moveInReadyOnly`
7841
+ * (default true — excludes homes marked "Coming Soon").
7842
+ */
7843
+ searchAvailableHomes(filters?: HolidaybuildersSearchFilters): Promise<HolidaybuildersHome[]>;
7844
+
7845
+ /**
7846
+ * Reads one home's own listing page — full specs, description, and whether the site's Contact
7847
+ * Us Today / Request a Tour forms are present. `url` is a listing URL from a
7848
+ * `searchAvailableHomes` result.
7849
+ */
7850
+ getHomeDetail(url: string): Promise<HolidaybuildersHomeDetail>;
7851
+ }
7852
+ }
7853
+
7010
7854
  declare namespace BowmarkProvider_hunter {
7011
7855
  // ── Hunter — the unit's own declarations, verbatim ──
7012
7856
  interface hunterDomainCandidate {
@@ -8415,6 +9259,75 @@ interface JoybirdPriceResult {
8415
9259
  }
8416
9260
  }
8417
9261
 
9262
+ declare namespace BowmarkProvider_joycefactorydirect {
9263
+ // ── Joyce Windows, Sunrooms & Baths — the unit's own declarations, verbatim ──
9264
+ interface JoyceCalculatorOption {
9265
+ label: string;
9266
+ answerId: string;
9267
+ }
9268
+ interface JoyceCalculatorQuestion {
9269
+ page: number;
9270
+ componentId: string;
9271
+ prompt: string;
9272
+ kind: "select" | "quantity";
9273
+ options: JoyceCalculatorOption[] | null;
9274
+ }
9275
+ interface JoyceWindowCalculatorOptions {
9276
+ calculatorUrl: string;
9277
+ questions: JoyceCalculatorQuestion[];
9278
+ }
9279
+
9280
+ /**
9281
+ * Reads the live question/option set behind Joyce Windows' own window-cost calculator (an
9282
+ * involve.me embed) with no browser and no interaction.
9283
+ */
9284
+ interface Unit {
9285
+ /**
9286
+ * Reads the live window-cost calculator's real questions and answer options (styles,
9287
+ * quantities, grade, colors, glass, grids) straight off the page — no interaction needed.
9288
+ */
9289
+ getWindowCalculatorOptions(): Promise<JoyceWindowCalculatorOptions>;
9290
+
9291
+ /**
9292
+ * Reads the live bath-remodel cost calculator's real questions and answer options straight off
9293
+ * the page — no interaction needed. Same involve.me platform and return shape as
9294
+ * getWindowCalculatorOptions.
9295
+ */
9296
+ getBathCalculatorOptions(): Promise<JoyceWindowCalculatorOptions>;
9297
+ }
9298
+ }
9299
+
9300
+ declare namespace BowmarkProvider_justinwine {
9301
+ // ── JUSTIN Vineyards & Winery — the unit's own declarations, verbatim ──
9302
+ interface JustinwineClubPriceRange {
9303
+ quantityLabel: string;
9304
+ bottles: number;
9305
+ min: number;
9306
+ max: number;
9307
+ checkoutUrl: string;
9308
+ }
9309
+
9310
+ interface JustinwineClubTier {
9311
+ category: string;
9312
+ categorySlug: string;
9313
+ description: string;
9314
+ priceRanges: JustinwineClubPriceRange[];
9315
+ }
9316
+
9317
+ /**
9318
+ * JUSTIN Vineyards & Winery's Wine Society club — per-shipment price by tier and quantity,
9319
+ * with the exact join handoff URL, off the club page's own embedded data.
9320
+ */
9321
+ interface Unit {
9322
+ /**
9323
+ * Lists the JUSTIN Wine Society club tiers, each with its per-shipment price range at 4/6/12
9324
+ * bottles and the exact join/checkout URL for that tier+quantity. Pass a category (e.g.
9325
+ * "Isosceles Only") to filter to one tier.
9326
+ */
9327
+ listClubTiers(category?: string): Promise<JustinwineClubTier[]>;
9328
+ }
9329
+ }
9330
+
8418
9331
  declare namespace BowmarkProvider_kayak {
8419
9332
  // ── Kayak — the unit's own declarations, verbatim ──
8420
9333
  interface KayakQuery {
@@ -8558,6 +9471,39 @@ interface KayakCar {
8558
9471
  }
8559
9472
  }
8560
9473
 
9474
+ declare namespace BowmarkProvider_kingsdown {
9475
+ // ── Kingsdown — the unit's own declarations, verbatim ──
9476
+ interface kingsdownBedmatchResult {
9477
+ zoneName: "Gold" | "Green" | "Blue" | "Red";
9478
+ zoneColor: string;
9479
+ scalar: number;
9480
+ findDealerUrl: string;
9481
+ buyUrl: string;
9482
+ }
9483
+
9484
+ /**
9485
+ * Kingsdown's own bedMATCH mattress-fit diagnostic (kingsdown.com/bedmatch/) —
9486
+ * getBedMatchResult runs the real questionnaire and returns the live computed support-color
9487
+ * classification (Gold/Green/Blue/Red) plus find-a-dealer and buy-direct handoff URLs.
9488
+ */
9489
+ interface Unit {
9490
+ /**
9491
+ * Runs Kingsdown's live bedMATCH diagnostic for one sleeper profile and returns the real
9492
+ * computed support-color classification (`zoneName`: "Gold" | "Green" | "Blue" | "Red", with
9493
+ * the raw fit `scalar` behind it), plus Kingsdown's own `findDealerUrl` and `buyUrl` handoffs.
9494
+ * Pass `{ name, ageBand, gender, position, heightBand, weightBand, pantBand, shirtBand,
9495
+ * painAreas? }` — every numeric field is the SITE'S OWN bucket code (its radio-button values),
9496
+ * not a raw age/height/weight, because bedMATCH itself only ever rates a band. `ageBand` ∈
9497
+ * {20, 33, 48, 63, 85}; `gender` ∈ {"F","M","N"}; `position` ∈ {1 Back, 2 Side, 3 Stomach};
9498
+ * `heightBand` ∈ {50, 57.5, 63.5, 69, 75.5, 78}; `weightBand`/`pantBand`/`shirtBand` are small
9499
+ * integer bucket codes (1-8 / 1-6 / 1-6). Read-only and account-free — the site's own quiz
9500
+ * asks for nothing but this questionnaire, and this function submits nothing beyond it (no
9501
+ * email, no purchase).
9502
+ */
9503
+ getBedMatchResult(profile: object): Promise<kingsdownBedmatchResult>;
9504
+ }
9505
+ }
9506
+
8561
9507
  declare namespace BowmarkProvider_kitchentuneup {
8562
9508
  // ── Kitchen Tune-Up — the unit's own declarations, verbatim ──
8563
9509
  interface KitchentuneupCabinetStyle {
@@ -8658,6 +9604,98 @@ interface KompanSparePartsDocuments {
8658
9604
  }
8659
9605
  }
8660
9606
 
9607
+ declare namespace BowmarkProvider_kuiu {
9608
+ // ── KUIU — the unit's own declarations, verbatim ──
9609
+ interface KuiuVariant {
9610
+ /** Shopify's numeric variant id as a string. */
9611
+ id: string;
9612
+ /** The variant's own label, e.g. "Vias / M". */
9613
+ title: string;
9614
+ /** String verbatim from the storefront — "129.00" (dollars) on /products.json, "12900" (cents) on /products/<handle>.js. */
9615
+ price: string;
9616
+ /** Same scale as price. Null when the variant is not on sale. */
9617
+ compareAtPrice: string | null;
9618
+ sku: string | null;
9619
+ /** Whether the variant is purchasable right now. */
9620
+ available: boolean;
9621
+ /** e.g. ["Vias", "M"] — camo pattern/color + size. */
9622
+ options: string[];
9623
+ }
9624
+ interface KuiuProduct {
9625
+ /** The handle is the only stable identifier across the catalogue. */
9626
+ handle: string;
9627
+ title: string;
9628
+ vendor: string;
9629
+ productType: string;
9630
+ url: string;
9631
+ descriptionHtml: string | null;
9632
+ optionNames: string[];
9633
+ variants: KuiuVariant[];
9634
+ priceRange: { min: string; max: string } | null;
9635
+ /** True if ANY variant is purchasable. */
9636
+ inStock: boolean;
9637
+ tags: string[];
9638
+ images: string[];
9639
+ }
9640
+ interface KuiuSizeMatch {
9641
+ /** The chart size that matched both chest and waist, e.g. "M". Null on no match. */
9642
+ size: string | null;
9643
+ chestRange: string | null;
9644
+ waistRange: string | null;
9645
+ armLengthRange: string | null;
9646
+ /** The size the CHEST measurement alone points to. */
9647
+ chestMatch: string | null;
9648
+ /** The size the WAIST measurement alone points to. */
9649
+ waistMatch: string | null;
9650
+ /** Populated when chest and waist disagree, or neither matched. */
9651
+ warnings: string[];
9652
+ }
9653
+ interface KuiuCheckoutLink {
9654
+ /** Shopify's own cart-permalink URL — a GET that adds the line item and redirects into the cart. */
9655
+ url: string;
9656
+ variant: KuiuVariant;
9657
+ product: KuiuProduct;
9658
+ }
9659
+
9660
+ /**
9661
+ * KUIU's live hunting-apparel catalogue — every product, its camo-pattern/color and size
9662
+ * variants, real prices and stock — plus the storefront's own Find Your Fit men's size chart
9663
+ * and a live-validated checkout handoff link.
9664
+ */
9665
+ interface Unit {
9666
+ /**
9667
+ * Reads the live KUIU catalogue as the storefront publishes it — every product, its handle,
9668
+ * title, vendor, description, tags, images and the per-variant price/stock the storefront is
9669
+ * quoting right now.
9670
+ */
9671
+ listKuiuProducts(opts?: { limit?: number }): Promise<KuiuProduct[]>;
9672
+
9673
+ /**
9674
+ * Reads one product by its handle — every camo-pattern/color and size variant, its exact price
9675
+ * and whether that specific variant is purchasable right now. Takes the handle
9676
+ * listKuiuProducts returns. THROWS on an unknown handle (the store answers a real 404).
9677
+ */
9678
+ getKuiuProduct(handle: string): Promise<KuiuProduct>;
9679
+
9680
+ /**
9681
+ * Maps chest and waist measurements (inches) to KUIU's own published men's apparel size,
9682
+ * reading the storefront's live Find Your Fit chart. Returns the matched size plus each
9683
+ * measurement's OWN match, so a caller can see when chest and waist point at different rows —
9684
+ * a real case on a chart sized primarily by chest.
9685
+ */
9686
+ findKuiuSize(measurements: { chest: number; waist: number }): Promise<KuiuSizeMatch>;
9687
+
9688
+ /**
9689
+ * Resolves a product handle + a variant match (either the exact variant title like "Vias / M",
9690
+ * or a substring of it) to a real Shopify cart-permalink URL, validated live against the
9691
+ * storefront. THROWS if the handle is unknown, if no variant matches, if the match is
9692
+ * ambiguous, or if the matched variant is out of stock — the error names the candidates or
9693
+ * in-stock options so the caller can retry.
9694
+ */
9695
+ getKuiuCheckoutLink(handle: string, variantTitleOrOptions: string, opts?: { quantity?: number }): Promise<KuiuCheckoutLink>;
9696
+ }
9697
+ }
9698
+
8661
9699
  declare namespace BowmarkProvider_labcorp {
8662
9700
  // ── Labcorp — the unit's own declarations, verbatim ──
8663
9701
  interface LabcorpTestSummary {
@@ -9141,6 +10179,76 @@ interface FindLocalDealerResult {
9141
10179
  }
9142
10180
  }
9143
10181
 
10182
+ declare namespace BowmarkProvider_lovelybride {
10183
+ // ── Lovely Bride — the unit's own declarations, verbatim ──
10184
+ interface LovelybrideStore {
10185
+ slug: string; // e.g. "houston" — what the other two functions take
10186
+ name: string; // e.g. "Houston"
10187
+ url: string;
10188
+ }
10189
+ interface LovelybrideAppointmentType {
10190
+ id: number; // e.g. 66220 — what getAvailableSlots takes
10191
+ description: string; // e.g. "1. Lovely Bridal Gown Appointment - $50 Fee"
10192
+ durationMinutes: number; // e.g. 90
10193
+ priceUsd: number | null;
10194
+ priceFormatted: string | null; // e.g. "$50.00"
10195
+ requiresPaymentInfo: boolean;
10196
+ }
10197
+ interface LovelybrideStoreInfo {
10198
+ name: string;
10199
+ emailAddress: string | null;
10200
+ phoneNumber: string | null;
10201
+ address: string | null;
10202
+ schedulerUrl: string; // the BridalLive scheduler page — the write handoff
10203
+ }
10204
+ interface LovelybrideTimeSlot {
10205
+ startDateTime: string; // ISO 8601
10206
+ endDateTime: string; // ISO 8601
10207
+ startDateTimeForView: string; // e.g. "10:00AM", store-local time
10208
+ location: string | null; // e.g. "Room 2"
10209
+ }
10210
+ interface LovelybrideAvailability {
10211
+ storeSlug: string;
10212
+ date: string; // echoes the requested "YYYY-MM-DD"
10213
+ slots: LovelybrideTimeSlot[]; // [] is a genuine "fully booked" answer
10214
+ }
10215
+
10216
+ /**
10217
+ * Reads Lovely Bride's real per-store BridalLive appointment scheduler — every store, a
10218
+ * store's real bookable appointment types and prices, and real open time slots — straight off
10219
+ * lovelybride.com and app.bridallive.com's own private JSON API, no key, no browser.
10220
+ */
10221
+ interface Unit {
10222
+ /**
10223
+ * Lists every Lovely Bride store the site's own store locator links — 19 across the US and one
10224
+ * in London, each with the slug the other two functions take. Takes nothing. The entry point:
10225
+ * a caller asking 'where can I book' has nowhere else to start.
10226
+ */
10227
+ listStores(): Promise<LovelybrideStore[]>;
10228
+
10229
+ /**
10230
+ * Reads one store's real, currently-bookable BridalLive appointment types — each with its real
10231
+ * price and duration exactly as the store's own scheduler quotes it — plus the store's contact
10232
+ * info and the live scheduler URL to hand off to. Takes the slug listStores returns. THROWS
10233
+ * LovelybrideNoOnlineBooking (not caller-fixable — no slug fixes it) when the store's own page
10234
+ * carries no online-booking link at all, which is a real answer for some stores (Charlotte,
10235
+ * measured 2026-08-16), not a parse failure.
10236
+ */
10237
+ getStoreAppointmentTypes(storeSlug: string): Promise<{ store: LovelybrideStoreInfo; appointmentTypes: LovelybrideAppointmentType[] }>;
10238
+
10239
+ /**
10240
+ * Reads the real open appointment slots for one store, one appointment type, and one date
10241
+ * ("YYYY-MM-DD") — the exact slots a shopper would see on the store's own scheduler page.
10242
+ * Takes the appointmentTypeId getStoreAppointmentTypes returns. Returns the requested date
10243
+ * alongside the slots; an empty `slots` array is a genuine answer (the date is fully booked),
10244
+ * never an error. This is a READ only: it does not hold or submit anything — a shopper follows
10245
+ * the store's schedulerUrl (from getStoreAppointmentTypes) to actually book the slot this
10246
+ * function found.
10247
+ */
10248
+ getAvailableSlots(storeSlug: string, appointmentTypeId: number, date: string): Promise<LovelybrideAvailability>;
10249
+ }
10250
+ }
10251
+
9144
10252
  declare namespace BowmarkProvider_lufthansa {
9145
10253
  // ── Lufthansa — the unit's own declarations, verbatim ──
9146
10254
  interface LufthansaFlightLeg {
@@ -9461,8 +10569,16 @@ interface LululemonRow {
9461
10569
  interface LululemonSearch {
9462
10570
  query: string;
9463
10571
  products: LululemonRow[];
9464
- /** How many entries matched before the row cap. */
10572
+ /** How many entries matched IN TOTAL, before the row cap — the size of the
10573
+ * thing you are paging through, not of this page. */
9465
10574
  matched: number;
10575
+ /** Where in the ranked match list this page started. */
10576
+ offset: number;
10577
+ /** The offset that reads the NEXT page, or null at the end of the list. Pass
10578
+ * it back verbatim — it is NOT offset + products.length, because a row that
10579
+ * was reached for and lost is dropped from products and named in warnings, so
10580
+ * a page of 24 can hand back 22 rows. */
10581
+ nextOffset: number | null;
9466
10582
  warnings: string[];
9467
10583
  }
9468
10584
  interface LululemonSimilarProducts {
@@ -9483,10 +10599,16 @@ interface LululemonSimilarProducts {
9483
10599
  * first — id, title, URL, price range, how many colours the style comes in, and whether it is
9484
10600
  * in stock. Ranks over the site's own published product index, then reads the price and colour
9485
10601
  * count per row. A match the pricing catalogue does not carry still comes back, with `priced:
9486
- * false` and null prices; `matched` says how many matched before the row cap so a caller can
9487
- * raise `limit` (default 8, max 24).
10602
+ * false` and null prices. PAGED: `matched` is the total match count and `nextOffset` is the
10603
+ * offset that reads the next page, or null at the end — pass it back verbatim rather than
10604
+ * adding `products.length`, since a lost row is dropped from `products` and named in
10605
+ * `warnings`. `limit` is rows per page (default 8, max 24, and each row costs one third-party
10606
+ * read), `offset` where the page starts (default 0). An offset past the end is an empty page,
10607
+ * not an error. A category is just a query — the site's own URL segments (`womens-leggings`,
10608
+ * `men-joggers`) are ranked over, so `{ query: "womens leggings", offset }` walks that
10609
+ * category.
9488
10610
  */
9489
- search(query: { query: string; limit?: number }): Promise<LululemonSearch>;
10611
+ search(query: { query: string; limit?: number; offset?: number }): Promise<LululemonSearch>;
9490
10612
 
9491
10613
  /**
9492
10614
  * Reads one product's full configurator the way its product page presents it — every colourway
@@ -9809,6 +10931,60 @@ interface mcdonaldsFindStoresResult {
9809
10931
  }
9810
10932
  }
9811
10933
 
10934
+ declare namespace BowmarkProvider_medicalguardian {
10935
+ // ── Medical Guardian — the unit's own declarations, verbatim ──
10936
+ // Medical Guardian's OWN shapes — not a capability contract.
10937
+
10938
+ type MedicalguardianActivityLevel = "Low" | "Medium" | "High";
10939
+ type MedicalguardianRiskLevel = "low" | "medium" | "high";
10940
+
10941
+ interface MedicalguardianRiskQuestion {
10942
+ id: string;
10943
+ prompt: string;
10944
+ options: Array<{ value: string; score: number }>;
10945
+ }
10946
+
10947
+ interface MedicalguardianFallRiskAnswers {
10948
+ hearingImpaired: boolean;
10949
+ chronicHealthCondition: boolean;
10950
+ limitedMobility: boolean;
10951
+ activityLevel: MedicalguardianActivityLevel;
10952
+ takesDailyMedications: boolean;
10953
+ travelsAnnually: boolean;
10954
+ homeHasStairs: boolean;
10955
+ drivesDaily: boolean;
10956
+ previouslyFallen: boolean;
10957
+ }
10958
+
10959
+ interface MedicalguardianFallRiskResult {
10960
+ score: number; // 0-9
10961
+ riskLevel: MedicalguardianRiskLevel;
10962
+ assessmentUrl: string;
10963
+ deviceSelectionUrl: string; // the site's own next step — device selection, not built here
10964
+ }
10965
+
10966
+ /**
10967
+ * Medical Guardian's own fall-risk assessment (medicalguardian.com/risk-assessment) — a real
10968
+ * 0-9 score and low/medium/high risk level computed exactly as the site computes it, plus the
10969
+ * site's own 'Choose a Device' handoff URL as the real next step.
10970
+ */
10971
+ interface Unit {
10972
+ /**
10973
+ * Returns Medical Guardian's own 9 fall-risk assessment questions, in order, exactly as
10974
+ * medicalguardian.com/risk-assessment asks them — ask them one at a time, then call
10975
+ * assessFallRisk with the answers.
10976
+ */
10977
+ getRiskAssessmentQuestions(): Promise<{ questions: MedicalguardianRiskQuestion[] }>;
10978
+
10979
+ /**
10980
+ * Runs Medical Guardian's own fall-risk scoring — a real, personalized 0-9 score and risk
10981
+ * level, computed exactly as the site's own calculator computes it, no estimate.
10982
+ * `deviceSelectionUrl` is the real next step the site itself sends the user to.
10983
+ */
10984
+ assessFallRisk(answers: MedicalguardianFallRiskAnswers): Promise<MedicalguardianFallRiskResult>;
10985
+ }
10986
+ }
10987
+
9812
10988
  declare namespace BowmarkProvider_medicare {
9813
10989
  // ── Medicare.gov — the unit's own declarations, verbatim ──
9814
10990
  interface medicareCounty {
@@ -10983,6 +12159,89 @@ interface KayakCar {
10983
12159
  }
10984
12160
  }
10985
12161
 
12162
+ declare namespace BowmarkProvider_mossyoak {
12163
+ // ── Mossy Oak — the unit's own declarations, verbatim ──
12164
+ interface MossyoakVariant {
12165
+ /** Shopify's numeric variant id as a string. */
12166
+ id: string;
12167
+ /** The variant's own label, e.g. "Full Foliage / M/L". */
12168
+ title: string;
12169
+ /** String verbatim from the storefront — "149.99" (dollars) on /products.json, "14999" (cents) on /products/<h>.js. */
12170
+ price: string;
12171
+ /** Same scale as price. Null when the variant is not on sale. */
12172
+ compareAtPrice: string | null;
12173
+ /** The store's own SKU. Null on a variant without one. */
12174
+ sku: string | null;
12175
+ /** Whether the variant is purchasable right now. */
12176
+ available: boolean;
12177
+ /** e.g. ["Full Foliage", "M/L"] — camo pattern + combined size. */
12178
+ options: string[];
12179
+ }
12180
+ interface MossyoakProduct {
12181
+ /** The handle is the only stable identifier across the catalogue. */
12182
+ handle: string;
12183
+ title: string;
12184
+ vendor: string;
12185
+ productType: string;
12186
+ url: string;
12187
+ descriptionHtml: string | null;
12188
+ optionNames: string[];
12189
+ variants: MossyoakVariant[];
12190
+ /** Same scale as variants — see MossyoakVariant.price. */
12191
+ priceRange: { min: string; max: string } | null;
12192
+ /** True if ANY variant is purchasable. */
12193
+ inStock: boolean;
12194
+ tags: string[];
12195
+ /** Mossy Oak's own images, in the order the storefront publishes them. */
12196
+ images: string[];
12197
+ }
12198
+ interface MossyoakCatalogue {
12199
+ /** All matching products, in-stock first, then by handle. */
12200
+ products: MossyoakProduct[];
12201
+ /** What the filter DROPPED, in the same register the rest of the library uses. */
12202
+ warnings: string[];
12203
+ }
12204
+ interface MossyoakCheckoutLink {
12205
+ /** Shopify's own cart-permalink URL — a GET that adds the line item and redirects into the cart. */
12206
+ url: string;
12207
+ /** The exact variant the link resolved to, read live off the storefront. */
12208
+ variant: MossyoakVariant;
12209
+ /** The product the variant belongs to. */
12210
+ product: MossyoakProduct;
12211
+ }
12212
+
12213
+ /**
12214
+ * Mossy Oak camo-apparel and gear catalogue — every product, its camo-pattern and size
12215
+ * variants, real prices and stock — read off the live Shopify storefront, plus a
12216
+ * live-validated checkout handoff link.
12217
+ */
12218
+ interface Unit {
12219
+ /**
12220
+ * Reads the live Mossy Oak catalogue as the storefront publishes it — every product, its
12221
+ * handle, title, vendor, description, tags, images and the per-variant price the storefront is
12222
+ * quoting right now. Returns [] on a transport failure. The catalog page is the line and the
12223
+ * parse is the unit of work.
12224
+ */
12225
+ listMossyoakProducts(opts?: { limit?: number }): Promise<MossyoakProduct[]>;
12226
+
12227
+ /**
12228
+ * Reads one product by its handle — every camo-pattern/size variant, its exact price and
12229
+ * whether that specific variant is purchasable right now. Takes the handle
12230
+ * listMossyoakProducts returns. THROWS on an unknown handle (the store answers a real 404).
12231
+ */
12232
+ getMossyoakProduct(handle: string): Promise<MossyoakProduct>;
12233
+
12234
+ /**
12235
+ * Resolves a product handle + a variant match (either the exact variant title like "Full
12236
+ * Foliage / M/L", or a substring of it) to a real Shopify cart-permalink URL, validated live
12237
+ * against the storefront. THROWS if the handle is unknown, if no variant matches, if the match
12238
+ * is ambiguous (matches more than one variant), or if the matched variant is not currently
12239
+ * available — the error names the candidate or in-stock options so the caller can retry.
12240
+ */
12241
+ getMossyoakCheckoutLink(handle: string, variantTitleOrOptions: string, opts?: { quantity?: number }): Promise<MossyoakCheckoutLink>;
12242
+ }
12243
+ }
12244
+
10986
12245
  declare namespace BowmarkProvider_naic {
10987
12246
  // ── NAIC — the unit's own declarations, verbatim ──
10988
12247
  interface naicCompanyQuery {
@@ -11451,6 +12710,56 @@ interface ottoSearchQuery {
11451
12710
  }
11452
12711
  }
11453
12712
 
12713
+ declare namespace BowmarkProvider_outdoorresearch {
12714
+ // ── Outdoor Research — the unit's own declarations, verbatim ──
12715
+ interface OutdoorResearchWarrantyPolicy {
12716
+ teamId: string;
12717
+ teamName: string; // "Outdoor Research"
12718
+ excludedTags: string[]; // e.g. ["Non-OR","warehouse_sale","POS_only","Nikwax"]
12719
+ thirdPartyPurchasesAccepted: boolean;
12720
+ purchaseLocations: string[]; // e.g. ["www.outdoorresearch.com","Other"]
12721
+ replacesFromFullCatalogWhenInStock: boolean;
12722
+ replacesFromFullCatalogWhenOutOfStock: boolean;
12723
+ receiptRequiredForThirdParty: boolean;
12724
+ productPhotoRequiredForThirdParty: boolean;
12725
+ supportEmail: string | null;
12726
+ notFoundMessage: string | null;
12727
+ expiredMessage: string | null;
12728
+ }
12729
+ interface OutdoorResearchClaimEligibility {
12730
+ eligible: boolean;
12731
+ status: "not_found" | "blocked" | "expired" | "eligible";
12732
+ message: string; // the site's own wording for this outcome
12733
+ continueUrl: string | null; // set only when eligible: true
12734
+ }
12735
+
12736
+ /**
12737
+ * Reads Outdoor Research's Infinite Guarantee warranty program straight from the ReturnLogic
12738
+ * claim portal's own API — the real program rules, and whether a given order/email can open a
12739
+ * claim right now — no key, no browser.
12740
+ */
12741
+ interface Unit {
12742
+ /**
12743
+ * Reads Outdoor Research's Infinite Guarantee program config straight from the ReturnLogic
12744
+ * claim portal — exclusion tags, in-stock/out-of-stock replacement scenarios, third-party
12745
+ * purchase acceptance and its named purchase locations, receipt/photo requirements, and the
12746
+ * site's own not-found/expired copy. Takes nothing. THROWS rather than returning a placeholder
12747
+ * when the settings endpoint answers without teamId/teamName.
12748
+ */
12749
+ getWarrantyPolicy(): Promise<OutdoorResearchWarrantyPolicy>;
12750
+
12751
+ /**
12752
+ * Starts an Infinite Guarantee claim by order number + email — the same lookup 'File a
12753
+ * Warranty Claim' performs. Returns `eligible: false` with a `status` of
12754
+ * not_found/blocked/expired and the site's own message when the pair does not qualify (a real,
12755
+ * expected answer, not an error) — never throws for those. On `eligible: true`, `continueUrl`
12756
+ * is where the customer would pick items and see per-item eligibility. THROWS only on a
12757
+ * transport failure or an unrecognized response.
12758
+ */
12759
+ checkClaimEligibility(orderNumber: string, email: string): Promise<OutdoorResearchClaimEligibility>;
12760
+ }
12761
+ }
12762
+
11454
12763
  declare namespace BowmarkProvider_paypal {
11455
12764
  // ── PayPal — the unit's own declarations, verbatim ──
11456
12765
  interface PaypalEstimateFeeArgs {
@@ -12928,6 +14237,176 @@ interface RedditThread {
12928
14237
  }
12929
14238
  }
12930
14239
 
14240
+ declare namespace BowmarkProvider_reliancepartners {
14241
+ // ── Reliance Partners — the unit's own declarations, verbatim ──
14242
+ interface ReliancePartnersApplicationSchema {
14243
+ entryUrl: string;
14244
+ steps: Array<{
14245
+ title: string; // "Basic Info" | "Coverage" | "Equipment"
14246
+ fields: Array<{ gfName: string; label: string; type: string; required: boolean; options?: Array<{ value: string; label: string }> }>;
14247
+ repeaters: Array<{ title: string; gfRepeaterId: string; maxItems: number; columns: Array<{ gfName: string; label: string; type: string; required: boolean; options?: Array<{ value: string; label: string }> }> }>;
14248
+ }>;
14249
+ }
14250
+
14251
+ interface AssembledApplication {
14252
+ valid: boolean;
14253
+ errors: string[];
14254
+ entryUrl: string;
14255
+ formFields: Record<string, string>; // the site's own GF field names
14256
+ summary: string;
14257
+ }
14258
+
14259
+ /**
14260
+ * Reliance Partners' own 3-step commercial-trucking insurance application (FMCSA/EIN, per-line
14261
+ * coverage limits, equipment) — reads the live field structure and enumerated catalogs, and
14262
+ * validates + assembles a caller's application against it, ready to submit.
14263
+ */
14264
+ interface Unit {
14265
+ /**
14266
+ * Reads reliancepartners.com/quote/'s live 3-step trucking-insurance application — every
14267
+ * field, and every real enumerated catalog (15 coverage lines, 30 commodities, FMCSA type, all
14268
+ * US states).
14269
+ */
14270
+ getApplicationSchema(): Promise<ReliancePartnersApplicationSchema>;
14271
+
14272
+ /**
14273
+ * Validates a caller's trucking-insurance application against the live schema's own field
14274
+ * requirements and enumerated catalogs, then maps it onto the site's own Gravity Forms field
14275
+ * names — exact, ready to submit. Never submits it; the site's own flow ends in a human
14276
+ * underwriting follow-up, not an instant quote.
14277
+ */
14278
+ assembleApplication(args: object): Promise<AssembledApplication>;
14279
+ }
14280
+ }
14281
+
14282
+ declare namespace BowmarkProvider_revisionskincare {
14283
+ // ── Revision Skincare — the unit's own declarations, verbatim ──
14284
+ type RevisionQuestionType = "single-select" | "multi-select";
14285
+
14286
+ interface RevisionQuizOption {
14287
+ title: string;
14288
+ }
14289
+
14290
+ interface RevisionQuizQuestion {
14291
+ questionId: string;
14292
+ text: string;
14293
+ type: RevisionQuestionType;
14294
+ options: RevisionQuizOption[];
14295
+ }
14296
+
14297
+ interface RevisionQuizQuestions {
14298
+ quizId: string;
14299
+ channelQuizId: string;
14300
+ subscriberId: string;
14301
+ questions: RevisionQuizQuestion[];
14302
+ }
14303
+
14304
+ interface RevisionQuizAnswer {
14305
+ questionId: string;
14306
+ type: RevisionQuestionType;
14307
+ answer: string | string[];
14308
+ }
14309
+
14310
+ interface RevisionRecommendedProduct {
14311
+ productId: string;
14312
+ name: string;
14313
+ description: string;
14314
+ url: string;
14315
+ imageUrl: string;
14316
+ price: number | null;
14317
+ currencyCode: string | null;
14318
+ averageRating: number | null;
14319
+ approvedReviewsCount: number | null;
14320
+ }
14321
+
14322
+ interface RevisionQuizResult {
14323
+ quizResponseId: string;
14324
+ title: string;
14325
+ subtitle: string;
14326
+ products: RevisionRecommendedProduct[];
14327
+ }
14328
+
14329
+ /**
14330
+ * Reads and answers Revision Skincare's own Product Finder Quiz
14331
+ * (revisionskincare.com/pages/skincare-quiz), returning the site's real computed product
14332
+ * recommendations.
14333
+ */
14334
+ interface Unit {
14335
+ /**
14336
+ * Reads the live Product Finder Quiz's real questions, in order, each with its options and
14337
+ * answer type.
14338
+ */
14339
+ getSkincareQuizQuestions(): Promise<RevisionQuizQuestions>;
14340
+
14341
+ /**
14342
+ * Submits a shopper's answers to the Product Finder Quiz and returns the site's real computed
14343
+ * product recommendations.
14344
+ */
14345
+ takeSkincareQuiz(arg: { answers: RevisionQuizAnswer[] }): Promise<RevisionQuizResult>;
14346
+ }
14347
+ }
14348
+
14349
+ declare namespace BowmarkProvider_rishitea {
14350
+ // ── Rishi Tea & Botanicals — the unit's own declarations, verbatim ──
14351
+ interface TeaFinderQuestion {
14352
+ id: string;
14353
+ profileQuestionId: string;
14354
+ text: string;
14355
+ selectionType: "single" | "multi";
14356
+ options: string[];
14357
+ minSelections?: number;
14358
+ maxSelections?: number;
14359
+ }
14360
+ interface TeaFinderQuiz {
14361
+ quizId: string;
14362
+ channelQuizId: string;
14363
+ questions: TeaFinderQuestion[];
14364
+ }
14365
+ interface TeaFinderAnswerInput {
14366
+ questionId: string; // a TeaFinderQuestion.id
14367
+ answer: string | string[]; // string for selectionType "single", string[] for "multi"
14368
+ }
14369
+ interface TeaFinderProduct {
14370
+ name: string;
14371
+ url: string;
14372
+ description: string;
14373
+ imageUrl: string;
14374
+ averageRating: number | null;
14375
+ approvedReviewsCount: number;
14376
+ price: number | null;
14377
+ currencyCode: string | null;
14378
+ }
14379
+ interface TeaFinderResult {
14380
+ quizResponseId: string;
14381
+ title: string;
14382
+ subtitle: string | null;
14383
+ products: TeaFinderProduct[];
14384
+ runnerUpProducts: TeaFinderProduct[];
14385
+ }
14386
+
14387
+ /**
14388
+ * Rishi Tea's own "Tea Finder" quiz (Okendo Quizzes) — reads the real question set and submits
14389
+ * real answers to get back the site's own personalized tea recommendation.
14390
+ */
14391
+ interface Unit {
14392
+ /**
14393
+ * Reads the live Tea Finder quiz's real question set straight from Okendo's quiz API — every
14394
+ * question's text, whether it takes one answer or several, and its exact option strings. Call
14395
+ * this first: `matchTeaFinderQuiz` needs the caller's answers keyed on each question's own
14396
+ * `id`.
14397
+ */
14398
+ getTeaFinderQuiz(): Promise<TeaFinderQuiz>;
14399
+
14400
+ /**
14401
+ * Submits a full set of answers (one per question `getTeaFinderQuiz` returned) to Okendo's
14402
+ * quiz engine and returns the SAME personalized recommendation the live widget shows — a
14403
+ * title/subtitle and the real recommended products (name, buy link, description, rating,
14404
+ * price) pulled from Rishi's actual catalog, plus a runner-up list.
14405
+ */
14406
+ matchTeaFinderQuiz(quiz: TeaFinderQuiz, answers: TeaFinderAnswerInput[]): Promise<TeaFinderResult>;
14407
+ }
14408
+ }
14409
+
12931
14410
  declare namespace BowmarkProvider_ritani {
12932
14411
  // ── Ritani — the unit's own declarations, verbatim ──
12933
14412
  // Ritani's OWN shapes — not a capability contract.
@@ -13038,6 +14517,137 @@ interface RoofmaxxCostEstimate {
13038
14517
  }
13039
14518
  }
13040
14519
 
14520
+ declare namespace BowmarkProvider_saatva {
14521
+ // ── Saatva — the unit's own declarations, verbatim ──
14522
+ // Saatva's OWN shapes — not a capability contract.
14523
+
14524
+ interface MattressQuizAnswers {
14525
+ sleepPosition: "side" | "back" | "stomach";
14526
+ feel: "soft" | "medium" | "firm";
14527
+ sharesBed?: boolean; // optional — narrows scoring further when given
14528
+ }
14529
+
14530
+ interface SaatvaVariant {
14531
+ sku: string;
14532
+ name: string;
14533
+ size: string | null;
14534
+ comfortLevel: string | null; // Saatva's own label, e.g. "Medium Firm"
14535
+ mattressType: string | null; // "Standard" | "Split" | "Upper-Flex"
14536
+ price: number | null;
14537
+ inStock: boolean;
14538
+ sleepPositions: string[]; // e.g. ["Side Sleeper", "Back Sleeper"]
14539
+ url: string; // pre-selected-SKU product page, one click from cart
14540
+ }
14541
+
14542
+ interface SaatvaMattress {
14543
+ productCode: string;
14544
+ name: string;
14545
+ url: string;
14546
+ variants: SaatvaVariant[];
14547
+ }
14548
+
14549
+ interface SaatvaRecommendation {
14550
+ productCode: string;
14551
+ name: string;
14552
+ score: number; // higher is a better match; ties break on lower price
14553
+ matchedOn: string[]; // plain-language reasons this variant scored
14554
+ bestVariant: SaatvaVariant | null;
14555
+ }
14556
+
14557
+ /**
14558
+ * Saatva's mattress catalogue and its own mattress-quiz recommendation logic — every mattress
14559
+ * line Saatva currently sells with every buyable variant's size, comfort level, sleep-position
14560
+ * fit, stock and price, plus a real computed recommendation from stated sleep position,
14561
+ * weight, and firmness preference, each with the exact pre-selected-SKU product link to buy
14562
+ * it.
14563
+ */
14564
+ interface Unit {
14565
+ /**
14566
+ * Lists every mattress product line Saatva currently sells with every buyable variant — size,
14567
+ * comfort level, sleep-position fit, stock and price — read out of the same catalogue the
14568
+ * site's own mattress quiz scores against. Takes nothing. THROWS rather than returning [] when
14569
+ * the page answers without its payload or names no mattress lines, because Saatva always sells
14570
+ * these and an empty array would read as a catalogue that had emptied.
14571
+ */
14572
+ listMattresses(): Promise<SaatvaMattress[]>;
14573
+
14574
+ /**
14575
+ * Runs Saatva's mattress-quiz goal-flow (saatva.com/mattress-quiz) for a stated sleep position
14576
+ * and firmness preference, ranking every mattress line against the SAME live catalogue the
14577
+ * site's own quiz reads and returning the best-matching in-stock variant for each, with its
14578
+ * exact pre-selected-SKU buy link. Ranked highest score first, ties broken by lower price.
14579
+ * `matchedOn` names which stated preferences the top variant actually satisfies. Does NOT
14580
+ * replicate Saatva's internal weighted scoring formula byte-for-byte — that logic is
14581
+ * proprietary client-side JS — it scores each variant's own declared attributes against what
14582
+ * was asked, which is a genuine computation over real data rather than a guess from marketing
14583
+ * copy.
14584
+ */
14585
+ recommendMattress(answers: MattressQuizAnswers): Promise<SaatvaRecommendation[]>;
14586
+ }
14587
+ }
14588
+
14589
+ declare namespace BowmarkProvider_saltandstone {
14590
+ // ── Salt & Stone — the unit's own declarations, verbatim ──
14591
+ // Salt & Stone's OWN shapes — not a capability contract.
14592
+
14593
+ interface ScentFamily {
14594
+ handle: string;
14595
+ name: string; // e.g. "Santal & Vetiver"
14596
+ description: string; // the site's own mood copy
14597
+ notes: { top: string[]; heart: string[]; base: string[] }; // real fragrance notes
14598
+ url: string;
14599
+ }
14600
+
14601
+ interface ScentMatch {
14602
+ handle: string;
14603
+ name: string;
14604
+ score: number; // 0-1 — how much of the caller's preference matched this family's real notes/copy
14605
+ matchedTerms: string[]; // which of the caller's own words matched, and why
14606
+ url: string;
14607
+ }
14608
+
14609
+ interface ScentProduct {
14610
+ handle: string; // "body-wash" | "body-mist" | "body-lotion" | "natural-deodorant" | "hand-cream" | "candle"
14611
+ title: string;
14612
+ productType: string;
14613
+ variantId: string;
14614
+ variantTitle: string;
14615
+ price: number; // dollars, real Shopify variant price
14616
+ compareAtPrice: number | null;
14617
+ available: boolean; // real live stock flag
14618
+ url: string; // real product page, this exact variant preselected
14619
+ }
14620
+
14621
+ /**
14622
+ * Salt & Stone's own Scent Quiz, reimplemented over its real six named scent families: list
14623
+ * every family's real fragrance notes, compute a real ranked match against a free-text
14624
+ * preference, and shop the real core products (body wash, mist, lotion, deodorant, hand cream,
14625
+ * candle) in the matched scent with real price and availability.
14626
+ */
14627
+ interface Unit {
14628
+ /**
14629
+ * Lists Salt & Stone's real six named scent families, each with its own real top/heart/base
14630
+ * fragrance notes and mood description, read off the site's own collection pages.
14631
+ */
14632
+ listScentFamilies(): Promise<ScentFamily[]>;
14633
+
14634
+ /**
14635
+ * Salt & Stone's own Scent Quiz, reimplemented: computes a real ranked match across all six
14636
+ * scent families by scoring the preference's terms against each family's own published
14637
+ * fragrance notes and description.
14638
+ */
14639
+ matchScent(preferences: string): Promise<ScentMatch[]>;
14640
+
14641
+ /**
14642
+ * Lists the real core products (body wash, body mist, body lotion, deodorant, hand cream,
14643
+ * candle) available in one named scent family, with each one's real price, availability and
14644
+ * product page. THROWS on an unknown family name, naming listScentFamilies() as the way to
14645
+ * find current ones.
14646
+ */
14647
+ getScentProducts(familyName: string): Promise<ScentProduct[]>;
14648
+ }
14649
+ }
14650
+
13041
14651
  declare namespace BowmarkProvider_samsclub {
13042
14652
  // ── Sam's Club — the unit's own declarations, verbatim ──
13043
14653
  interface SamsclubInstantSavingsItem {
@@ -13230,6 +14840,50 @@ interface SamsclubMembershipPlan {
13230
14840
  }
13231
14841
  }
13232
14842
 
14843
+ declare namespace BowmarkProvider_seakeeper {
14844
+ // ── Seakeeper — the unit's own declarations, verbatim ──
14845
+ interface SeakeeperDealer {
14846
+ name: string;
14847
+ address: string;
14848
+ contactName: string;
14849
+ phone: string;
14850
+ email: string;
14851
+ website: string;
14852
+ latitude: number;
14853
+ longitude: number;
14854
+ tier: string;
14855
+ tierLabel: string;
14856
+ }
14857
+ interface SeakeeperNearbyDealer extends SeakeeperDealer {
14858
+ distanceMiles: number;
14859
+ }
14860
+ interface SeakeeperNearestDealersResult {
14861
+ zip: string;
14862
+ dealers: SeakeeperNearbyDealer[];
14863
+ }
14864
+
14865
+ /**
14866
+ * Reads Seakeeper's own real-time Dealer / Elite Dealer Locator directly (the same admin-ajax
14867
+ * endpoint the site's map runs) — every real gyro-stabilizer dealer worldwide, or the nearest
14868
+ * ones to a US zip ranked by distance with each dealer's real tier (Elite Dealer / Dealer /
14869
+ * Master Technician).
14870
+ */
14871
+ interface Unit {
14872
+ /**
14873
+ * Every real Seakeeper dealer worldwide (name, address, contact, coordinates, tier), read
14874
+ * straight from the locator's own live data endpoint.
14875
+ */
14876
+ listAllDealers(): Promise<SeakeeperDealer[]>;
14877
+
14878
+ /**
14879
+ * Ranks every real Seakeeper dealer by distance from a US zip and returns the nearest `limit`
14880
+ * (default 20, matching the site's own displayed count), each with its real tier and how far
14881
+ * it is.
14882
+ */
14883
+ findNearestDealers(zip: string, limit?: number): Promise<SeakeeperNearestDealersResult>;
14884
+ }
14885
+ }
14886
+
13233
14887
  declare namespace BowmarkProvider_sears {
13234
14888
  // ── Sears — the unit's own declarations, verbatim ──
13235
14889
  interface SearsSearchPrice {
@@ -13562,6 +15216,52 @@ interface SemihandmadePriceResult {
13562
15216
  }
13563
15217
  }
13564
15218
 
15219
+ declare namespace BowmarkProvider_smartsign {
15220
+ // ── SmartSign — the unit's own declarations, verbatim ──
15221
+ interface SmartsignSearchResult {
15222
+ sku: string;
15223
+ name: string;
15224
+ url: string; // absolute product page URL — what getTemplate takes
15225
+ imageUrl: string;
15226
+ }
15227
+ interface SmartsignMaterialPricing {
15228
+ name: string; // e.g. "Aluminum"
15229
+ sizeCode: string; // SmartSign's own per-material+size code
15230
+ unitPrice: number; // single-unit price, e.g. 37.94
15231
+ pricingTiers: { qty: number; price: number }[]; // volume-discount ladder, includes qty:1
15232
+ }
15233
+ interface SmartsignTemplate {
15234
+ sku: string;
15235
+ title: string;
15236
+ url: string;
15237
+ materials: SmartsignMaterialPricing[];
15238
+ }
15239
+
15240
+ /**
15241
+ * Reads SmartSign's custom-sign template configurator — search for a template, then read its
15242
+ * real per-material live pricing and volume-discount ladder — straight from smartsign.com's
15243
+ * own pages, no key, no browser.
15244
+ */
15245
+ interface Unit {
15246
+ /**
15247
+ * Runs SmartSign's own site-search suggest endpoint for a free-text query (e.g. "parking
15248
+ * sign", "custom aluminum sign") and returns the matching product/template rows — sku, name,
15249
+ * product URL, thumbnail — deduplicated by URL. The `sku` it returns is what getTemplate
15250
+ * takes. May legitimately return [] for a query that matches nothing.
15251
+ */
15252
+ search(query: string): Promise<SmartsignSearchResult[]>;
15253
+
15254
+ /**
15255
+ * Reads one custom-sign template's product page and returns its title plus every material
15256
+ * option offered — display name, the site's own size+material code, single-unit price, and the
15257
+ * FULL volume-discount ladder (qty tier -> price). THROWS rather than returning an empty
15258
+ * materials list on a retired/mistyped SKU — every real template offers at least one material,
15259
+ * so zero is never an honest answer.
15260
+ */
15261
+ getTemplate(sku: string): Promise<SmartsignTemplate>;
15262
+ }
15263
+ }
15264
+
13565
15265
  declare namespace BowmarkProvider_soundcloud {
13566
15266
  // ── SoundCloud — the unit's own declarations, verbatim ──
13567
15267
  // SoundCloud's OWN row shape — not the `music` capability contract.
@@ -14328,6 +16028,69 @@ interface teladocInsuranceCoverage {
14328
16028
  }
14329
16029
  }
14330
16030
 
16031
+ declare namespace BowmarkProvider_teneohg {
16032
+ // ── Teneo Hospitality Group — the unit's own declarations, verbatim ──
16033
+ // Teneo's OWN shapes — not a capability contract.
16034
+
16035
+ interface TeneohgHotelSummary {
16036
+ slug: string;
16037
+ name: string;
16038
+ city: string | null;
16039
+ region: string | null; // US state code, e.g. "AZ", or a country name
16040
+ profileUrl: string;
16041
+ totalMeetingSpaceSqFt: number | null;
16042
+ largestMeetingSpaceSqFt: number | null;
16043
+ sleepingRooms: number | null;
16044
+ collections: string[]; // e.g. ["Luxury", "Resorts"]
16045
+ }
16046
+
16047
+ interface TeneohgSearchResult { hotels: TeneohgHotelSummary[]; totalMatched: number; totalScanned: number; pagesScanned: number }
16048
+
16049
+ type TeneohgHotelStats = Record<string, string>; // e.g. { "Meeting Room Space": "156,000 Sq. Ft.", "Number of Sleeping Rooms": "517" }
16050
+
16051
+ interface TeneohgRfpHandoff { url: string; hotelsOfInterestValue: string }
16052
+
16053
+ interface TeneohgHotelDetail {
16054
+ slug: string;
16055
+ name: string;
16056
+ city: string | null;
16057
+ region: string | null;
16058
+ profileUrl: string;
16059
+ stats: TeneohgHotelStats;
16060
+ rfpHandoff: TeneohgRfpHandoff; // the public RFP form + what to type into its "Hotels of Interest" field
16061
+ }
16062
+
16063
+ /**
16064
+ * Teneo Hospitality Group's own member-hotel directory — search 350+ independent and
16065
+ * small-branded meeting hotels by destination, collection and meeting-space/room-block size
16066
+ * with real specs, then read one hotel's full meeting-space stat block and the RFP hand-off to
16067
+ * actually request a proposal.
16068
+ */
16069
+ interface Unit {
16070
+ /**
16071
+ * Searches Teneo's own member-hotel directory (350+ hotels) by US state (2-letter code, e.g.
16072
+ * "AZ"), country, collection tag substring (e.g. "luxury", "resorts"), minimum total
16073
+ * meeting-space square footage, minimum sleeping-room count and a name/city substring. Uses
16074
+ * one of the site's own curated per-state directory pages when the requested state has one
16075
+ * (faster, pre-filtered), otherwise scans the base listing's pages (bounded by
16076
+ * `maxPagesToScan`, default 8) and filters client-side. `totalMatched` is the count before
16077
+ * `limit` (default 20, max 50) cuts the list; `totalScanned`/`pagesScanned` say how much of
16078
+ * the directory the call actually covered.
16079
+ */
16080
+ searchMemberHotels(args?: { state?: string; country?: string; collection?: string; minMeetingSpaceSqFt?: number; minSleepingRooms?: number; query?: string; limit?: number; maxPagesToScan?: number }): Promise<TeneohgSearchResult>;
16081
+
16082
+ /**
16083
+ * Reads one member hotel's own profile page: every stat its meeting-space and sleeping-room
16084
+ * widgets carry (total/largest/second-largest meeting room space, outdoor space, meeting-room
16085
+ * count, suites, doubles), keyed on the site's own label text, plus `rfpHandoff` — the public
16086
+ * RFP form URL and the exact value to put in its "Hotels of Interest" field to route a request
16087
+ * at this hotel. `slug` comes from searchMemberHotels(). THROWS on an unknown slug, naming
16088
+ * searchMemberHotels() as the way to find current ones.
16089
+ */
16090
+ getMemberHotel(slug: string): Promise<TeneohgHotelDetail>;
16091
+ }
16092
+ }
16093
+
14331
16094
  declare namespace BowmarkProvider_therabody {
14332
16095
  // ── Therabody — the unit's own declarations, verbatim ──
14333
16096
  interface TherabodyVariant {
@@ -14913,6 +16676,108 @@ interface thezebraAutoQuotes {
14913
16676
  }
14914
16677
  }
14915
16678
 
16679
+ declare namespace BowmarkProvider_tilsonhomes {
16680
+ // ── Tilson Homes — the unit's own declarations, verbatim ──
16681
+ interface TilsonhomesPlan {
16682
+ id: number;
16683
+ name: string;
16684
+ displayName: string | null;
16685
+ bed: number | null;
16686
+ bath: number | null;
16687
+ size: number | null;
16688
+ cost: number | null;
16689
+ defaultElevationId: number | null;
16690
+ }
16691
+
16692
+ interface TilsonhomesElevationDetails {
16693
+ id: number;
16694
+ planName: string | null;
16695
+ caption: string | null;
16696
+ thumb: string | null;
16697
+ bed: number | null;
16698
+ bedMin: number | null;
16699
+ bedMax: number | null;
16700
+ bath: number | null;
16701
+ bathMin: number | null;
16702
+ bathMax: number | null;
16703
+ size: number | null;
16704
+ sizeMin: number | null;
16705
+ sizeMax: number | null;
16706
+ cost: number | null;
16707
+ costMin: number | null;
16708
+ costMax: number | null;
16709
+ description: string | null;
16710
+ finishes: TilsonhomesFinishOption[];
16711
+ }
16712
+
16713
+ interface TilsonhomesFinishOption {
16714
+ category: string | null;
16715
+ name: string | null;
16716
+ displayName: string | null;
16717
+ swatches: { id: number; name: string | null }[];
16718
+ }
16719
+
16720
+ /**
16721
+ * Reads Tilson Homes' Build-On-Your-Land floor plan catalog and each plan's Anewgo-powered
16722
+ * customizer — bed/bath/size range and exterior finish options — the way the live site's
16723
+ * interactive floorplan tool would show them.
16724
+ */
16725
+ interface Unit {
16726
+ /**
16727
+ * Lists Tilson Homes' Build-On-Your-Land floor plans — model name, bed/bath/size and the
16728
+ * default elevation id `getElevationDetails` reads. The entry point: every plan links to a
16729
+ * customizer instance.
16730
+ */
16731
+ listPlans(activeOnly?: boolean): Promise<TilsonhomesPlan[]>;
16732
+
16733
+ /**
16734
+ * Reads one plan's elevation — the exterior style's customization range (how far bed/bath/size
16735
+ * can be pushed by the site's own add-a-room options) and its exterior finish categories
16736
+ * (roof, trim, body, accent) with the swatch currently assigned to each. The read behind 'add
16737
+ * a covered porch and a 4th bedroom, show me the finishes'.
16738
+ */
16739
+ getElevationDetails(elevationId: number | string): Promise<TilsonhomesElevationDetails>;
16740
+ }
16741
+ }
16742
+
16743
+ declare namespace BowmarkProvider_titlenine {
16744
+ // ── Title Nine — the unit's own declarations, verbatim ──
16745
+ // Title Nine's OWN shapes — not a capability contract.
16746
+
16747
+ interface TitlenineBraMeasurements {
16748
+ chestInches: number; // site's calculatable range: 30-46
16749
+ bustInches: number;
16750
+ belowBustInches: number; // site requires >= 24
16751
+ }
16752
+
16753
+ interface TitlenineBraSizeResult {
16754
+ bandSize: number;
16755
+ cupCode: string; // the site's own raw catalog query param, e.g. "DD%2B"
16756
+ cupLabel: string; // the label shown to the customer, e.g. "M (11D)"
16757
+ sizeLabel: string; // "<bandSize><cupLabel>", e.g. "40M (11D)"
16758
+ inStock: boolean; // false for the extended range (n2 >= 9)
16759
+ shopUrl: string | null; // pre-filtered catalog link, only when inStock
16760
+ unavailableMessage: string | null;
16761
+ calculatorUrl: string;
16762
+ }
16763
+
16764
+ /**
16765
+ * Title Nine's own bra-size calculator — real band + cup math off three measurements, computed
16766
+ * exactly as the site computes it, including the extended cup range (up to "M (11D)") that
16767
+ * generic AI knowledge gets wrong — plus the exact 'Shop <size>' catalog link when the size is
16768
+ * in stock.
16769
+ */
16770
+ interface Unit {
16771
+ /**
16772
+ * Runs Title Nine's own bra-size calculator — chest/bust/under-bust in, a real band + cup size
16773
+ * out computed exactly as the site computes it, including Title Nine's own extended cup
16774
+ * labeling past DDD (up to "M (11D)") that generic AI knowledge gets wrong. Returns the exact
16775
+ * 'Shop <size>' catalog link when the size is currently carried online.
16776
+ */
16777
+ calculateBraSize(input: TitlenineBraMeasurements): Promise<TitlenineBraSizeResult>;
16778
+ }
16779
+ }
16780
+
14916
16781
  declare namespace BowmarkProvider_topviewtix {
14917
16782
  // ── TopView Sightseeing — the unit's own declarations, verbatim ──
14918
16783
  interface topviewtixPackageDetails {
@@ -15594,6 +17459,74 @@ interface VoluspaQuizIntro {
15594
17459
  }
15595
17460
  }
15596
17461
 
17462
+ declare namespace BowmarkProvider_walkerhughes {
17463
+ // ── WalkerHughes Insurance — the unit's own declarations, verbatim ──
17464
+ // WalkerHughes' OWN shapes — not a capability contract.
17465
+
17466
+ interface WalkerhughesProduct {
17467
+ id: string; // the exact `product` value /start-quote expects
17468
+ name: string;
17469
+ personal: boolean; // Personal vs Business, from the site's own toggle
17470
+ }
17471
+
17472
+ interface WalkerhughesQuoteCatalog {
17473
+ products: WalkerhughesProduct[];
17474
+ applyUrl: string; // the real /start-quote URL — no query prefill exists
17475
+ sourceUrl: string;
17476
+ }
17477
+
17478
+ interface WalkerhughesOffice {
17479
+ label: string; // exact `preferredOffice` value /start-quote expects
17480
+ city: string;
17481
+ state: string;
17482
+ address: string | null;
17483
+ phone: string | null;
17484
+ url: string; // this office's own detail page
17485
+ }
17486
+
17487
+ interface WalkerhughesOfficeDirectory {
17488
+ offices: WalkerhughesOffice[];
17489
+ sourceUrl: string;
17490
+ }
17491
+
17492
+ interface WalkerhughesOfficeMatch extends WalkerhughesOffice {
17493
+ matchedOn: "label" | "city" | "state";
17494
+ }
17495
+
17496
+ interface WalkerhughesOfficeSearch {
17497
+ query: string;
17498
+ matches: WalkerhughesOfficeMatch[];
17499
+ sourceUrl: string;
17500
+ }
17501
+
17502
+ /**
17503
+ * WalkerHughes' real 16-product Personal/Business insurance-quote application catalog and its
17504
+ * real 25-office directory, straight off /start-quote and /locations — list and filter the
17505
+ * product catalog, list and filter offices, and match a caller's free-text location against
17506
+ * the real office directory.
17507
+ */
17508
+ interface Unit {
17509
+ /**
17510
+ * Lists WalkerHughes' real 16-product insurance catalog straight off the /start-quote form's
17511
+ * own <select>, optionally filtered to just Personal or just Business — the same toggle the
17512
+ * live form applies. Includes the real applyUrl handoff.
17513
+ */
17514
+ listQuoteProducts(department?: "Personal" | "Business"): Promise<WalkerhughesQuoteCatalog>;
17515
+
17516
+ /**
17517
+ * Lists WalkerHughes' real 25-office directory straight off /locations' own server-rendered
17518
+ * cards, optionally filtered to one two-letter state.
17519
+ */
17520
+ listOffices(state?: string): Promise<WalkerhughesOfficeDirectory>;
17521
+
17522
+ /**
17523
+ * Matches a free-text location (a city, a two-letter state, or "City, ST") against the real
17524
+ * office directory and returns every match, ranked exact-label > city > state.
17525
+ */
17526
+ findNearestOffice(query: string): Promise<WalkerhughesOfficeSearch>;
17527
+ }
17528
+ }
17529
+
15597
17530
  declare namespace BowmarkProvider_walmart {
15598
17531
  // ── Walmart — the unit's own declarations, verbatim ──
15599
17532
  interface walmartStore {
@@ -15661,6 +17594,64 @@ interface walmartSearchResult {
15661
17594
  }
15662
17595
  }
15663
17596
 
17597
+ declare namespace BowmarkProvider_waterfurnace {
17598
+ // ── WaterFurnace — the unit's own declarations, verbatim ──
17599
+ type WaterfurnaceFuelSource = "gas" | "propane" | "heatpump" | "resistance" | "oil";
17600
+ type WaterfurnaceSecondaryFuelSource = "gas" | "propane" | "resistance" | "oil" | "none";
17601
+ interface WaterfurnaceHomeDetails {
17602
+ address: string;
17603
+ postalCode: string;
17604
+ homeAgeYears: number;
17605
+ livingSqft: number;
17606
+ basementSqft: number;
17607
+ lotAcreage: number;
17608
+ }
17609
+ interface WaterfurnaceRecommendedSystem {
17610
+ tier: "good" | "better" | "best";
17611
+ title: string;
17612
+ description: string;
17613
+ highlights: string[];
17614
+ }
17615
+ interface WaterfurnaceSavingsEstimate {
17616
+ zipCode: string;
17617
+ lat: number;
17618
+ lng: number;
17619
+ currentAnnualCostUsd: number;
17620
+ geothermalAnnualCostUsd: number;
17621
+ annualSavingsUsd: number;
17622
+ savingsBreakdownUsd: { heating: number; cooling: number; hotWater: number };
17623
+ carbonFootprintLbsPerYear: { current: number; geothermal: number; reduction: number };
17624
+ fuelRates: { gas: number; electric: number; oil: number; propane: number };
17625
+ recommendedSystems: WaterfurnaceRecommendedSystem[];
17626
+ warnings: string[];
17627
+ }
17628
+
17629
+ /**
17630
+ * WaterFurnace's Savings Calculator, run for real — the site's own computed Free Savings
17631
+ * Report (annual dollar savings, energy comparison, carbon footprint, recommended geothermal
17632
+ * systems) for a real address and fuel source, off its undocumented backend API.
17633
+ */
17634
+ interface Unit {
17635
+ /**
17636
+ * Runs the Savings Calculator's own home-details lookup for an address/zip. Returns the site's
17637
+ * real public-data estimate of home age, living sqft and basement sqft — a fixed fallback
17638
+ * estimate (not an error) when the address isn't in its data source, matching what the
17639
+ * wizard's own UI does.
17640
+ */
17641
+ lookupHomeDetails(input: { address: string; city?: string; state?: string; zipCode: string }): Promise<WaterfurnaceHomeDetails>;
17642
+
17643
+ /**
17644
+ * Runs the Savings Calculator's real backend computation for a home and current fuel source
17645
+ * (gas/propane/electric heat pump/electric resistance/oil) and returns the site's own computed
17646
+ * Free Savings Report: current vs. geothermal annual cost, dollar savings, carbon footprint
17647
+ * reduction, and WaterFurnace's recommended systems. Missing home details are filled from
17648
+ * lookupHomeDetails; a missing lat/lng is resolved from the zip via a keyless geocode. THROWS
17649
+ * if the API's response shape has changed.
17650
+ */
17651
+ estimateGeothermalSavings(input: { zipCode: string; state: string; address?: string; city?: string; fuelSource: WaterfurnaceFuelSource; secondaryFuelSource?: WaterfurnaceSecondaryFuelSource; homeAgeYears?: number; livingSqft?: number; basementSqft?: number; numResidents?: number; winterSetpointF?: number; summerSetpointF?: number; lat?: number; lng?: number }): Promise<WaterfurnaceSavingsEstimate>;
17652
+ }
17653
+ }
17654
+
15664
17655
  declare namespace BowmarkProvider_wellfound {
15665
17656
  // ── Wellfound — the unit's own declarations, verbatim ──
15666
17657
  interface wellfoundRow {
@@ -15819,6 +17810,62 @@ interface XpressWaitTime {
15819
17810
  }
15820
17811
  }
15821
17812
 
17813
+ declare namespace BowmarkProvider_yorkwallcoverings {
17814
+ // ── York Wallcoverings — the unit's own declarations, verbatim ──
17815
+ interface YorkWallcoveringsSearchResult {
17816
+ sku: string;
17817
+ name: string;
17818
+ url: string;
17819
+ price: number;
17820
+ }
17821
+
17822
+ interface YorkWallcoveringsProduct {
17823
+ sku: string;
17824
+ name: string;
17825
+ url: string;
17826
+ price: number;
17827
+ inStock: boolean;
17828
+ description: string;
17829
+ images: string[];
17830
+ }
17831
+
17832
+ interface YorkWallcoveringsAddToCartHandoff {
17833
+ sku: string;
17834
+ name: string;
17835
+ url: string;
17836
+ price: number;
17837
+ inStock: boolean;
17838
+ note: string;
17839
+ }
17840
+
17841
+ /**
17842
+ * Reads York Wallcoverings' public wallpaper/mural storefront (yorkwallcoverings.com) — search
17843
+ * the catalog by keyword, read a product's live price and stock, and get the handoff to add it
17844
+ * to cart on the real site.
17845
+ */
17846
+ interface Unit {
17847
+ /**
17848
+ * Searches York's live public catalog (wallpaper, wall murals, grasscloth) by keyword — theme,
17849
+ * style, color or brand words all match, since the site's own search covers name and
17850
+ * description — and returns each match's SKU, name, product URL and price.
17851
+ */
17852
+ search(query: string): Promise<YorkWallcoveringsSearchResult[]>;
17853
+
17854
+ /**
17855
+ * Reads one York product page in full — SKU, live price, in-stock/out-of-stock status,
17856
+ * description and images — for a product URL `search` already returned.
17857
+ */
17858
+ getProduct(url: string): Promise<YorkWallcoveringsProduct>;
17859
+
17860
+ /**
17861
+ * Hands back the shopper's own York product page — the exact Add to cart button for this SKU —
17862
+ * since the site's cart requires a per-session ASP.NET token nobody but the shopper can
17863
+ * supply. Writes nothing.
17864
+ */
17865
+ addToCart(url: string): Promise<YorkWallcoveringsAddToCartHandoff>;
17866
+ }
17867
+ }
17868
+
15822
17869
  declare namespace BowmarkProvider_yourarborhome {
15823
17870
  // ── Arbor Homes — the unit's own declarations, verbatim ──
15824
17871
  interface ArborHome {
@@ -15870,6 +17917,57 @@ interface SearchHomesFilters {
15870
17917
  }
15871
17918
  }
15872
17919
 
17920
+ declare namespace BowmarkProvider_zennioptical {
17921
+ // ── Zenni Optical — the unit's own declarations, verbatim ──
17922
+ interface ZenniFrame {
17923
+ sku: string;
17924
+ name: string;
17925
+ price: number;
17926
+ colors: Array<{ sku: string; price: number }>;
17927
+ }
17928
+ interface ZenniStock {
17929
+ skuId: string;
17930
+ inStock: boolean;
17931
+ quantity: number;
17932
+ backOrderable: boolean;
17933
+ preOrderable: boolean;
17934
+ }
17935
+ interface ZenniRx {
17936
+ odSph: number;
17937
+ osSph: number;
17938
+ pd: number;
17939
+ birthYear: number;
17940
+ }
17941
+ interface ZenniLensPriceRow {
17942
+ type: string;
17943
+ minPrice: number;
17944
+ maxPrice: number;
17945
+ subTypes: Array<{ type: string; usage: string; minPrice: number; maxPrice: number; tints: boolean }>;
17946
+ }
17947
+
17948
+ /**
17949
+ * Online prescription eyewear. Prices a real frame + Rx + lens-type configuration off the
17950
+ * site's own configurator, and checks live per-SKU stock.
17951
+ */
17952
+ interface Unit {
17953
+ /**
17954
+ * Reads one frame's name, base price and per-color-variant price straight off the product
17955
+ * page's own embedded data. No rendering.
17956
+ */
17957
+ getFrame(skuId: string): Promise<ZenniFrame>;
17958
+
17959
+ /** Checks live per-SKU inventory off Zenni's own inventory endpoint. */
17960
+ checkStock(skuId: string): Promise<ZenniStock>;
17961
+
17962
+ /**
17963
+ * Runs a real prescription through Zenni's own order-configurator wizard (usage type -> manual
17964
+ * Rx entry -> confirm) and returns the priced lens-type matrix the site computes for that
17965
+ * exact Rx — a completed, priced configuration rather than a base frame price.
17966
+ */
17967
+ priceLensConfig(skuId: string, rx: ZenniRx): Promise<ZenniLensPriceRow[]>;
17968
+ }
17969
+ }
17970
+
15873
17971
  declare namespace BowmarkFamily_shopify_store {
15874
17972
  // ── Shopify storefronts — the unit's own declarations, verbatim ──
15875
17973
  interface ShopifyVariant {
@@ -16692,26 +18790,32 @@ interface BowmarkProviders {
16692
18790
  aiper: BowmarkProvider_aiper.Unit;
16693
18791
  ajmadison: BowmarkProvider_ajmadison.Unit;
16694
18792
  ashleyfurniture: BowmarkProvider_ashleyfurniture.Unit;
18793
+ asppoolco: BowmarkProvider_asppoolco.Unit;
18794
+ atlasoceanvoyages: BowmarkProvider_atlasoceanvoyages.Unit;
16695
18795
  atlasseniorliving: BowmarkProvider_atlasseniorliving.Unit;
16696
18796
  avis: BowmarkProvider_avis.Unit;
16697
18797
  azure: BowmarkProvider_azure.Unit;
16698
18798
  barletta: BowmarkProvider_barletta.Unit;
16699
18799
  bhphoto: BowmarkProvider_bhphoto.Unit;
16700
18800
  bigrentz: BowmarkProvider_bigrentz.Unit;
18801
+ bing: BowmarkProvider_bing.Unit;
16701
18802
  blenderseyewear: BowmarkProvider_blenderseyewear.Unit;
16702
18803
  bluehaven: BowmarkProvider_bluehaven.Unit;
16703
18804
  bmwusa: BowmarkProvider_bmwusa.Unit;
16704
18805
  boydsleep: BowmarkProvider_boydsleep.Unit;
18806
+ brixton: BowmarkProvider_brixton.Unit;
16705
18807
  bykoket: BowmarkProvider_bykoket.Unit;
16706
18808
  cancer: BowmarkProvider_cancer.Unit;
16707
18809
  caraway: BowmarkProvider_caraway.Unit;
16708
18810
  cars: BowmarkProvider_cars.Unit;
18811
+ chantecaille: BowmarkProvider_chantecaille.Unit;
16709
18812
  cheapflights: BowmarkProvider_cheapflights.Unit;
16710
18813
  chriscraft: BowmarkProvider_chriscraft.Unit;
16711
18814
  classichome: BowmarkProvider_classichome.Unit;
16712
18815
  classpass: BowmarkProvider_classpass.Unit;
16713
18816
  cloudflare: BowmarkProvider_cloudflare.Unit;
16714
18817
  cyberpowerpc: BowmarkProvider_cyberpowerpc.Unit;
18818
+ davidsonhomes: BowmarkProvider_davidsonhomes.Unit;
16715
18819
  decked: BowmarkProvider_decked.Unit;
16716
18820
  dice: BowmarkProvider_dice.Unit;
16717
18821
  dickssportinggoods: BowmarkProvider_dickssportinggoods.Unit;
@@ -16720,10 +18824,13 @@ interface BowmarkProviders {
16720
18824
  embroker: BowmarkProvider_embroker.Unit;
16721
18825
  erieinsurance: BowmarkProvider_erieinsurance.Unit;
16722
18826
  eventsource: BowmarkProvider_eventsource.Unit;
18827
+ evolutionofsmooth: BowmarkProvider_evolutionofsmooth.Unit;
16723
18828
  extraspace: BowmarkProvider_extraspace.Unit;
16724
18829
  firstdibs: BowmarkProvider_firstdibs.Unit;
18830
+ fivestarbathsolutions: BowmarkProvider_fivestarbathsolutions.Unit;
16725
18831
  flightradar24: BowmarkProvider_flightradar24.Unit;
16726
18832
  ford: BowmarkProvider_ford.Unit;
18833
+ fourseasonsyachts: BowmarkProvider_fourseasonsyachts.Unit;
16727
18834
  framebridge: BowmarkProvider_framebridge.Unit;
16728
18835
  fred: BowmarkProvider_fred.Unit;
16729
18836
  geico: BowmarkProvider_geico.Unit;
@@ -16732,13 +18839,16 @@ interface BowmarkProviders {
16732
18839
  grainger: BowmarkProvider_grainger.Unit;
16733
18840
  grandwelcome: BowmarkProvider_grandwelcome.Unit;
16734
18841
  handypro: BowmarkProvider_handypro.Unit;
18842
+ hansons: BowmarkProvider_hansons.Unit;
16735
18843
  harmar: BowmarkProvider_harmar.Unit;
16736
18844
  hauslabs: BowmarkProvider_hauslabs.Unit;
18845
+ haydenhomes: BowmarkProvider_haydenhomes.Unit;
16737
18846
  healthcare_gov: BowmarkProvider_healthcare_gov.Unit;
16738
18847
  hellofresh: BowmarkProvider_hellofresh.Unit;
16739
18848
  hellotend: BowmarkProvider_hellotend.Unit;
16740
18849
  hilton: BowmarkProvider_hilton.Unit;
16741
18850
  hobie: BowmarkProvider_hobie.Unit;
18851
+ holidaybuilders: BowmarkProvider_holidaybuilders.Unit;
16742
18852
  hunter: BowmarkProvider_hunter.Unit;
16743
18853
  ibuypower: BowmarkProvider_ibuypower.Unit;
16744
18854
  insurify: BowmarkProvider_insurify.Unit;
@@ -16746,31 +18856,39 @@ interface BowmarkProviders {
16746
18856
  islllc: BowmarkProvider_islllc.Unit;
16747
18857
  jennikayne: BowmarkProvider_jennikayne.Unit;
16748
18858
  joybird: BowmarkProvider_joybird.Unit;
18859
+ joycefactorydirect: BowmarkProvider_joycefactorydirect.Unit;
18860
+ justinwine: BowmarkProvider_justinwine.Unit;
16749
18861
  kayak: BowmarkProvider_kayak.Unit;
18862
+ kingsdown: BowmarkProvider_kingsdown.Unit;
16750
18863
  kitchentuneup: BowmarkProvider_kitchentuneup.Unit;
16751
18864
  kompan: BowmarkProvider_kompan.Unit;
18865
+ kuiu: BowmarkProvider_kuiu.Unit;
16752
18866
  labcorp: BowmarkProvider_labcorp.Unit;
16753
18867
  linkedin: BowmarkProvider_linkedin.Unit;
16754
18868
  liquiddeath: BowmarkProvider_liquiddeath.Unit;
16755
18869
  lonelyplanet: BowmarkProvider_lonelyplanet.Unit;
16756
18870
  louvershop: BowmarkProvider_louvershop.Unit;
18871
+ lovelybride: BowmarkProvider_lovelybride.Unit;
16757
18872
  lufthansa: BowmarkProvider_lufthansa.Unit;
16758
18873
  lululemon: BowmarkProvider_lululemon.Unit;
16759
18874
  maidenhome: BowmarkProvider_maidenhome.Unit;
16760
18875
  mailchimp: BowmarkProvider_mailchimp.Unit;
16761
18876
  marriott: BowmarkProvider_marriott.Unit;
16762
18877
  mcdonalds: BowmarkProvider_mcdonalds.Unit;
18878
+ medicalguardian: BowmarkProvider_medicalguardian.Unit;
16763
18879
  medicare: BowmarkProvider_medicare.Unit;
16764
18880
  microcenter: BowmarkProvider_microcenter.Unit;
16765
18881
  minted: BowmarkProvider_minted.Unit;
16766
18882
  mixbook: BowmarkProvider_mixbook.Unit;
16767
18883
  modularclosets: BowmarkProvider_modularclosets.Unit;
16768
18884
  momondo: BowmarkProvider_momondo.Unit;
18885
+ mossyoak: BowmarkProvider_mossyoak.Unit;
16769
18886
  naic: BowmarkProvider_naic.Unit;
16770
18887
  namecheap: BowmarkProvider_namecheap.Unit;
16771
18888
  newegg: BowmarkProvider_newegg.Unit;
16772
18889
  oanda: BowmarkProvider_oanda.Unit;
16773
18890
  otto: BowmarkProvider_otto.Unit;
18891
+ outdoorresearch: BowmarkProvider_outdoorresearch.Unit;
16774
18892
  paypal: BowmarkProvider_paypal.Unit;
16775
18893
  pirateship: BowmarkProvider_pirateship.Unit;
16776
18894
  pizzahut: BowmarkProvider_pizzahut.Unit;
@@ -16778,13 +18896,20 @@ interface BowmarkProviders {
16778
18896
  progressive: BowmarkProvider_progressive.Unit;
16779
18897
  prose: BowmarkProvider_prose.Unit;
16780
18898
  reddit: BowmarkProvider_reddit.Unit;
18899
+ reliancepartners: BowmarkProvider_reliancepartners.Unit;
18900
+ revisionskincare: BowmarkProvider_revisionskincare.Unit;
18901
+ rishitea: BowmarkProvider_rishitea.Unit;
16781
18902
  ritani: BowmarkProvider_ritani.Unit;
16782
18903
  roofmaxx: BowmarkProvider_roofmaxx.Unit;
18904
+ saatva: BowmarkProvider_saatva.Unit;
18905
+ saltandstone: BowmarkProvider_saltandstone.Unit;
16783
18906
  samsclub: BowmarkProvider_samsclub.Unit;
18907
+ seakeeper: BowmarkProvider_seakeeper.Unit;
16784
18908
  sears: BowmarkProvider_sears.Unit;
16785
18909
  seegarsfence: BowmarkProvider_seegarsfence.Unit;
16786
18910
  selectblinds: BowmarkProvider_selectblinds.Unit;
16787
18911
  semihandmade: BowmarkProvider_semihandmade.Unit;
18912
+ smartsign: BowmarkProvider_smartsign.Unit;
16788
18913
  soundcloud: BowmarkProvider_soundcloud.Unit;
16789
18914
  statefarm: BowmarkProvider_statefarm.Unit;
16790
18915
  stickergiant: BowmarkProvider_stickergiant.Unit;
@@ -16793,8 +18918,11 @@ interface BowmarkProviders {
16793
18918
  target: BowmarkProvider_target.Unit;
16794
18919
  tatcha: BowmarkProvider_tatcha.Unit;
16795
18920
  teladoc: BowmarkProvider_teladoc.Unit;
18921
+ teneohg: BowmarkProvider_teneohg.Unit;
16796
18922
  therabody: BowmarkProvider_therabody.Unit;
16797
18923
  thezebra: BowmarkProvider_thezebra.Unit;
18924
+ tilsonhomes: BowmarkProvider_tilsonhomes.Unit;
18925
+ titlenine: BowmarkProvider_titlenine.Unit;
16798
18926
  topviewtix: BowmarkProvider_topviewtix.Unit;
16799
18927
  trektravel: BowmarkProvider_trektravel.Unit;
16800
18928
  twiddy: BowmarkProvider_twiddy.Unit;
@@ -16804,10 +18932,14 @@ interface BowmarkProviders {
16804
18932
  villagerealtyobx: BowmarkProvider_villagerealtyobx.Unit;
16805
18933
  visible: BowmarkProvider_visible.Unit;
16806
18934
  voluspa: BowmarkProvider_voluspa.Unit;
18935
+ walkerhughes: BowmarkProvider_walkerhughes.Unit;
16807
18936
  walmart: BowmarkProvider_walmart.Unit;
18937
+ waterfurnace: BowmarkProvider_waterfurnace.Unit;
16808
18938
  wellfound: BowmarkProvider_wellfound.Unit;
16809
18939
  xpresswellnessurgentcare: BowmarkProvider_xpresswellnessurgentcare.Unit;
18940
+ yorkwallcoverings: BowmarkProvider_yorkwallcoverings.Unit;
16810
18941
  yourarborhome: BowmarkProvider_yourarborhome.Unit;
18942
+ zennioptical: BowmarkProvider_zennioptical.Unit;
16811
18943
  "000de82": BowmarkFamily_shopify_store.Unit;
16812
18944
  "001r3iv0": BowmarkFamily_shopify_store.Unit;
16813
18945
  "00246d8e": BowmarkFamily_shopify_store.Unit;
@@ -68539,6 +70671,7 @@ interface BowmarkLibrary {
68539
70671
  music: BowmarkCapability_music.Unit;
68540
70672
  pcparts: BowmarkCapability_pcparts.Unit;
68541
70673
  read: BowmarkCapability_read.Unit;
70674
+ search: BowmarkCapability_search.Unit;
68542
70675
  sheds: BowmarkCapability_sheds.Unit;
68543
70676
  providers: BowmarkProviders;
68544
70677
  }