TripCheat · AI Trip Planner (trip-cheat-sheet)
Turn scattered flight/hotel screenshots, conference agendas, tickets, guide screenshots, and chat logs into a single mobile-friendly web page: Itinerary Timeline (where to go at what time), Checklists (what not to forget), Handbook (how to get around, how to pay, who to call in trouble).
It works immediately on your phone, supports dual timezones, dark theme, font adjustment, map deep links, QR ticket pages, and can be deployed to any static host.
The page is built by the skill's own generator from a single trip.json file. Data contract: references/trip-schema.md, writing rules: references/content-guide.md, deployment: references/deploy.md.
When to Use
Trigger Scenarios
- "Help me plan a trip" "Organize flights, hotels, conference agenda into one page" "Business trip / conference preparation"
- "Travel cheat sheet" "Companion page" "Travel handbook" "Packing list" "What to do each day"
- User provides screenshots / PDFs / emails / links / chat logs that need structuring + supplementary research + a browsable companion page
trip.jsonalready exists: need to regenerate the page, change theme, add a password gate, deploy, or share ticket pages
Not Suitable
- Only need attraction info, weather, or ticketing: just search/answer directly, no need for a page
- Need real-time inventory, booking, payment, or check-in: this skill does not connect to booking APIs; it only organizes information and links
- Pure route navigation: use a map tool; no need for a trip page
Output
| Mode | Command | Output |
|---|---|---|
| Single File (default) | node scripts/build.mjs trip.json --out dist | dist/index.html (CSS/JS/data/PWA manifest fully inlined) + on-demand copied ticket images |
| Multi-File Site | node scripts/build.mjs trip.json --multi --out dist | dist/index.html, dist/ticket-<id>.html, dist/assets/style.css, dist/assets/app.js, dist/manifest.json, copied ticket assets |
Page capabilities: Itinerary Timeline / Checklists / Handbook three views; "Current / Next Event" highlighting; dual-timezone clock & conversion; themes (paper/slate/night) & font size toggle; Google/Gaode/Apple Maps deep links (Google route links include transport mode parameter); checklist checking (localStorage); QR ticket pages; optional password gate (front-end SHA-256 verification); add to home screen (PWA, --no-pwa to disable).
Workflow (6 Steps)
Step 1: Gather Materials (Questionnaire + Files/Screenshots/Links)
Ask a round of questions first, at most 6, to avoid back-to-back questioning; for unanswered questions use default assumptions and explicitly mark them as "Assumption".
- Who is going, how many people, relationships (do companions need elderly/child/accessibility arrangements)
- Departure city, dates (including overnight/red-eye), destination(s) (multiple cities/transfers?)
- What is already booked vs still to book (flights, hotel, conference registration, tickets, restaurants)
- Key times for conference/events (registration, opening, own presentation/poster session, dinner)
- Preferences & non-negotiables (budget, dietary restrictions/allergies, pace intensity, what to skip)
- Privacy requirements (public sharing, need password gate, what info cannot go online)
Gather materials: screenshots, PDFs, emails, chat logs, links all work. First organize into a list of facts before writing JSON; do not guess as you collect.
Step 2: Deep Research (Online, Distinguish "Confirmed" vs "To Verify")
Research in priority order, and record source links with verification dates:
| Priority | Research Content |
|---|---|
| P0 | Visa/passport validity, flights/trains, accommodation, conference registration/tickets, insurance |
| P1 | Airport ↔ city transport (last train, terminal), city transport tickets, timed-entry tickets, restaurant reservations |
| P2 | Attractions, shopping, backup plans, weather |
- Prioritize official sources: airline/airport/rail, hotel, conference website, museum/attraction website, consulate, transport operator.
- Every critical piece of information must be labeled with one of four wordings: Confirmed / To Verify / Unconfirmed / Example (rules in
references/content-guide.md§6). - Do not fabricate prices, schedules, opening hours, or reservation status; if you can't find it, write "To Verify" and give a fallback of "check the official source".
- Common pitfalls (airport transport, timed-entry tickets, Wi-Fi, payment, emergency numbers, timezone/DST) must be checked item by item and written into the handbook or event notes.
Step 3: Write trip.json
Strictly follow references/trip-schema.md; you can directly reference the example examples/tokyo-conference/trip.json.
meta: title, subtitle, home location, start/end dates, theme, map provider, footer (write data cutoff date).destinations: each destination has anid+ IANA timezone (e.g.,Asia/Tokyo).days[].events: each event must at least havetime/title/short/detail/kind; if there's a location, writelocation+map; if there are official links, writelinks; if related to a checklist, writecheckId.checklists: grouped by phase (Before Departure / After Arrival / During / Before Return),idmust be globally unique.handbook: sections for transport, network, payment, safety & emergency, attending conference, food & drink, packing, etc. (can be merged/supplemented, but don't skip topics).tickets: one per person,qrpoints to a placeholder image or user-supplied image (do not commit real ticket codes).
Dual Timezone Rules (Most Error-Prone)
time/endTimeare both local time of the event; iftzis not set, it inherits the destination's timezone for that day.- When a flight crosses timezones,
tzindicates the departure city timezone, andendTimeis also interpreted in thattz. If merging into one flight event,endTimemust be "landing time converted to departure city timezone" and indetailwrite "Landing local time HH:MM"; a simpler approach is to split departure and landing into two events, each with its own local timezone. - Multi-day arrival goes in the next day's
days[],detailwrite "+1 day" / "next day"; for events crossing midnight, ifendTimeis less thantime, it is handled as the next day, but textual explanation is still recommended. - For all-day events with no specific time, use
skipTimezone: true; always write timezone as IANA name, neverUTC+9orJST. - The page automatically converts times to the home timezone; do not manually write the conversion in the description, unless it's something like "online check-in opens" / "remote meeting" that must be acted on in the home timezone before departure.
Step 4: Build
Execute in the skill root directory (the one containing scripts/, templates/); the script resolves paths relative to the current working directory; you can also use full paths from any directory.
node scripts/build.mjs <trip.json> --out dist
Common flags:
# Multi-file site (generates shareable ticket-<id>.html)
node scripts/build.mjs trip.json --multi --out dist
# Override theme / add password gate / disable PWA / overwrite non-empty output dir / quiet mode
node scripts/build.mjs trip.json --theme night --gate-password "your-password" --out dist
node scripts/build.mjs trip.json --no-pwa --out dist
node scripts/build.mjs trip.json --force --quiet --out dist
- Default output:
dist/index.html;--outdefaults todist. buildruns the same data validation internally first; if there are errors, exits with code 1 and does not produce a half-baked output; warnings are printed but do not block.- If the output directory exists and is non-empty, you must add
--force(this clears the directory first). --helpto see all flags.
Step 5: Validate
node scripts/verify.mjs <trip.json> # Default: errors cause failure (exit 1), warnings only prompt
node scripts/verify.mjs <trip.json> --strict # warnings also count as failure (recommended before publishing)
node scripts/verify.mjs <trip.json> --quiet # only show error summary
Validation covers: meta required fields & valid timezone/date, destinations references, days/events time format & tz validity, link protocols, handbook HTML whitelist, tickets.qr file existence, and privacy scan (suspected phone numbers/long numeric IDs get warnings). Either fix warnings, or be able to explain them.
Step 6: Preview & Deploy
- Local preview: Open
dist/index.htmldirectly in your browser (single file works by double-click); for multi-file, it's better to serve locally:npx serve dist # or python -m http.server --directory dist - Deploy: See
references/deploy.md(GitHub Pages / Cloudflare Pages / any static host). - Share ticket pages: In multi-file mode,
ticket-<id>.htmlcan be individually sent to the corresponding person; in single-file mode, use#ticket-<id>anchor, but the same page contains everyone's content. - Privacy reminder: Public site = visible to anyone. Do not put real QR codes, ticket codes, ID numbers, or phone numbers into a public page; the password gate is front-end only (see
deploy.mdfor details).
Invocation Examples
Example 1: Tokyo Academic Conference (same as example data)
User: I'm going to Tokyo for a conference from November 20–24, two people (A/B). Here are the flight and hotel screenshots and the agenda link;
help me put registration, opening, poster session, dinner all into a schedule, and make it a page I can view on my phone anytime.
Agent:
1. Gather materials → ask 3 things: Does the hotel booking include breakfast, types of conference badges for A/B, return flight check-in time
2. Research → Haneda→city transport options & last train, meeting venue vs hotel location, arrival immigration time
3. Write trip.json → reference examples/tokyo-conference/trip.json (example merges flights as one event, endTime converted to departure timezone)
4. Build → node scripts/build.mjs trips/tokyo-2026/trip.json --multi --out dist
5. Validate → node scripts/verify.mjs trips/tokyo-2026/trip.json --strict
6. Preview → open dist/index.html; propose deploying to GitHub Pages / send ticket-badge-a.html to A
Example 2: Family International Trip (multiple destinations + dual timezone + insurance info)
User: This summer, I'm taking my parents to Spain for 10 days, Madrid in and Barcelona out. Help me plan an itinerary that includes metro info and emergency numbers.
Agent:
- destinations write two (Madrid / Barcelona, timezone Europe/Madrid compared to departure city)
- handbook focus on: airport↔city, metro tickets, payment & tips, emergency numbers & embassy, food (parents' dietary restrictions)
- events write the "why" and "what to skip" (e.g., "Skip Retiro today to save energy for the Royal Palace")
- After build, run verify, deploy dist to GitHub Pages, send the link to family
Example 3: Update Existing Data + Share Only One Person's Ticket Page
User: The plan changed: dinner moved from the 23rd to the 24th at 19:30, and also send me my wife's conference badge page separately.
Agent:
1. Edit trip.json, update the corresponding event's time/detail (keep "Confirmed" wording and source)
2. node scripts/build.mjs trip.json --multi --out dist --force
3. node scripts/verify.mjs trip.json
4. Share dist/ticket-badge-b.html separately; remind: public link exposes QR codes, suggest sending only to the person or adding access control
Quality Red Lines
- Do not fabricate: prices, schedules, opening hours, reservation status, phone numbers must have a source; if not available, write "To Verify" + "Check the official source".
- Confirmed vs To Verify: User's confirmation / official page = Confirmed; third-party platform / old screenshot / guide = To Verify; fixed wording in
content-guide.md§6; do not use "reportedly" or "probably". - Dual timezone:
timewrites event local time; when merging flights,endTimeis converted using eventtz(departure city timezone),detailwrites landing local time; multi-day events split to the next day; timezone uses only IANA names. - Privacy & ticket codes: Do not put real QR codes, ticket codes, PNR, ID numbers, phone numbers, or addresses into a page that will be made public; use placeholders for
qr; example data must be fictional and anonymized; the repository only contains placeholder QR codes. - Do not promise capabilities: Do not promise real-time inventory / booking / check-in; leave irreversible actions like purchases, payments, cancellations, and changes to the user; do not execute them on behalf of the user.
- Must run validation before delivery:
verify.mjs --strictmust pass with zero errors before delivering; double-check for sensitive information before deploying. - Explain boundaries: The password gate is acquaintances-level sharing protection, not encryption; for real security, use private hosting / access control.
Single File vs Multi File: How to Choose
| Requirement | Choose Single File (default) | Choose Multi File (--multi) |
|---|---|---|
| Send to family/colleagues, WeChat/email, offline double-click | ✅ One HTML file is most convenient | Not recommended (whole directory needed) |
| Deploy as a site, long-term use, frequent updates | Fine (re-upload one file each time) | ✅ Cache-friendly, clear structure |
| Individually share ticket pages per person | ❌ Anchor reveals everyone's tickets on the same page | ✅ ticket-<id>.html independent page |
| Want a completely single file (including QR codes) | Replace tickets[].qr with data: URI or external link URL | — |
| Need a password gate | ✅ Supported (prompt on main page and in-page ticket views) | ✅ Main page and ticket-<id>.html all show password prompt (same password, unlocked once per browser) |
Note: In single-file mode, local images pointed to by
qrare automatically inlined asdata:URIs, so the output is truly a single HTML file;data:/http(s)QR sources are kept as-is.
File Map
skills/trip-cheat-sheet/
├── SKILL.md # This file: when to use, how to use, red lines
├── references/
│ ├── trip-schema.md # Single data contract (fields/timezone/build commands)
│ ├── content-guide.md # Content writing rules (six elements/dual timezone/handbook sections/labeling rules)
│ └── deploy.md # Deployment & sharing (Pages/Cloudflare/single-multi-file/password gate)
├── scripts/
│ ├── build.mjs # trip.json → web page
│ └── verify.mjs # trip.json validator (reused internally by build)
├── templates/ # style.css / app.js / index.html / ticket.html
└── examples/tokyo-conference/ # Runnable example (with placeholder QR codes)
├── trip.json
└── assets/qr-a.svg, qr-b.svg
FAQ
| Issue | Resolution |
|---|---|
❌ Output directory is not empty | Add --force, or change --out directory |
| Blank page / missing styles | In multi-file mode, upload the entire dist/ (including assets/) together; ensure index.html and assets/ are at the same level |
| Time displays incorrectly | Check tz spelling (IANA name); for merged flights, ensure endTime is converted using departure city timezone |
verify shows warnings | Fix them, or confirm acceptable before delivery; --strict will fail |
| Forgot password gate password | Rebuild: node scripts/build.mjs trip.json --gate-password "new password" |
| 404 after deployment | Check Pages branch/directory settings, whether Actions ran, filename case |
| Node version error | Use Node.js ≥ 18 (needs full Intl timezone data and ESM support) |
English Quick Reference
- What: generate a mobile-first travel cheat-sheet web page from one
trip.json— itinerary timeline, checklists, destination handbook, dual-timezone display, map deep links, QR ticket pages, optional password gate, PWA. - Build:
node scripts/build.mjs <trip.json> --out dist(single file, default) or--multi(static site withticket-<id>.html). Flags:--theme paper|slate|night,--gate-password,--no-pwa,--force,--quiet. - Verify:
node scripts/verify.mjs <trip.json> [--strict] [--quiet]. - Contract:
references/trip-schema.md; writing rules:references/content-guide.md; deployment:references/deploy.md. - Never: fabricate prices/schedules, mix up timezones, or commit real ticket codes, QR images, IDs or phone numbers. Mark verified vs unverified content explicitly.