Files
jakevin eb59b7444d feat(ctrip): add hotel-search + flight browser-mode commands (#1481) (#1489)
* feat(ctrip): add hotel-search + flight browser-mode commands

Closes #1481.

Two new browser-mode commands on top of the existing public `search` /
`hotel-suggest` pair:

- `ctrip hotel-search <city> --checkin --checkout [--limit]` reads
  `window.__NEXT_DATA__.props.pageProps.initListData.hotelList` on
  `hotels.ctrip.com/hotels/list`. SSR-rendered first page ships ~13
  entries; the server ignores `&pageSize=N` so limit caps at 30 with
  default 10. AuthRequiredError surfaces when Ctrip redirects to the
  captcha gate.

- `ctrip flight <from> <to> --date [--limit]` searches one-way flights on
  `flights.ctrip.com/online/list/oneway-…`. The post-load XHR is not
  currently captured by the daemon network buffer (per the known
  daemon_capture_pipeline_bug_2026_05_07 in agent memory), so rows are
  pulled from `.flight-list > span > div` cards via a position-anchored
  innerText parser. A generic `buildScrollUntilJs(selector, target)`
  helper mirrors the PR #1487 xiaohongshu scroll-until pattern with the
  selector parameterised. Round-trip + airline filters are out of scope
  for v1.

All argument validation (IATA / ISO date / city ID / limit range) fires
upfront before any `page.goto`, per the PR #1387 boundary standard. No
silent clamps, no sentinel rows: rows missing required fields are
dropped, and end-state checks raise `ArgumentError` /
`AuthRequiredError` / `EmptyResultError` as appropriate. The new
`mapHotelRow` / `pickHotelMapCoords` / `buildFlightExtractJs` /
`buildScrollUntilJs` helpers live in `clis/ctrip/utils.js` alongside the
existing suggest helpers.

Docs at `docs/adapters/browser/ctrip.md` now distinguish the public
suggest commands from the browser-mode commands and document each
command's columns + caveats.

Verified:
- 61/61 vitest tests in `clis/ctrip/ctrip.test.js` (including JSDOM
  exercises of `buildFlightExtractJs` and full `mapHotelRow` shape parity)
- `check:typed-error-lint` 189/189 (0 new)
- `check:silent-column-drop` 103/103 (0 new)
- `build-manifest` clean — 812 entries total (was 810)

* fix(ctrip): harden browser search failure contracts

* fix(ctrip): tighten browser empty-vs-parser failures
2026-05-12 03:43:32 +08:00
..