macos-calendar-assistant
Use bundled scripts for reliable Calendar.app operations.
Workflow
- 1. Extract title, start/end, timezone, calendar, location, notes, alarm.
- Check conflicts before writing:
-
scripts/list_events.swift <start_iso> <end_iso>
- 3. Prefer idempotent writes:
-
scripts/upsert_event.py (create/update/skip)
- 4. Apply alarm if requested:
-
scripts/set_alarm.py --uid <event_uid> --alarm-minutes <n>
- 5. For hygiene, run duplicate scan:
- INLINECODE3
Calendar routing defaults
- - Workout / Run / Training → INLINECODE4
- Work / Meeting / Client → INLINECODE5
- Product / Development / Building → INLINECODE6
- Personal / Social / Travel → INLINECODE7
- If unspecified: prefer writable iCloud/CalDAV calendars over local calendars.
Note: Calendar names vary by user setup. Map the intent to the closest local calendar name before writing.
Commands
List calendars
CODEBLOCK0
List events in range
CODEBLOCK1
Output includes uid for follow-up alarm/edit operations.
Idempotent create/update (recommended)
CODEBLOCK2
Result is one of: CREATED, UPDATED, SKIPPED.
Use --dry-run for preview.
Legacy direct add (always creates)
CODEBLOCK3
Set alarm by UID
CODEBLOCK4
Move event (legacy utility)
swift scripts/move_event.swift "Team sync" "Work" "2026-03-07T10:00:00+08:00" 60 --search-days 7
# optional precise match:
# --original-start "2026-03-06T10:00:00+08:00"
Prefer
upsert_event.py for most rescheduling flows; use
move_event.swift for direct title-based move when needed.
Duplicate scan / cleanup
CODEBLOCK6
Upcoming events (within 2 hours)
CODEBLOCK7
Environment + tests
CODEBLOCK8
Daily auto-check notifier
CODEBLOCK9
Extraction & scheduling heuristics (from real usage)
- 1. Speaker ownership from chat screenshots
- Treat the user's message bubble as primary intent.
- Treat counterpart bubbles as constraints (availability/travel window), not direct auto-create tasks.
- 2. Conflict policy
- If user explicitly says "override" (for example, "replace this slot"), allow replacing an existing slot and reschedule the displaced event.
- If not explicit, warn and ask for a choice before overwriting.
- 3. Time-window intent parsing
- Phrases like "4–6 PM for the other person" should first be interpreted as an availability window.
- Convert to a formal event only after user confirmation.
- 4. Reschedule priority
- Prefer moving flexible events (workouts/optional blocks) before strategic P0 work blocks.
- Do not auto-move P0 items unless user explicitly requests.
- 5. Confirmation prompt template
- Use: "I identified X as your intent and Y as counterpart constraints. I will apply Z. Confirm?"
- Keep it short; avoid over-confirming when intent is explicit.
Constraints
- - macOS only (EventKit + Calendar permission required)
- Default timezone comes from
config.json.timezone (fallback Asia/Shanghai) when user does not specify - Use
--apply only after reviewing dry-run output
macos-calendar-assistant
使用捆绑脚本进行可靠的Calendar.app操作。
工作流程
- 1. 提取标题、开始/结束时间、时区、日历、地点、备注、提醒。
- 写入前检查冲突:
- scripts/list
events.swift <开始时间iso> <结束时间_iso>
- 3. 优先使用幂等写入:
- scripts/upsert_event.py(创建/更新/跳过)
- 4. 如需提醒则应用:
- scripts/set_alarm.py --uid <事件uid> --alarm-minutes <分钟数>
- 5. 为保持整洁,运行重复项扫描:
- scripts/calendar_clean.py --start
--end
日历路由默认规则
- - 锻炼/跑步/训练 → Training
- 工作/会议/客户 → Work
- 产品/开发/构建 → Product
- 个人/社交/旅行 → Life
- 未指定时:优先使用可写的iCloud/CalDAV日历,而非本地日历。
注意:日历名称因用户设置而异。写入前需将意图映射到最接近的本地日历名称。
命令
列出日历
bash
swift scripts/list_calendars.swift
列出时间范围内的事件
bash
swift scripts/list_events.swift 2026-03-06T00:00:00+08:00 2026-03-06T23:59:59+08:00
输出包含uid,用于后续的提醒/编辑操作。
幂等创建/更新(推荐)
bash
python3 scripts/upsert_event.py \
--title 团队同步 \
--start 2026-03-06T19:00:00+08:00 \
--end 2026-03-06T20:00:00+08:00 \
--calendar Work \
--notes 议程 \
--location 在线 \
--alarm-minutes 15
结果为以下之一:CREATED、UPDATED、SKIPPED。
使用--dry-run进行预览。
传统直接添加(始终创建)
bash
python3 scripts/add_event.py --title ... --start ... --end ...
按UID设置提醒
bash
python3 scripts/set_alarm.py --uid 事件UID --alarm-minutes 15
移动事件(传统工具)
bash
swift scripts/move_event.swift 团队同步 Work 2026-03-07T10:00:00+08:00 60 --search-days 7
可选精确匹配:
--original-start 2026-03-06T10:00:00+08:00
大多数重新安排流程优先使用upsertevent.py;需要时可直接使用moveevent.swift进行基于标题的移动。
重复项扫描/清理
bash
python3 scripts/calendar_clean.py --start 2026-03-01T00:00:00+08:00 --end 2026-03-08T23:59:59+08:00
python3 scripts/calendar_clean.py --start ... --end ... --apply --confirm yes --snapshot-out ./delete-plan.json
即将发生的事件(2小时内)
bash
python3 scripts/within_2h.py
环境检查与测试
bash
python3 scripts/env_check.py
python3 scripts/regression_test.py
scripts/smoke_test.sh
每日自动检查通知
bash
scripts/install.sh # 运行环境检查并从config.json安装cron
scripts/uninstall.sh # 移除cron
提取与排程启发式规则(来自实际使用)
- 1. 从聊天截图判断发言者归属
- 将用户的消息气泡视为主要意图。
- 将对方的气泡视为约束条件(可用性/出行时间窗口),而非直接自动创建任务。
- 2. 冲突处理策略
- 如果用户明确说覆盖(例如替换这个时间段),允许替换现有时间段并重新安排被替换的事件。
- 如果不明确,在覆盖前发出警告并询问选择。
- 3. 时间窗口意图解析
- 像对方下午4-6点有空这样的表述应首先解读为可用性时间窗口。
- 仅在用户确认后才转换为正式事件。
- 4. 重新安排优先级
- 优先移动灵活事件(锻炼/可选时间段),再移动战略性P0工作块。
- 除非用户明确要求,否则不自动移动P0项目。
- 5. 确认提示模板
- 使用:我识别到X是您的意图,Y是对方的约束条件。我将应用Z。确认?
- 保持简短;当意图明确时避免过度确认。
约束条件
- - 仅限macOS(需要EventKit + 日历权限)
- 默认时区来自config.json.timezone(用户未指定时默认为Asia/Shanghai)
- 仅在审查dry-run输出后使用--apply