@curless/hotel-storefront 0.46.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,31 @@
1
- /** In the order a chip row shows them. */
2
- export const ROOM_FILTER_KEYS = [
1
+ /**
2
+ * The four a hotel's chip row ALWAYS has - a guest looks for these on every
3
+ * hotel, and a chip that is gone says nothing, where one marked 0 says the
4
+ * hotel has none (robin, 2026-10-23).
5
+ */
6
+ export const CORE_FILTER_KEYS = [
3
7
  'breakfast',
4
8
  'king',
5
9
  'twin',
6
10
  'freeCancellation',
7
11
  ];
12
+ /**
13
+ * The ones that are offered only where a hotel's rooms DIFFER in them: a chip
14
+ * for a window every room has (or none has) narrows nothing.
15
+ */
16
+ export const SPLIT_FILTER_KEYS = [
17
+ 'window',
18
+ 'payAtHotel',
19
+ 'payOnline',
20
+ 'family',
21
+ ];
22
+ /** In the order a chip row shows them. */
23
+ export const ROOM_FILTER_KEYS = [
24
+ ...CORE_FILTER_KEYS,
25
+ ...SPLIT_FILTER_KEYS,
26
+ ];
27
+ /** A room that sleeps this many is a family room: 家庭房, "Sleeps 3+". */
28
+ export const FAMILY_SLEEPS = 3;
8
29
  /**
9
30
  * Two ways of reading a bed in words. A QUEEN COUNTS WITH THE KING: "king" is
10
31
  * the large-bed filter - one big bed for two, which is what a guest who says
@@ -119,7 +140,14 @@ export const breakfastOf = (room) => {
119
140
  * way). A room by the hour has no cancellation terms to speak of.
120
141
  */
121
142
  export const freeCancellationOf = (room) => !room.hourly && room.refundable && !!room.freeCancellationUntil;
122
- /** Everything a card needs to know about one room to filter it. */
143
+ /**
144
+ * Everything a card needs to know about one room to filter it.
145
+ *
146
+ * ⚠️ A WINDOW IS 'yes' AND NOTHING ELSE (robin, 2026-10-23): a partly-windowed
147
+ * room, an inner window onto a light well, a room with none, and a room whose
148
+ * data says nothing are not "has a window". A room that says nothing of how it
149
+ * is paid is neither at the hotel nor online - the card does not guess.
150
+ */
123
151
  export const facetsOf = (room) => {
124
152
  const beds = bedKindsOf(room);
125
153
  return {
@@ -127,49 +155,82 @@ export const facetsOf = (room) => {
127
155
  king: beds.king,
128
156
  twin: beds.twin,
129
157
  freeCancellation: freeCancellationOf(room),
158
+ window: room.window === 'yes',
159
+ payAtHotel: room.payment === 'at-hotel',
160
+ payOnline: room.payment === 'prepaid',
161
+ family: room.sleeps >= FAMILY_SLEEPS,
130
162
  };
131
163
  };
132
- /** The terms a call asked for, or undefined when it asked for none. Only `true` narrows. */
164
+ /** The terms a call asked for, or undefined when it asked for none. Only `true` (or a payment given) narrows. */
133
165
  export const roomTermsOf = (args) => {
134
166
  const terms = {
135
167
  ...(args.bed === 'king' || args.bed === 'twin' ? { bed: args.bed } : {}),
136
168
  ...(args.breakfast === true ? { breakfast: true } : {}),
137
169
  ...(args.freeCancellation === true ? { freeCancellation: true } : {}),
170
+ ...(args.window === true ? { window: true } : {}),
171
+ ...(args.payment === 'at-hotel' || args.payment === 'online' ? { payment: args.payment } : {}),
172
+ ...(args.family === true ? { family: true } : {}),
138
173
  };
139
174
  return Object.keys(terms).length ? terms : undefined;
140
175
  };
176
+ /** Whether the terms switch this chip on. The two beds, and the two ways to pay, are one choice each. */
177
+ const termsHave = (terms, k) => {
178
+ if (!terms)
179
+ return false;
180
+ switch (k) {
181
+ case 'king':
182
+ case 'twin':
183
+ return terms.bed === k;
184
+ case 'payAtHotel':
185
+ return terms.payment === 'at-hotel';
186
+ case 'payOnline':
187
+ return terms.payment === 'online';
188
+ default:
189
+ return !!terms[k];
190
+ }
191
+ };
141
192
  /** The terms as the chip keys they switch on - the order a chip row shows them. */
142
- export const activeKeysOf = (terms) => ROOM_FILTER_KEYS.filter((k) => k === 'king' || k === 'twin'
143
- ? terms?.bed === k
144
- : !!terms?.[k]);
193
+ export const activeKeysOf = (terms) => ROOM_FILTER_KEYS.filter((k) => termsHave(terms, k));
145
194
  /** Whether a room has everything the terms ask for. */
146
195
  export const matchesTerms = (room, terms) => {
147
196
  if (!terms)
148
197
  return true;
149
198
  const f = facetsOf(room);
150
- return ((!terms.bed || f[terms.bed]) &&
151
- (!terms.breakfast || f.breakfast) &&
152
- (!terms.freeCancellation || f.freeCancellation));
199
+ return activeKeysOf(terms).every((k) => f[k]);
153
200
  };
154
201
  /**
155
- * The chips a hotel's rooms offer: only a kind at least one room has, each with
156
- * how many rooms (rates) it keeps on its own, in the order a chip row shows
157
- * them.
202
+ * The chips a hotel's rooms offer, each with how many rooms (rates) it keeps
203
+ * on its own, in the order a chip row shows them.
204
+ *
205
+ * ⚠️ THE CORE FOUR ARE ALWAYS HERE, even at 0: a hotel with no twin room says
206
+ * so, and the card draws that chip empty and pressable. The rest are here ONLY
207
+ * WHERE THEY SPLIT the hotel's rooms - some have it and some do not. A window
208
+ * every room has, or none does, narrows nothing, and a row of chips that do
209
+ * nothing is noise.
158
210
  */
159
211
  export const optionsOf = (rooms) => {
160
212
  const all = rooms.map(facetsOf);
161
- return ROOM_FILTER_KEYS.map((key) => ({ key, count: all.filter((f) => f[key]).length })).filter((o) => o.count > 0);
213
+ return ROOM_FILTER_KEYS.map((key) => ({ key, count: all.filter((f) => f[key]).length })).filter((o) => CORE_FILTER_KEYS.includes(o.key) || (o.count > 0 && o.count < all.length));
214
+ };
215
+ const KEY_WORDS = {
216
+ breakfast: 'breakfast included',
217
+ king: 'king bed',
218
+ twin: 'twin beds',
219
+ freeCancellation: 'free cancellation',
220
+ window: 'a window',
221
+ payAtHotel: 'payment at the hotel',
222
+ payOnline: 'payment online',
223
+ family: `room for ${FAMILY_SLEEPS} or more`,
162
224
  };
225
+ const isBedKey = (k) => k === 'king' || k === 'twin';
163
226
  /** The terms in words, for a sentence: "king bed, breakfast included, free cancellation". */
164
- export const termWords = (terms) => [
165
- terms.bed === 'king' ? 'king bed' : terms.bed === 'twin' ? 'twin beds' : '',
166
- terms.breakfast ? 'breakfast included' : '',
167
- terms.freeCancellation ? 'free cancellation' : '',
168
- ]
169
- .filter(Boolean)
227
+ export const termWords = (terms) => activeKeysOf(terms)
228
+ // The sentence has always said the bed first.
229
+ .sort((a, b) => Number(!isBedKey(a)) - Number(!isBedKey(b)))
230
+ .map((k) => KEY_WORDS[k])
170
231
  .join(', ');
171
232
  /** One chip in words, for a sentence. */
172
- export const keyWords = (key) => termWords(key === 'king' ? { bed: 'king' } : key === 'twin' ? { bed: 'twin' } : { [key]: true });
233
+ export const keyWords = (key) => KEY_WORDS[key];
173
234
  /**
174
235
  * A hotel's rooms by room type, in the order the types first appear: a group
175
236
  * that sells several rates on one type (Huazhu's 房型 × 房价码) shares a
@@ -1 +1 @@
1
- {"version":3,"file":"room-filters.js","sourceRoot":"","sources":["../src/room-filters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room-filters.js","sourceRoot":"","sources":["../src/room-filters.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -28,7 +28,7 @@ export declare const INITIALIZE_PER_MINUTE = 300;
28
28
  * number. Found by reading the boot banner of a container that had just been
29
29
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
30
30
  */
31
- export declare const VERSION = "0.46.0";
31
+ export declare const VERSION = "0.47.0";
32
32
  /**
33
33
  * The card's resource URI.
34
34
  *
@@ -37,7 +37,7 @@ export declare const VERSION = "0.46.0";
37
37
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
38
38
  * this reason.
39
39
  */
40
- export declare const CARD_URI = "ui://curless/hotel/booking-v87.html";
40
+ export declare const CARD_URI = "ui://curless/hotel/booking-v88.html";
41
41
  /**
42
42
  * The URI one deployment names its card by: `CARD_URI` with a short hash of
43
43
  * everything a host caches under it - the card itself, and the hosts it may
package/dist/server.js CHANGED
@@ -47,7 +47,7 @@ export const INITIALIZE_PER_MINUTE = 300;
47
47
  * number. Found by reading the boot banner of a container that had just been
48
48
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
49
49
  */
50
- export const VERSION = '0.46.0';
50
+ export const VERSION = '0.47.0';
51
51
  /**
52
52
  * The card's resource URI.
53
53
  *
@@ -56,7 +56,7 @@ export const VERSION = '0.46.0';
56
56
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
57
57
  * this reason.
58
58
  */
59
- export const CARD_URI = 'ui://curless/hotel/booking-v87.html';
59
+ export const CARD_URI = 'ui://curless/hotel/booking-v88.html';
60
60
  /** The card as it ships, hashed once - what a host caches under the URI. */
61
61
  const CARD_HTML_SHA = createHash('sha256').update(HOTEL_CARD_HTML).digest('hex');
62
62
  /**
package/dist/tools.d.ts CHANGED
@@ -110,7 +110,7 @@ export declare const buildTools: (n: ToolNames, v: Vocabulary, caps?: BackendCap
110
110
  };
111
111
  } | {
112
112
  readonly name: `get_${string}${string}`;
113
- readonly description: `One ${string} in full: description, amenities, address, and check-in and check-out times where the ${string} publishes them. Given \`checkIn\` and \`checkOut\` it also returns the room types that can be booked for those nights, one line per type at its lowest rate: the nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many rates it has. \`rooms\` leaves out the types that have fewer than that many left. \`bed\`, \`breakfast\` and \`freeCancellation\` keep only the rates that meet all of those given; the card still holds every room, with the given filters selected. Without dates it returns the ${string} only, because a room has no price until the nights are known. The ${string} is drawn as a card for the guest to look at.${string}`;
113
+ readonly description: `One ${string} in full: description, amenities, address, and check-in and check-out times where the ${string} publishes them. Given \`checkIn\` and \`checkOut\` it also returns the room types that can be booked for those nights, one line per type at its lowest rate: the nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many rates it has. \`rooms\` leaves out the types that have fewer than that many left. \`bed\`, \`breakfast\`, \`freeCancellation\`, \`window\`, \`payment\` and \`family\` keep only the rates that meet all of those given; the card still holds every room, with the given filters selected. Without dates it returns the ${string} only, because a room has no price until the nights are known. The ${string} is drawn as a card for the guest to look at.${string}`;
114
114
  readonly annotations: {
115
115
  readonly title: string;
116
116
  readonly readOnlyHint: true;
@@ -140,6 +140,19 @@ export declare const buildTools: (n: ToolNames, v: Vocabulary, caps?: BackendCap
140
140
  readonly type: "boolean";
141
141
  readonly description: "With dates: only rooms that can be cancelled free";
142
142
  };
143
+ readonly window: {
144
+ readonly type: "boolean";
145
+ readonly description: "With dates: only rooms with a window (not a partial or an inner one)";
146
+ };
147
+ readonly payment: {
148
+ readonly type: "string";
149
+ readonly enum: readonly ["at-hotel", "online"];
150
+ readonly description: "With dates: only rooms paid at the hotel (`at-hotel`) or in advance online (`online`)";
151
+ };
152
+ readonly family: {
153
+ readonly type: "boolean";
154
+ readonly description: "With dates: only rooms that sleep 3 or more";
155
+ };
143
156
  readonly checkIn: {
144
157
  readonly type: "string";
145
158
  readonly pattern: "^\\d{4}-\\d{2}-\\d{2}$";
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -339,7 +339,7 @@ const allTools = (n, v) => {
339
339
  },
340
340
  {
341
341
  name: n.getHotel,
342
- description: `One ${v.noun} in full: description, amenities, address, and check-in and check-out times where the ${v.noun} publishes them. Given \`checkIn\` and \`checkOut\` it also returns the room types that can be booked for those nights, one line per type at its lowest rate: the nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many rates it has. \`rooms\` leaves out the types that have fewer than that many left. \`bed\`, \`breakfast\` and \`freeCancellation\` keep only the rates that meet all of those given; the card still holds every room, with the given filters selected. Without dates it returns the ${v.noun} only, because a room has no price until the nights are known. The ${v.noun} is drawn as a card for the guest to look at.${v.hints.hotel ? ` ${v.hints.hotel}` : ''}`,
342
+ description: `One ${v.noun} in full: description, amenities, address, and check-in and check-out times where the ${v.noun} publishes them. Given \`checkIn\` and \`checkOut\` it also returns the room types that can be booked for those nights, one line per type at its lowest rate: the nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many rates it has. \`rooms\` leaves out the types that have fewer than that many left. \`bed\`, \`breakfast\`, \`freeCancellation\`, \`window\`, \`payment\` and \`family\` keep only the rates that meet all of those given; the card still holds every room, with the given filters selected. Without dates it returns the ${v.noun} only, because a room has no price until the nights are known. The ${v.noun} is drawn as a card for the guest to look at.${v.hints.hotel ? ` ${v.hints.hotel}` : ''}`,
343
343
  annotations: reads(`View one ${catalogue(v, true)}`, open),
344
344
  inputSchema: {
345
345
  type: 'object',
@@ -368,6 +368,19 @@ const allTools = (n, v) => {
368
368
  type: 'boolean',
369
369
  description: 'With dates: only rooms that can be cancelled free',
370
370
  },
371
+ window: {
372
+ type: 'boolean',
373
+ description: 'With dates: only rooms with a window (not a partial or an inner one)',
374
+ },
375
+ payment: {
376
+ type: 'string',
377
+ enum: ['at-hotel', 'online'],
378
+ description: 'With dates: only rooms paid at the hotel (`at-hotel`) or in advance online (`online`)',
379
+ },
380
+ family: {
381
+ type: 'boolean',
382
+ description: 'With dates: only rooms that sleep 3 or more',
383
+ },
371
384
  },
372
385
  required: ['hotel'],
373
386
  },
@@ -1050,12 +1063,22 @@ const HOTEL_PAGE = {
1050
1063
  dates: ARR,
1051
1064
  /**
1052
1065
  * The room filters this hotel's rooms offer, each with how many rooms (rates)
1053
- * it keeps - `{ key: 'breakfast' | 'king' | 'twin' | 'freeCancellation', count }`.
1054
- * Only a kind at least one room has.
1066
+ * it keeps - `{ key, count }`, `key` one of `breakfast`, `king`, `twin`,
1067
+ * `freeCancellation` (always here, `count` 0 where no room has it) and
1068
+ * `window`, `payAtHotel`, `payOnline`, `family` (here only where some rooms
1069
+ * have it and some do not).
1055
1070
  */
1056
1071
  roomFilters: ARR,
1057
1072
  /** The filters the call asked for, as the same keys - the card opens with these selected. */
1058
1073
  activeFilters: STRS,
1074
+ /**
1075
+ * Room types with no room to book for these nights (none left, or fewer
1076
+ * than the rooms asked for): `{ id, name, names?, sleeps, ..., left? }`, no
1077
+ * price. The card draws them muted at the end of the list, so a type the
1078
+ * guest saw is said to be sold out and not left out. Absent where there are
1079
+ * none - and never in what the assistant is told.
1080
+ */
1081
+ soldOut: ARR,
1059
1082
  };
1060
1083
  export const buildOutputSchemas = (n) => ({
1061
1084
  [n.listHotels]: {
@@ -1173,6 +1196,8 @@ export const buildOutputSchemas = (n) => ({
1173
1196
  accessibility: BOOL,
1174
1197
  /** One per stay, when the trip held several. */
1175
1198
  bookings: ARR,
1199
+ /** What all of `bookings` come to, where they are in one currency (the card's first screen). */
1200
+ totalAll: STR,
1176
1201
  /**
1177
1202
  * The stays that could not be booked when the others were - each with
1178
1203
  * why, still in the trip, and what could be booked instead (robin,
@@ -2068,7 +2093,7 @@ when, enough, roomsWanted, terms) => {
2068
2093
  ...roomTypeLines(rs, roomsWanted, terms),
2069
2094
  ...(byRoomType(rs).some((t) => t.rooms.length > 1)
2070
2095
  ? [
2071
- 'A type with several rates is priced from its cheapest one; bed, breakfast and freeCancellation narrow to the others (the card lists every rate).',
2096
+ 'A type with several rates is priced from its cheapest one; bed, breakfast, freeCancellation, window, payment and family narrow to the others (the card lists every rate).',
2072
2097
  ]
2073
2098
  : []),
2074
2099
  ];
@@ -2221,6 +2246,52 @@ const dateFlex = (dates, stay) => {
2221
2246
  text: `Arriving ${beats.checkIn} instead is ${formatMoney(saved)} less for ${sameNights}.`,
2222
2247
  };
2223
2248
  };
2249
+ /**
2250
+ * The room types a guest can no longer book on these nights - for the card to
2251
+ * say so, and not leave them out (r10 #10: a type the guest saw earlier
2252
+ * vanished from the list, and the heading counted one fewer, without a word).
2253
+ *
2254
+ * ⚠️ AN ADDITIVE FIELD, NEVER THE TEXT. What the assistant is told is the rooms
2255
+ * that can be booked, as before; this is only what the card draws, muted, at
2256
+ * the end of the list. A type is listed when
2257
+ * - the backend sends it with none left (`HotelDetail.soldOut`, or a room with
2258
+ * `roomsLeft: 0`), or
2259
+ * - it has some left, but fewer than the rooms asked for (`left`): a guest who
2260
+ * asked for two rooms and was shown no type with one left was not told why.
2261
+ * Not a type that sleeps fewer than the party (the backend never sends it), and
2262
+ * not a type any of whose rates can be booked. One entry a type, with the facts
2263
+ * the card says of a room and no price.
2264
+ */
2265
+ const soldOutTypesOf = (detail, enough, wanted) => {
2266
+ const key = (r) => r.roomType?.id ?? r.id;
2267
+ const open = new Set(enough.map(key));
2268
+ const types = new Map();
2269
+ for (const r of [...(detail.rooms ?? []), ...(detail.soldOut ?? [])]) {
2270
+ if (r.hourly || open.has(key(r)) || r.roomsLeft >= wanted)
2271
+ continue;
2272
+ const seen = types.get(key(r));
2273
+ if (seen)
2274
+ seen.left = Math.max(seen.left, r.roomsLeft);
2275
+ else
2276
+ types.set(key(r), { room: r, left: r.roomsLeft });
2277
+ }
2278
+ return [...types.entries()].map(([id, { room: r, left }]) => ({
2279
+ id,
2280
+ name: r.roomType?.name ?? r.name,
2281
+ ...((r.roomType?.names ?? r.names) ? { names: r.roomType?.names ?? r.names } : {}),
2282
+ sleeps: r.sleeps,
2283
+ ...(r.maxChildren ? { maxChildren: r.maxChildren } : {}),
2284
+ ...(r.sizeSqm ? { sizeSqm: r.sizeSqm } : {}),
2285
+ ...(r.beds ? { beds: r.beds } : {}),
2286
+ ...(r.bedTypes ? { bedTypes: r.bedTypes } : {}),
2287
+ ...(r.view ? { view: r.view } : {}),
2288
+ ...(r.window ? { window: r.window } : {}),
2289
+ ...(r.floor ? { floor: r.floor } : {}),
2290
+ ...(r.imageUrl ? { imageUrl: r.imageUrl } : {}),
2291
+ // Some left, but not as many as were asked for.
2292
+ ...(left > 0 ? { left } : {}),
2293
+ }));
2294
+ };
2224
2295
  const identity = (deps, ctx, key, args = {}) => {
2225
2296
  const email = str(args.email);
2226
2297
  const member = deps.members.read(key);
@@ -3329,6 +3400,7 @@ const answerTool = async (deps, name, rawArgs, ctx) => {
3329
3400
  // with what is true of each (`facets`), so a chip switched on or off on the
3330
3401
  // card needs no call to the server.
3331
3402
  const terms = roomTermsOf(args);
3403
+ const soldOut = soldOutTypesOf(detail, enough, roomsWanted);
3332
3404
  const rooms = enough.map((r) => ({
3333
3405
  ...r,
3334
3406
  facets: facetsOf(r),
@@ -3366,6 +3438,8 @@ const answerTool = async (deps, name, rawArgs, ctx) => {
3366
3438
  rooms_wanted: roomsWanted,
3367
3439
  roomFilters: optionsOf(enough),
3368
3440
  activeFilters: activeKeysOf(terms),
3441
+ // Types with no room to book for these nights, said and not left out.
3442
+ ...(byTheHour || !soldOut.length ? {} : { soldOut }),
3369
3443
  ...flex.structured,
3370
3444
  },
3371
3445
  text: [
@@ -4018,6 +4092,17 @@ const answerTool = async (deps, name, rawArgs, ctx) => {
4018
4092
  : {}),
4019
4093
  paid: false,
4020
4094
  ...(remembered ? { remembered: remembered.kept } : {}),
4095
+ // What they come to together, said by the server like every figure on
4096
+ // the card - never added up there (r10, #15). Only in one currency.
4097
+ ...(several &&
4098
+ booked.every(({ booking }) => booking.quote.total.currency === first.booking.quote.total.currency)
4099
+ ? {
4100
+ totalAll: formatMoney({
4101
+ minor: booked.reduce((n, { booking }) => n + booking.quote.total.minor, 0),
4102
+ currency: first.booking.quote.total.currency,
4103
+ }),
4104
+ }
4105
+ : {}),
4021
4106
  holdUntil: first.booking.holdUntil,
4022
4107
  total: formatMoney(first.booking.quote.total),
4023
4108
  ...(first.asked.length ? { requested: first.asked } : {}),