TripCheat · AI 行程规划专家(trip-cheat-sheet)
把用户散落的航班、酒店、会议议程、门票、攻略截图和聊天记录,整理成一个随身网页: 行程时间线(今天几点去哪)、清单(别忘了什么)、手册(怎么走/怎么付/出问题找谁)。 手机打开即用,支持双时区、深色主题、字号调节、地图深链、二维码票券,可部署到任何静态托管。
页面由本 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);票券二维码页;可选密码门(前端 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>锚点,但同页含所有人内容。 - 隐私提醒:公开站点 = 任何人可见。真实二维码、票码、证件号、手机号不要放进公开页面;密码门只是前端校验(详见
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 单独分享;提醒:公开链接会暴露二维码,建议只给本人或加访问控制
质量红线
- 不编造:价格、班次、开放时间、预约状态、电话必须有来源;没有就写「待核实」+「以官方为准」。
- 已确认 vs 待核实:用户确认单/官方页面 = 已确认;第三方平台/旧截图/攻略 = 待核实;固定措辞见
content-guide.md§6,不要用「据说」「应该」。 - 双时区:
time写事件当地时间;航班合并写时endTime按事件tz(起飞地时区)换算,detail写落地当地时间;跨日拆到次日;时区只用 IANA 名称。 - 隐私与票码:不把真实二维码、票码、PNR、证件号、手机号、住址写进要公开的页面;
copy用占位符;示例数据必须虚构脱敏;仓库只放占位二维码。 - 不承诺能力:不承诺实时库存/预订/值机;下单、付款、退改等不可逆操作交给用户,不替用户执行。
- 交付前必跑校验:
verify.mjs --strict零错误再交付;部署前再确认没有敏感信息。 - 说明边界:密码门是熟人分享级保护,不是加密;要真安全用私有托管/访问控制。
单文件 vs 多文件怎么选
| 需求 | 选单文件(默认) | 选多文件(--multi) |
|---|---|---|
| 发给家人/同事、微信/邮件、离线双击 | ✅ 一个 HTML 最省事 | 不建议(要整目录) |
| 部署成站点、长期使用、随时更新 | 可以(每次重传一个文件) | ✅ 缓存友好、结构清晰 |
| 按人单独分享票券页 | ❌ 用锚点会暴露同一页其他人的票 | ✅ ticket-<id>.html 独立页面 |
| 想彻底一个文件(含二维码) | 把 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/ # 可跑示例(含占位二维码)
├── 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.