TripCheat · AI 行程規劃專家(trip-cheat-sheet)
把使用者散落的航班、飯店、會議議程、門票、攻略截圖和聊天記錄,整理成一個隨身網頁: 行程時間線(今天幾點去哪)、清單(別忘了什麼)、手冊(怎麼走/怎麼付/出問題找誰)。 手機打開即用,支援雙時區、深色主題、字號調節、地圖深鏈、QR 碼票券,可部署到任何靜態託管。
頁面由本 skill 自帶的生成器從一份 trip.json 構建:資料契約見 references/trip-schema.md,寫作規範見 references/content-guide.md,部署見 references/deploy.md。
何時使用
觸發場景
- 「幫我做個行程」「把機票、飯店、會議議程整理成一頁」「出差/參會準備」
- 「行程攻略」「隨身頁」「旅行手冊」「出行清單」「每天幾點幹嘛」
- 使用者給了一堆截圖 / PDF / 郵件 / 連結 / 聊天記錄,需要結構化 + 補調研 + 做成可隨身查看的頁面
- 已有
trip.json:要重新生成頁面、改主題、加密碼門、部署或分享票券頁
不適用
- 只需要查某個景點介紹、天氣、訂票:直接搜尋/回答,不必做頁面
- 需要即時庫存、下單、付款、值機:本 skill 不接預訂 API,只整理資訊與連結
- 純路線導航:用地圖工具,不需要行程頁
產出物
| 模式 | 命令 | 產物 |
|---|---|---|
| 單檔案(預設) | node scripts/build.mjs trip.json --out dist | dist/index.html(CSS/JS/資料/PWA manifest 全內嵌)+ 按需複製的票券圖片 |
| 多檔案站點 | 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、複製的票券資源 |
頁面能力:行程時間線 / 清單 / 手冊三視圖;「當前/下一件事」高亮;雙時區時鐘與時間換算;主題(paper/slate/night)與字號切換;Google/高德/Apple 地圖深鏈(Google 路線連結帶出行方式參數);清單勾選(本機 localStorage);票券 QR 碼頁;可選密碼門(前端 SHA-256 校驗);可加到主螢幕(PWA,--no-pwa 關閉)。
工作流(6 步)
第 1 步:收集資料(問卷 + 檔案/截圖/連結)
先問一輪,最多 6 個問題,避免連環追問;使用者沒答的用預設假設並顯式標註「假設」。
- 誰去、幾個人、關係(同行人是否需要老人/小孩/無障礙安排)
- 出發地、日期(含跨日/紅眼)、目的地(是否多城市/中轉)
- 哪些已訂、哪些待訂(航班、飯店、會議註冊、門票、餐廳)
- 會議/活動的關鍵時間(註冊、開幕、自己的報告/海報時段、晚宴)
- 偏好與紅線(預算、飲食忌口/過敏、節奏強度、想放棄什麼)
- 隱私要求(是否公開分享、是否需要密碼門、哪些資訊不能上網)
收集材料:截圖、PDF、郵件、聊天記錄、連結都行。先整理成事實清單再動手寫 JSON,不要邊收集邊猜。
第 2 步:深度調研(聯網,區分「已確認」與「待核實」)
按優先級調研,並把來源連結與核查日期記下來:
| 優先級 | 調研內容 |
|---|---|
| P0 | 簽證/護照有效期、航班/車次、住宿、會議註冊/門票、保險 |
| P1 | 機場 ↔ 市區交通(末班車、航廈)、市內交通票、門票分時預約、餐廳預訂 |
| P2 | 景點、購物、備選方案、天氣 |
- 優先官方來源:航司/機場/鐵路、飯店、會議官網、博物館/景點官網、使領館、交通運營方。
- 每條關鍵資訊分四類措辭:已確認 / 待核實 / 未定 / 範例(規則見
references/content-guide.md§6)。 - 不要編造價格、班次、開放時間、預約狀態;查不到就寫「待核實」並給「以官方為準」的兜底。
- 常見坑(機場交通、門票預約、Wi-Fi、支付、緊急電話、時區/DST)逐項核對,寫進手冊或事件說明。
第 3 步:寫 trip.json
嚴格按 references/trip-schema.md 寫;可直接參考範例
examples/tokyo-conference/trip.json。
meta:標題、副標題、常駐地(home)、起止日期、主題、地圖供應商、頁腳(寫資料截止日期)。destinations:每個目的地一個id+ IANA 時區(如Asia/Tokyo)。days[].events:每條事件至少寫time/title/short/detail/kind;有地點的寫location+map;有官方連結的寫links;能關聯清單的寫checkId。checklists:按階段分組(出發前 / 落地後 / 期間 / 返程前),id全域唯一。handbook:交通、網路、支付、安全應急、參會、飲食、打包等章節(可合併/增補,主題別漏)。tickets:每人一張,qr指向佔位圖或使用者自備圖片(不要提交真實票碼)。
雙時區規則(最容易錯)
time/endTime都是事件當地的時間;tz不填時繼承當天目的地的時區。- 航班跨時區時
tz表示起飛地時區,且endTime也按該tz解釋。合併成一條航班時,endTime要寫「落地時刻換算到起飛地時區」的值,並在detail寫清「落地當地時間 HH:MM」;更省事的做法是把起飛、落地拆成兩條事件,各自用自己的當地時區。 - 跨日到達放到次日
days[],detail寫「+1 天」/「次日」;跨午夜事件的endTime小於time時會按次日處理,但仍建議文字說明。 - 全天無時刻的安排用
skipTimezone: true;時區一律寫 IANA 名稱,不要寫UTC+9、JST。 - 頁面會自動把時間換算成常駐地時間,正文不要重複手寫換算,除非是「值機開放/遠端會議」這類必須在出發前按常駐地時間行動的事。
第 4 步:構建
在 skill 根目錄(含 scripts/、templates/ 的目錄)執行;腳本按當前工作目錄解析路徑,也可在任意目錄用完整路徑運行。
node scripts/build.mjs <trip.json> --out dist
常用參數:
# 多檔案站點(生成可單獨分享的 ticket-<id>.html)
node scripts/build.mjs trip.json --multi --out dist
# 覆蓋主題 / 加密碼門 / 關閉 PWA / 覆蓋非空輸出目錄 / 安靜模式
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
- 預設輸出
dist/index.html;--out預設dist。 build內部先跑同一套資料校驗,有 errors 會退出碼 1,不會生成半成品;warnings 會列印但不阻塞。- 輸出目錄已存在且非空時必須加
--force(會先清空該目錄)。 --help查看全部參數。
第 5 步:校驗
node scripts/verify.mjs <trip.json> # 預設:errors 失敗(退出碼 1),warnings 只提示
node scripts/verify.mjs <trip.json> --strict # warnings 也算失敗(發布前推薦)
node scripts/verify.mjs <trip.json> --quiet # 只輸出錯誤摘要
校驗覆蓋:meta 必填與合法時區/日期、destinations 引用、days/events 時間格式與 tz 合法性、連結協定、handbook HTML 白名單、tickets.qr 檔案存在性,以及隱私掃描(疑似手機號/長數字編號會給警告)。警告要麼修掉,要麼能解釋清楚。
第 6 步:預覽與部署
- 本地預覽:直接用瀏覽器打開
dist/index.html(單檔案可雙擊);多檔案建議起本地伺服器:npx serve dist # 或 python -m http.server --directory dist - 部署:見
references/deploy.md(GitHub Pages / Cloudflare Pages / 任意靜態託管)。 - 分享票券頁:多檔案模式的
ticket-<id>.html可單獨發給對應的人;單檔案模式用#ticket-<id>錨點,但同頁含所有人內容。 - 隱私提醒:公開站點 = 任何人可見。真實 QR 碼、票碼、證件號、手機號不要放進公開頁面;密碼門只是前端校驗(詳見
deploy.md)。
調用範例
範例 1:東京學術會議(範例資料同款)
使用者:我 11 月 20–24 日去東京開學術會議,兩個人(A/B),這是航班和飯店的截圖、議程連結;
幫我把註冊、開幕、海報、晚宴都排進去,做成手機上隨時能看的頁面。
Agent:
1. 收集資料 → 問清 3 件事:飯店訂單是否含早餐、A/B 各自的參會證類型、回程值機時間
2. 調研 → 羽田→市區的交通方式與末班車、會場與飯店的位置關係、落地入境用時
3. 寫 trip.json → 參考 examples/tokyo-conference/trip.json(範例把航班合併為一條、endTime 按起飛地時區換算)
4. 構建 → node scripts/build.mjs trips/tokyo-2026/trip.json --multi --out dist
5. 校驗 → node scripts/verify.mjs trips/tokyo-2026/trip.json --strict
6. 預覽 → 打開 dist/index.html;提出部署到 GitHub Pages / 把 ticket-badge-a.html 發給 A
範例 2:家庭出境遊(多目的地 + 雙時區 + 保險資訊)
使用者:暑假帶爸媽去西班牙 10 天,馬德里進巴塞隆納出,幫我做個行程,要能查地鐵和緊急電話。
Agent:
- destinations 寫兩個(Madrid / Barcelona,時區 Europe/Madrid 與出發地對比)
- handbook 重點寫:機場↔市區、地鐵票、支付與小費、緊急電話與使館、飲食(老人忌口)
- 事件裡寫清「為什麼」與「放棄項」(如「今天不去麗池,留體力給王宮」)
- build 後跑 verify,把 dist 部署到 GitHub Pages,連結發給家人
範例 3:已有資料更新 + 只分享某人的票券頁
使用者:行程改了:晚宴從 23 日改到 24 日 19:30,另外把我老婆的參會證頁單獨發我。
Agent:
1. 改 trip.json 裡對應 event 的 time/detail(保留「已確認」措辭與來源)
2. node scripts/build.mjs trip.json --multi --out dist --force
3. node scripts/verify.mjs trip.json
4. 把 dist/ticket-badge-b.html 單獨分享;提醒:公開連結會暴露 QR 碼,建議只給本人或加存取控制
品質紅線
- 不編造:價格、班次、開放時間、預約狀態、電話必須有來源;沒有就寫「待核實」+「以官方為準」。
- 已確認 vs 待核實:使用者確認單/官方頁面 = 已確認;第三方平台/舊截圖/攻略 = 待核實;固定措辭見
content-guide.md§6,不要用「據說」「應該」。 - 雙時區:
time寫事件當地時間;航班合併寫時endTime按事件tz(起飛地時區)換算,detail寫落地當地時間;跨日拆到次日;時區只用 IANA 名稱。 - 隱私與票碼:不把真實 QR 碼、票碼、PNR、證件號、手機號、住址寫進要公開的頁面;
copy用佔位符;範例數據必須虛構脫敏;倉庫只放佔位 QR 碼。 - 不承諾能力:不承諾即時庫存/預訂/值機;下單、付款、退改等不可逆操作交給使用者,不替使用者執行。
- 交付前必跑校驗:
verify.mjs --strict零錯誤再交付;部署前再確認沒有敏感資訊。 - 說明邊界:密碼門是熟人分享級保護,不是加密;要真安全用私有託管/存取控制。
單檔案 vs 多檔案怎麼選
| 需求 | 選單檔案(預設) | 選多檔案(--multi) |
|---|---|---|
| 發給家人/同事、微信/郵件、離線雙擊 | ✅ 一個 HTML 最省事 | 不建議(要整目錄) |
| 部署成站點、長期使用、隨時更新 | 可以(每次重傳一個檔案) | ✅ 快取友好、結構清晰 |
| 按人單獨分享票券頁 | ❌ 用錨點會暴露同一頁其他人的票 | ✅ ticket-<id>.html 獨立頁面 |
| 想徹底一個檔案(含 QR 碼) | 把 tickets[].qr 換成 data: URI 或外鏈 URL | — |
| 需要密碼門 | ✅ 支援(主頁面與頁內票券視圖都彈) | ✅ 主頁面與 ticket-<id>.html 都會彈密碼框(同一密碼,同一瀏覽器解鎖一次) |
注意:單檔案模式會把
qr指向的本地圖片自動內聯為data:URI,產物真的只有一個 HTML 檔案;已經是data:/http(s)的 QR 原樣保留。
檔案地圖
skills/trip-cheat-sheet/
├── SKILL.md # 本檔案:何時用、怎麼用、紅線
├── references/
│ ├── trip-schema.md # 唯一資料契約(欄位/時區/構建命令)
│ ├── content-guide.md # 內容寫作規範(六要素/雙時區/手冊章節/標註規則)
│ └── deploy.md # 部署與分享(Pages/Cloudflare/單多檔案/密碼門)
├── scripts/
│ ├── build.mjs # trip.json → 網頁
│ └── verify.mjs # trip.json 校驗器(build 內部複用)
├── templates/ # style.css / app.js / index.html / ticket.html
└── examples/tokyo-conference/ # 可跑範例(含佔位 QR 碼)
├── trip.json
└── assets/qr-a.svg, qr-b.svg
常見問題
| 現象 | 處理 |
|---|---|
❌ 輸出目錄非空 | 加 --force,或換 --out 目錄 |
| 頁面空白/樣式遺失 | 多檔案模式必須把整個 dist/(含 assets/)一起上傳;確認 index.html 與 assets/ 同級 |
| 時間顯示不對 | 檢查 tz 拼寫(IANA 名稱);合併航班時 endTime 是否按起飛地時區換算 |
verify 有警告 | 修掉,或確認可接受後交付;--strict 會失敗 |
| 忘了密碼門密碼 | 重新構建:node scripts/build.mjs trip.json --gate-password "新密碼" |
| 部署後 404 | 檢查 Pages 分支/目錄設定、Actions 是否跑完、檔案名稱大小寫 |
| Node 版本報錯 | 用 Node.js ≥ 18(需要完整 Intl 時區資料與 ESM) |
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.