All skills
cat-xierluo avatar

/apple-smart-schedule

@d691795

把一句自然语言(机票/高铁/开庭/会议/截止日期/聚会/看病等)或一张票据截图,自动变成苹果「日历」事件 + 一串按事件类型智能提前的「提醒事项」。在 macOS 上运行、经 iCloud 同步到 iPhone/iPad。当用户说「帮我加个日程/提醒」「机票 MU5137 8:30 起飞提醒我」「下周三下午开庭提前提醒」「G1234 高铁」「上诉期 15 号截止」「提前 2 小时提醒我」「把这个行程加到日历」等任何要把时间安排写进苹果日历或提醒事项的场景,都必须用本 skill。仅 macOS。

Use this Skill: https://skilld.dev/gh/cat-xierluo/legal-skills/apple-smart-schedule

This session only. Nothing lands on disk.

SKILL.md

≈155 tokens always: the name and description. ≈3.1k when used: this file. ≈2.3k more on demand in 3 files.

apple-smart-schedule · 苹果智能日程提醒

⚠️ 平台限制(先读)

本 skill 仅在 macOS 上运行:它通过 osascript/remindctl 调用 Mac 自带的「日历」和「提醒事项」App 来创建日程。

  • ✅ 创建结果经 iCloud 自动同步到你登录同一 Apple ID 的 iPhone / iPad。
  • ❌ 不能直接在 Windows / Android / Linux 上用,也不能在 iPhone 上直接运行这些脚本。
  • 授权(重要):首次运行脚本时,macOS 会弹出「xxx 想要控制「日历」/「提醒事项」」对话框,点「好」即可(只此一次)。每换一个终端 App 或新环境首次用,都会再弹一次——因为授权是按"调用的终端 App"分别记录的(Terminal 授权了不代表 iTerm 也授权了);点过就好,无需去设置里找。只有当弹窗没出现、或曾经点过"不允许"时,才去「系统设置 › 隐私与安全性 › 自动化」把对应终端的 Calendar / Reminders 开关手动打开。

它做什么

用户用大白话说一件事(或发张截图),本 skill:

  1. 解析出 事件标题、开始时间、结束时间(可选)、地点、事件类型;
  2. 按事件类型套用 默认提前量(飞机/高铁/开庭/会议/截止/社交 各不同);
  3. 在苹果日历建 1 个事件(当天已有同类事件则更新它,不重复新建),在提醒事项建 一串提前提醒;
  4. 回执告诉用户建了什么。

通用场景(同一套逻辑,不限于出行):

类型 示例输入 智能默认提前量
✈️ 航班 "东航 MU5137 7/20 8:30 浦东起飞" 前1天9点 + 前3h + 前1h
🚄 高铁 "G1234 北京南→上海虹桥 8/1 14:00" 前1h + 前30min
⚖️ 开庭 "下周三 14:00 开庭" 前1天9点 + 前3h + 前1h
💼 会议 "明天上午 10 点开会" 前1天9点 + 前1h
⏰ 期限 "15 号上诉期截止" 前3天 + 前1天 + 当天9点
🍻 社交 "周五晚和张总吃饭" 前1天9点 + 前2h
🎯 其他 "后天上午去体检" 前1h

核心流程(AI 执行步骤)

第 0 步:读配置(每次都要)

读 $SKILL_DIR/config/config.json,拿到:时区、默认日历名 default_calendar、默认提醒清单名 default_reminder_list、各类事件提前量 lead_times。 再读 $SKILL_DIR/references/lead-times.md,掌握事件类型判断规则和提前量计算方法。

第 1 步:解析输入

  • 文字输入:直接从用户消息提取 时间(日期+时分)、事件、地点、航班号/车次 等。
  • 截图输入(机票确认页、12306、微信邀约等):用视觉能力读出上述字段。
  • 时间按 config.timezone(默认 Asia/Shanghai)理解。含糊时(如"下周三"未指定时区、只说"下午"),按最常见理解并在回执里点明你的理解,让用户一眼能纠正。
  • 没给结束时间 → 事件默认时长 60 分钟(会议/社交够用;航班/高铁若能推断时长更好)。

第 2 步:判断事件类型

按 references/lead-times.md 的关键词表归类到 flight / train / court / meeting / deadline / social / default 之一。一条消息可能含多个事件(如出差=航班+到达后会议),分别处理。

第 3 步:算出每条提醒的绝对时间

从 config.lead_times[类型] 取数组,按 lead-times.md 的格式规则把每条换算成绝对时间(ISO,Asia/Shanghai)。

用户当次覆盖优先:若用户明说"提前 X 小时""只提醒一次",则当次只用用户指定的,忽略默认。

第 4 步:查重与写入(更新还是新建)

默认先查重,避免用户补充机票/酒店/改签信息时重复新建事件。用户明说「再建一个」「分开记」时才跳过查重直接新建。

# 1) 查事件日期当天的已有事件(默认查 default_calendar;用户提过别的日历就查那个;指称模糊用 ALL)
$SKILL_DIR/scripts/find_event.sh "<日历名|ALL>" "<事件日期YYYY-MM-DD>"

# 2a) 唯一匹配 → 更新已有事件(第 2–6 参数传 "-" = 不改该项;备注是整段替换,补充信息要先合并原备注再写入)
$SKILL_DIR/scripts/update_event.sh "<uid>" ["<新标题>"] ["<新开始ISO>"] ["<新结束ISO>"] ["<新地点>"] ["<新备注>"]
#     定位也可用标题关键词兜底;多匹配会拒绝并列出候选。详见下文「修改已有事件」一节。

# 2b) 无匹配 → 新建
$SKILL_DIR/scripts/create_event.sh "<标题>" "<default_calendar>" "<开始ISO>" ["<结束ISO>"] ["<地点>"] ["<备注>"]

# 3) 提醒:对每个提前量建一条
$SKILL_DIR/scripts/create_reminder.sh "<标题>" "<default_reminder_list>" "<提醒绝对ISO>"

查重匹配规则(对 find 输出的候选逐条判断):

  • 同一天,且 标题含相同关键标识(航班号/车次/案号/活动名)或 时间相近(±3 小时)且主题一致 → 同一事件;
  • 全天事件(00:00 起、无明确时长)按「当天」参与匹配;
  • 唯一匹配 → update;多个候选或拿不准 → 把候选列给用户选,不要猜;
  • 0 匹配但用户说「我已经建过了」→ 窗口扩到前后各 1 天重查(find_event.sh "<日历>" "<前一天>" "<后两天>");
  • 走了更新路径就不要再新建提醒(很可能之前已建过,重复建=骚扰),回执里问一句要不要顺带补提醒;
  • 更新的如果是用户手动建的事件,回执里说清楚改了哪些字段(时间/地点/备注)。

写入要点:

  • 一次出差 = 一个日历事件:同一行程的去程/住宿/返程(及当地多个安排)默认合并进一个事件——起止 = 去程出发 → 返程落地,标题 = 行程名(如 XX大学 · 行业前沿讲座(西安)),航班/酒店细节分层写进备注(✈️ 去程… / 🏨 住宿… / ✈️ 返程…)。不要按交通/住宿拆成多条事件;提醒仍按行程内关键节点(如每个航班前 3h)建。
  • 行程内部的细节也合并进总览:讲座/会议的精确时段、地点、会议室号、线上会议号、议程要点——都进总览事件的备注或地点字段,不新建讲座/会议子事件,也不单独为它建提醒。判准:凡是「出差总览事件已经开始/结束的当天或中间一天发生的细节」,都按合并处理;只有真正独立、不依附任何出行总览的日程,才新建事件。已写入 DEC-006。
  • 单段行程(只有一个航班/一场会议)标题示例:✈️ MU5137 上海浦东→北京首都
  • 航班/出行录关键字段:参照 references/lead-times.md 的「航班详细字段录入模板」,把 航司/舱位/机型/飞行时长 整理进事件备注(update/create 的备注参数),航站楼进地点。不录乘客/机票号/订单号(没必要、有隐私顾虑)。
  • 提醒标题加区分后缀,让用户在清单里一眼看清:✈️ MU5137 值机打包(前1天)、🚄 G1234 该去车站了(前1h)、⚖️ 开庭准备(前3h)。
  • 脚本会自动降级:未装 remindctl 时用 osascript(提醒仍能创建,只是不能查/改/删)。

第 5 步:回执

给用户一个简短清单,例如:

已为你安排 ✈️ MU5137(2026-07-20 08:30,上海浦东 T2)
📅 日历事件已建 →「个人」日历
⏰ 提醒事项已建 3 条:
   • 07-19 09:00  值机打包(前1天)
   • 07-20 05:30  该去机场了(前3h)
   • 07-20 07:30  开始登机(前1h)
(经 iCloud 同步到你的 iPhone/iPad,稍等片刻可在手机上看到)

更新已有事件时,回执换成「改了什么」,例如:

✈️ MU5137 已改签为 08:50 起飞——更新的是你 7/20 已有的那条日历事件(未新建)
📅 改动:开始时间 08:30 → 08:50,备注补充了舱位信息

首次使用配置(重要)

  1. 若 config/config.json 还不存在,从模板复制一份:
    cp config/config.example.json config/config.json
  2. 跑自检,拿到你机器上真实的日历名和提醒清单名:
    bash $SKILL_DIR/scripts/setup_check.sh
  3. 把输出里的日历名填进 config.json 的 default_calendar,清单名填进 default_reminder_list。填错不会报错——脚本会兜底落到第一个日历/默认清单,但名字对才会落到你想要的地方。

config.json 是你的本地配置(被 .gitignore 忽略、不提交);config.example.json 是入库的默认模板。

想调整各类事件的提前量,直接改 config.json 的 lead_times(格式见 references/lead-times.md)。

提前量就是个人配置入口:用户表达「提醒太多/只要提前 3 小时/前 1 天不用提醒」这类偏好时,把它写进 config.json 的 lead_times(一次配置长期生效),不要每次口头忽略默认——否则下次换会话又会按默认建一串。

安装更强后端(可选)

提醒事项默认用 osascript(只能创建)。装上 remindctl 后还能查/改/删:

brew install steipete/tap/remindctl

装不装不影响创建功能,本 skill 会自动探测。

脚本参考

脚本 作用
scripts/create_event.sh 建日历事件(osascript)
scripts/find_event.sh 按日期窗口+关键词查已有事件(查重/定位,输出 uid 和各字段)
scripts/update_event.sh 修改已有日历事件(按 UID 或标题定位,- = 不改该项;create_event.sh 只能新建)
scripts/create_reminder.sh 建提醒(remindctl 优先,降级 osascript)
scripts/list_calendars.sh 列出所有日历名
scripts/list_reminder_lists.sh 列出所有提醒清单
scripts/setup_check.sh 首次自检:依赖、权限、日历/清单名

修改已有事件(用 update_event.sh,别用 create_event.sh 重建)

用户说「把行程加到我已有的那个日程上」「改一下时间」「补上酒店信息」时,是修改不是新建。 create_event.sh 只会新建,重复调用会产生重复事件——这类需求一律走:

$SKILL_DIR/scripts/update_event.sh "<UID 或 标题关键词>" ["<新标题>"] ["<开始>"] ["<结束>"] ["<地点>"] ["<备注>"]

参数规则:第 2–6 个参数传 - 表示「不改这一项」;开始/结束可只改其一,另一个填 -。

定位顺序:先按 UID 精确匹配 → 匹配不到再按标题包含匹配 → 标题匹配到多个时拒绝修改并返回候选清单(防误改),此时应改用 UID。

先查再改:不知道 UID 时,先用 osascript 按关键词把候选事件(含 UID、起止、日历名)列出来,再按 UID 精确改。

例:把已有的「西安出差」占位改准,并补酒店信息

update_event.sh "西安出差" "-" "2026-09-08 10:10" "2026-09-09 12:35" "西安 · XX大学" "去程 CA1234 …"
update_event.sh "XX酒店" "-" "-" "-" "-" "预订号 888888 · 客户经理 …"

⚠️ AppleScript 改日期的两个坑(已踩过)

  1. 组件顺序:必须先 set day of d to 1,再依次设 year / month / day,最后设 hours / minutes / seconds。顺序反了可能因目标月天数不足而溢出(例如把 31 日塞进 9 月)。
  2. 禁止用减法跨天:想表示「9 日 17:00」就直接设 day=9, hours=17;不要写成 day=9, hours=0 再 减 7 小时——减法会跨天回退到 8 日 17:00,把两天的行程压进同一天。

改完务必用 osascript 复核一遍起止时间,确认跨天事件真的跨了天。

注意

  • 这是改用户个人日历/提醒的操作。创建是安全的、可逆的(用户可在 App 里删);但如本 skill 未来扩展删除/批量操作,务必先和用户确认目标。
  • 提醒数据是个人隐私,不要把日历/提醒内容发到网络或第三方服务。解析只在本地完成。
  • 若用户其实想要的是飞书/钉钉/Outlook 等非苹果日历,本 skill 不适用——那些需要各自的工具。

Source: SKILL.md on GitHub

No alerts15d3 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    This skill automates the creation of calendar events and reminders on macOS by parsing natural language and images. It uses native AppleScript and local scripts, follows privacy best practices by avoiding sensitive data collection, and includes basic input sanitization.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: LOW · No issues

Signed by skilld at d691795. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 19 hours ago.

Activeupdated 2 weeks ago
homepage
https://github.com/cat-xierluo/legal-skills
author
杨卫薪律师(微信ywxlaw)
version
0.2.0

README badge

README badge for cat-xierluo/legal-skills/apple-smart-schedule