calendar-event-manager について
Calendar Event Manager は、macOS Calendar のイベントと Reminders のリマインダーを併せて作成するスキルです。段階別のサウンド通知と検証手順により、設定時の見落としを抑えます。
主な機能
- 01Calendar イベントと Reminders の併設
- 02音を使い分ける段階別アラーム
- 03早朝イベントの通知時刻ガイド
- 04AppleScript による日時設定とカレンダー検索
- 05作成後のアラームとリマインダーの検証
活用シーン
- 01招待や説明からのイベント作成
- 02予定に段階的な通知を設定
- 03Calendar と Reminders の通知テスト
- 04アラームとリマインダーの保存確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill calendar-event-managerインストール後、Claude Code で/calendar-event-managerを入力して読み込まれたか確認します。
同梱ファイルreferences/evolution-log.mdreferences/sound-reference.md
詳細
カレンダーイベントマネージャー
段階的なサウンドアラームと連携するリマインダーを使って macOS カレンダーのイベントを作成し、Mac と iOS の両方で予定を見逃さないようにします。
自己進化型スキル:このスキルは使用を通じて改善されます。手順に誤りがある、パラメーターが変化している、または回避策が必要になった場合は、先延ばしにせず、すぐにこのファイルを修正してください。実際に再現できる問題がある場合にのみ更新します。
重要なルール(2026-02-12に得られた重要な教訓)
以下のルールは絶対に守る必要があります。ひとつでも違反すると、このスキルの目的が損なわれます。
1. カレンダーとリマインダーは必ずセットで作成する
すべてのイベントで、次の両方を必ず作成します。
- 複数の
sound alarmエントリーを含むカレンダーイベント(各段階にカスタムサウンドを設定) - 別の通知チャネルとしてのリマインダー(最低3件)
片方だけを作成してはいけません。
2. display alarm ではなく sound alarm を使う
-- CORRECT: audible alert with custom sound
make new sound alarm at end of sound alarms with properties {trigger interval:-60, sound name:"Glass"}
-- WRONG: silent visual banner only
make new display alarm at end of display alarms with properties {trigger interval:-60}
各アラームは独自の sound name プロパティを設定できます。アラートの段階ごとに異なるサウンドを使い、音だけでアラートレベルがわかるようにしてください。
3. 長いサウンドのみ使用する(>= 1.4 秒)
短いサウンドは聞き逃され、無視されます。1.4秒未満のサウンドは絶対に使わないでください。
使用を承認済みのサウンドのみ:
| サウンド | 長さ | 用途 |
|---|---|---|
| Funk | 2.16s | イベント時刻(最も大きな音) |
| Glass | 1.65s | 1時間前 |
| Pop | 1.63s | 当日朝/3時間前 |
| Sosumi | 1.54s | 前日 |
| Ping | 1.50s | 30分前 |
| Submarine | 1.49s | 代替 |
| Blow | 1.40s | 早めの穏やかなリマインダー |
使用禁止のサウンド: Hero、Basso、Bottle、Purr、Frog、Morse、Tink(すべて1.4秒未満)
4. 複数の早めのリマインダーを必ず設定する
カレンダーでイベントごとに設定できるアラームは最大5件です(2026-08-17にCalDAVカレンダーで確認済み:6件目を追加するとエラーなしで先に追加したアラームがひとつ削除されます)。5枠を計画的に使い、同じ時刻に鳴るリマインダーがすでにある場合は重複させるために枠を使わないでください。
デフォルトのアラーム段階:
| 段階 | トリガー | カレンダーのサウンド | リマインダー |
|---|---|---|---|
| 1日前 | -1439 min | Blow | "TOMORROW: ..." |
| 前夜 | -720 min | Sosumi | — |
| 1時間前 | -60 min | Glass | (カレンダー経由) |
| 30分前 | -30 min | Ping | (カレンダー経由) |
| イベント時刻 | 0 min | Funk | 期限時刻のリマインダー |
さらに、リマインダーを3件作成します:"TOMORROW:"(前日の午前9時)、"TODAY:"(当日朝)、期限時刻のリマインダーです。
-1440ではなく、必ず-1439を使ってください。 1440分(24時間)のオフセットを正確に指定すると、カレンダーによって警告なしに破棄され、読み戻してもアラームが表示されません。2026-08-17に2回確認済みです。
-1439は保持されます。
早朝のイベント(午前9時30分頃より前)
デフォルトの段階設定は早朝のイベントでは適切に機能しません。次のように調整してください。
- 当日朝の午前9時のリマインダーは、午前8時30分のイベントより後に鳴ります。イベントの約90分前に移動してください。
- 午前8時30分のイベントで**-180 minの段階を設定すると、午前5時30分に鳴り、ユーザーを3時間も早く起こしてしまいます。この設定は削除し、前夜の-720**の段階を使ってください。
5. macOSの通知設定が必須
カレンダーの通知は、システム設定で有効にする必要があります。
- システム設定 > 通知 > カレンダー > 通知を許可 = ON
- 通知スタイル = バナーまたは通知
- サウンドを再生 = ON
次のコマンドで開きます:open "x-apple.systempreferences:com.apple.Notifications-Settings.extension"
TodoWriteのタスクテンプレート
テンプレートA:招待からイベントを作成
1. Extract event details (title, date, time, location, notes, RSVP)
2. Create Calendar event with 5-tier sound alarms (Blow, Sosumi, Glass, Ping, Funk)
3. Create 3 Reminders (TOMORROW, TODAY morning, due-time)
4. Verify event and reminders created
5. Report full schedule to user
テンプレートB:ユーザーの説明からイベントを作成
1. Ask user for: event name, date/time, duration, location
2. Create Calendar event with 5-tier sound alarms (max Calendar allows)
3. Create 3 Reminders
4. Verify event and reminders created
5. Report full schedule to user
テンプレートC:通知設定をテスト
1. Create test Calendar event 3 min in future with sound alarms (1 min, 2 min tiers)
2. Create test Reminder 2 min in future
3. Wait for user confirmation of notifications
4. Clean up test event and reminders
AppleScriptでの日付の構築(重要)
AppleScriptではdate "STRING"を絶対に使用しないでください。 文字列ベースの日付解析はロケールに依存し、気付かないうちに誤った結果を生成します。
| アンチパターン | 起きること | 例 |
|---|---|---|
date "April 1, 2026 at 6:00:00 PM" | 24時間制のシステムでは「PM」が無視され、06:00になります | 個人セッションで4件の失敗 |
date "2026-04-01 18:00:00" | ISO形式が個別の数値として解析され、年が12169になります | 1件の失敗 |
set day to 1より前にset month | 31日から4月(30日)に設定すると、5月1日に繰り越されます | 1件の失敗 |
必ずプログラムで日付を構築してください。
-- Build date safely: day-first-then-month prevents rollover
set d to current date
set day of d to 1 -- safe floor FIRST (prevents month rollover)
set month of d to April
set year of d to 2026
set day of d to 1 -- now set actual target day
set hours of d to 18 -- 24h format, no AM/PM ambiguity
set minutes of d to 0
set seconds of d to 0
カレンダーの検出(最初に実行)
tell application "Calendar"
set output to ""
repeat with c in calendars
set output to output & name of c & " (writable:" & writable of c & ")" & linefeed
end repeat
output
end tell
最初のwritable:trueカレンダーを使用してください。「Home」や「Calendar」が存在すると決めつけないでください。
イベントの完全な作成(コピーしてすぐに使用可能)
tell application "Calendar"
-- Build start date programmatically
set startDate to current date
set day of startDate to 1
set month of startDate to MONTH_CONSTANT
set year of startDate to YEAR_INT
set day of startDate to DAY_INT
set hours of startDate to HOUR_24
set minutes of startDate to 0
set seconds of startDate to 0
-- Build end date (1 hour later)
set endDate to startDate + 1 * hours
tell calendar "WRITABLE_CALENDAR_NAME"
set newEvent to make new event with properties {summary:"EVENT_NAME", start date:startDate, end date:endDate, location:"LOCATION", description:"NOTES"}
tell newEvent
-- EXACTLY 5 alarms: a 6th silently evicts one of these.
-- -1439 not -1440: an exact 24h offset is silently dropped.
make new sound alarm at end of sound alarms with properties {trigger interval:-1439, sound name:"Blow"}
make new sound alarm at end of sound alarms with properties {trigger interval:-720, sound name:"Sosumi"}
make new sound alarm at end of sound alarms with properties {trigger interval:-60, sound name:"Glass"}
make new sound alarm at end of sound alarms with properties {trigger interval:-30, sound name:"Ping"}
make new sound alarm at end of sound alarms with properties {trigger interval:0, sound name:"Funk"}
end tell
end tell
reload calendars
end tell
検証(作成後に必ず実行)
検証は任意ではありません。このファイルに記録されたすべての失敗は気付かれないものでした。作成処理は、いずれの場合も成功を返していました。
tell application "Calendar"
tell calendar "WRITABLE_CALENDAR_NAME"
set e to first event whose summary contains "EVENT_NAME"
set out to (summary of e) & " | " & (start date of e) & " -> " & (end date of e) & linefeed
-- Read BOTH classes: Calendar reports sound alarms back as display alarms.
set out to out & "alarms=" & ((count of display alarms of e) + (count of sound alarms of e)) & linefeed
repeat with a in display alarms of e
set out to out & " " & (trigger interval of a) & linefeed
end repeat
repeat with a in sound alarms of e
set out to out & " " & (trigger interval of a) & linefeed
end repeat
return out
end tell
end tell
アラームの件数と各トリガーの間隔を確認してください。イベントが存在することだけを確認してはいけません。アラームの欠落は、最もよくある気付かれない失敗です。
カレンダーのAppleScriptブリッジの制限事項(2026-08-17に確認)
| 試した操作 | 結果 | 代わりに行うこと |
|---|---|---|
repeat with e in (every event whose summary …) | error -1728、"Can't get item 1" | まずuid of (every event whose …)を収集し、その後、uidごとに削除または操作します |
count of (every alarm of e) | syntax error -2741、alarmクラスが存在しません | display alarmsとsound alarmsを別々に数えます |
delete (first display alarm whose …) | error -10000、AppleEventハンドラーの失敗 | 個別のアラームは削除できません。イベント全体を作り直してください |
delete display alarm <index> | error -10000 | 同様に、イベントを作り直してください |
作成したアラームのsound nameを読み戻す | サウンドアラームは0件、ディスプレイアラームはN件と報告されます | 想定どおりです。sound nameはEventKitレベルで保持されます。サウンドアラームは作成してください |
リマインダーと連動するイベントの作成
default listは絶対に使用しないでください。 このマシンでは、文字どおりDEFAULT_TASK_CALENDAR_NAMEという名前の空のプレースホルダーリスト(置換されていないテンプレート文字列)として解決されます。make new reminder in (default list)は成功を返しますが、何も書き込みません。完全に気付かれない失敗です。まず名前で実際のリストを検出し、それを明示的に指定してください。
-- Discover lists FIRST; never assume.
tell application "Reminders"
set out to ""
repeat with l in lists
set out to out & name of l & " count=" & (count of reminders in l) & linefeed
end repeat
return out
end tell
tell application "Reminders"
-- Target the real list BY NAME (usually "Reminders"), not `default list`.
set targetList to list "Reminders"
-- Build date programmatically (same pattern as Calendar)
set eventDate to current date
set day of eventDate to 1
set month of eventDate to MONTH_CONSTANT
set year of eventDate to YEAR_INT
set day of eventDate to DAY_INT
set hours of eventDate to HOUR_24
set minutes of eventDate to 0
set seconds of eventDate to 0
-- CRITICAL: `copy`, not `set`. `set x to eventDate` ALIASES the same date
-- object, so mutating x silently rewrites eventDate too (this corrupted a
-- due-time reminder to 07:00 on 2026-08-17). `copy` makes a real clone.
copy eventDate to morningDate
set hours of morningDate to 7
set minutes of morningDate to 0
set seconds of morningDate to 0
copy eventDate to dayBefore
set dayBefore to dayBefore - 1 * days
set hours of dayBefore to 9
set minutes of dayBefore to 0
set seconds of dayBefore to 0
make new reminder in targetList with properties {name:"NOW: EVENT_NAME", due date:eventDate, body:"LOCATION" & linefeed & "NOTES"}
make new reminder in targetList with properties {name:"TOMORROW: EVENT_NAME", due date:dayBefore, body:"Event tomorrow! LOCATION"}
make new reminder in targetList with properties {name:"TODAY: EVENT_NAME", due date:morningDate, body:"Today! LOCATION"}
end tell
body:には& linefeed &を使用する必要があることに注意してください。AppleScriptの文字列内のリテラルな\nは改行ではなく、バックスラッシュとnの2文字です。
変更後のチェックリスト
このスキルを変更した後:
- サウンドのリファレンステーブルがsound-reference.mdと一致している
- 5段階すべてのアラームが、正しいサウンドとともに記載されている(Calendarの上限は5件)
- 使用禁止サウンドのリストが完全である
- フックファイル(
hooks/calendar-reminder-sync.ts)がスキルのルールに準拠している - AppleScriptの例で
display alarmではなくsound alarmを使用している
参考資料
- サウンドのリファレンス - サウンドの長さに関するすべてのデータと、承認済み/却下済みリスト
- Apple Calendarスクリプティングガイド
実行後の振り返り
このスキルの実行後、終了する前に次の点を確認してください。
- コマンドは成功しましたか? — 成功していない場合は、失敗の原因となった手順またはエラーテーブルを修正します。
- パラメーターや出力に変更はありましたか? — 基盤となるツールのインターフェースに変更があった場合は、使用例とパラメーターテーブルを更新して一致させます。
- 回避策が必要でしたか? — 別のフラグや追加手順など、その場で工夫する必要があった場合は、次回の実行で同じ回避策が不要になるよう、この SKILL.md を更新します。
問題が実際に発生し、再現可能な場合にのみ更新してください。推測で更新しないでください。