運営中

Vigilare

Appleリマインダーをフローティングウィンドウで常に最前面に表示するmacOSアプリ。

何を解いているか

タスクは、見ていないあいだに忘れられます。macOSではタスク管理アプリもウィンドウのひとつなので、エディタやブラウザをフルスクリーンにした時点で視界から消えます。呼び戻すには、いま集中していることを一度手放さなければなりません。Vigilareが扱っているのはこの一点です。

なぜ作ったか

新しいタスク管理サービスを作る選択はしませんでした。Macにはすでに Apple リマインダーがあり、iCloud同期も、iPhoneからの入力も動いています。足りていないのは保管場所ではなく、それを見続ける方法でした。 Vigilare は EventKit 越しに Apple リマインダーを読み書きするだけのアプリとして作っています。データはVigilareの中に入りません。アプリを消してもリマインダーは残り、標準のリマインダーアプリと同時に開いていても構いません。移行作業が要らないので、合わなければ消すだけで終わります。

設計の判断

  • タスクの実体は Apple リマインダーに置く

    EventKit越しにAppleリマインダーを読み書きし、タスクを保存する独自のデータベースは持っていません。 CoreDataもSwiftDataも使っていません。 同期基盤やアカウントを作らない代わりに、純正アプリや他の端末との共存を最初から得ています。 Vigilare側に残るのは、ウィンドウの位置などの表示状態だけです。

    Vigilare のデータの持ち場所を、Apple が持つ側と Vigilare が持つ側に分けて示した図。Apple リマインダー(EventKit)の側に、リスト、リマインダーと期日、繰り返しルール、本文、ステータス、コメントというタスクの実体すべてがあり、同じストアを macOS 版 Vigilare、iOS 版 Vigilare、純正リマインダーアプリの 3 つが共有して読み書きする。タスクを保存する独自データベースは持たず、CoreData も SwiftData も使っていないため、同期や純正アプリとの共存は Apple の仕組みがそのまま働く。Vigilare が持つのは 2 つだけで、iCloud キー値ストアにアーカイブしたリストと 2 つの表示フラグ、この端末の UserDefaults にウィンドウの位置・サイズとウィンドウレベル・表示 Space が入る。
    タスクの実体は Apple 側にあり、Vigilare 側には表示の状態しか残らない
  • ステータスとコメントはノート欄に置く

    EventKitにはステータスもコメントも項目がありません。 別のテーブルを作ってIDで紐付けるのではなく、リマインダーのノート欄にYAML frontmatterとして書き、表示のときだけ外しています。 純正アプリではメタデータも文字として見えますが、同期はリマインダー本体と同じ経路に乗ります。

    EventKit のノート欄という 1 つのフィールドの中身を、上下 2 つの範囲に分けて示した図。reminder.notes の上側の範囲は Vigilare が足したメタデータで、3 本のハイフンに挟まれた YAML frontmatter として status に waiting、comments に JSON 文字列が入っている。下側の範囲はユーザーが書いたもとの本文。この 1 つの文字列を読む 2 者が右に並ぶ。Vigilare は frontmatter を外し、本文の範囲だけを本文として扱う。純正リマインダーアプリは範囲を区別せずノート欄全体を読むため、メタデータも本文と同じ文字として画面に出る。これがこの 1 フィールドに乗せる代わりに引き受けた代償である。
    ノート欄という 1 フィールドを、メタデータと本文の 2 つの範囲として使う
  • EventKit に触るのは常駐プロセスだけ

    MCPクライアントが起動するプロセスは、EventKitに触りません。 16個のツールのうち権限の要らない2つだけを自分で答え、残りはソケット越しに常駐プロセスへ毎回渡しています。 in-processの代替経路を置いていないので、MCPが使えるかは設定を有効にしたかどうかだけで決まります。

    MCP 経由でリマインダーを操作するときの経路を、権限の境界で区切って示した図。Claude Code や Claude Desktop などの MCP クライアントが標準入出力で Vigilare を --mcp として起動する。この --mcp プロセスは自分では EventKit に触らない。16 個のツールのうち EventKit を必要としない vigilare_ping と vigilare_get_settings の 2 つだけを自分で答え、残りの 14 個は Unix ドメインソケット経由で常駐プロセスへ、呼び出しごとに接続し直して渡す。EventKit に触るのは破線で囲まれた内側だけで、そこには --daemon として動く常駐プロセスがある。SMAppService の LaunchAgent として、設定で有効化するまで launchd に登録されず、オフにすれば登録も消える。その常駐プロセスから EventKit、さらに Apple リマインダーへ到達する。EKEventStore を生成している箇所はプロジェクト全体で 1 か所だけ。
    EventKit に触るのは常駐プロセスの内側だけ。境界を越えるのはソケット 1 本
  • 共有するのはコア、分けるのは View

    Model・UseCase・ViewModelはVigilareKitにまとめ、iOS側はViewだけを持つ構造にしています。 20ファイルのうち19がVigilareKitをimportし、編集画面のViewModelはmacOSと同じものを使います。 複数選択やドラッグのようなmacOS固有の仕組みは、アプリ側に残しています。

    macOS 版と iOS 版の構成を上下 2 段で示した図。上段は左右に分かれ、左の macOS アプリは View が 36 ファイル、MCP が 7 ファイル、ウィンドウ制御が 2 ファイルあり、複数選択やドラッグのペイロード、キーボードショートカットといった macOS 固有の ViewModel 3 ファイルと Model 3 ファイルもここに残している。右の iOS アプリが持つのは View 19 ファイルとアプリのエントリ 1 ファイルだけで、20 ファイルのうち 19 が VigilareKit を import し、編集画面の ViewModel は macOS と同じものを使う。上段の 2 つは 1 本に合流して下段の VigilareKit に入る。VigilareKit は 68 ファイルで、Models 12、ViewModels 5、UseCases 10、Stores 3、Services 5、Utilities 22、DesignSystem 8 を両 OS が同じものとして使う。
    View だけを OS ごとに分け、その下は VigilareKit に合流する

提供形態

対応プラットフォーム
macOS / iOS / iPadOS
動作要件
macOS 15.4 以降(Apple Silicon / Intel)
価格
macOS版は買い切り、iOS / iPadOS版は無料
配布
App Store
データの保存先
Appleリマインダー(iCloud同期)。Vigilare側にデータベースを持ちません
AI連携
MCPサーバー内蔵
プラットフォーム
  • macOS
  • iOS
  • iPadOS

開発の記録

Vigilareを作るなかで書いた記事です。

ほかのプロダクト

同じプラットフォーム向けに作っているものです。

← 自社プロダクト一覧へ