# flight-finder Reusable flight-search report skill for OpenClaw. It replaces the brittle one-off `dfw-blq-2026.md` prompt with typed intake, bounded source orchestration, explicit report gates, fixed-template PDF output, and Luke-sender email delivery. ## Core behavior `flight-finder` is designed to: - collect missing trip inputs explicitly instead of relying on hardcoded prompt prose - support split returns, flexible dates, passenger groups, and exclusions - use bounded search phases across KAYAK, Skyscanner, Expedia, and a best-effort airline direct cross-check - normalize pricing to USD before ranking - produce a report payload first, then render PDF/email only when the report is complete - behave safely on WhatsApp-style chat surfaces by treating status nudges as updates, not resets - require a fresh bounded search run for every report instead of reusing earlier captures ## Important rules - Recipient email is a delivery gate, not a search gate. - Cached flight-search data is forbidden as primary evidence for a new run. - same-day workspace captures must not be reused - previously rendered PDFs must not be treated as fresh search output - if fresh search fails, the skill must degrade honestly instead of recycling earlier artifacts - `marketCountry` is explicit-only in this implementation pass. - It must be an ISO 3166-1 alpha-2 uppercase code such as `TH` or `DE`. - If present, it activates VPN only for the bounded search phase. - If omitted, no VPN change happens. - If VPN connect or verification fails, the run falls back to the default market and records a degraded warning instead of hanging. - Direct-airline cross-checking is currently best-effort, not a hard blocker. ## Helper package From `skills/flight-finder/`: ```bash npm install npm run normalize-request -- --legacy-dfw-blq npm run normalize-request -- --input "" npm run report-status -- --input "" npm run render-report -- --input "" --output "" npm run delivery-plan -- --to "" --subject "" --body "" --attach "" ``` Expected report-payload provenance fields: - `searchExecution.freshSearch: true` - `searchExecution.startedAt` - `searchExecution.completedAt` - `searchExecution.artifactsRoot` ## Delivery - sender identity: `luke@fiorinis.com` - send path: - `zsh ~/.openclaw/workspace/bin/gog-luke gmail send --to "" --subject "" --body "" --attach ""` - if the user already provided the destination email, that counts as delivery authorization once the report is ready ## Source viability for implementation pass 1 Bounded checks on Stefano's MacBook Air showed: - `KAYAK`: viable - `Skyscanner`: viable - `Expedia`: viable - airline direct-booking cross-check: degraded / best-effort That means the first implementation pass should rely primarily on the three aggregator sources and treat direct-airline confirmation as additive evidence when it succeeds.