Skip to content
Conduit

skill

IntentTodo

App Intents中心設計で作るToDoアプリ

touyou/IntentTodocommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/touyou/IntentTodo itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 22, 2026

IntentTodo

App Intents 中心設計に基づいたマルチプラットフォーム Todo アプリです。

特徴

  • App Intents 中心設計: すべてのアクションを App Intent として定義し、Button(intent:) で統一的に実行
  • SwiftData: モダンなデータ永続化(CloudKit対応)
  • マルチプラットフォーム: iOS / iPadOS / macOS(ネイティブ)/ watchOS / visionOS 対応
  • Extension対応: Widget / Live Activity / Control Center / Complication / Siri Shortcuts / Spotlight / 集中モード
  • WWDC 2026 の App Intents 要素を網羅検証: App Schema / Visual Intelligence / AppIntentsTesting / UndoableIntent / LongRunningIntent / SyncableEntity など(採用状況は docs/APP_INTENTS_API_COVERAGE.md)
  • TDD: テスト駆動開発で実装

要件

  • iOS 27.0+ / macOS 27.0+ / watchOS 27.0+ / visionOS 27.0+
  • Xcode 27.0+
  • Swift 6.0+

App Intents 中心設計の適応状況

プラットフォーム別

5 プラットフォームとも出荷済み(1.1.4)で、各面を一通り触っている。 下の「検証状況」は画面とアクションが実機で動いていることを指す。 Siri の音声経路 / Spotlight の実 UI での見え方 / 通知の cold start など、 出荷しただけでは分からないものは #30 に残っている。

プラットフォーム実行パターンAppIntent活用検証状況
iOS / iPadOSButton(intent:)✅ 全アクション✅ リリース済み
macOS(ネイティブ、Catalyst ではない)Button(intent:)(メニューバー / コンテキストメニュー含む)✅ 全アクション✅ リリース済み(メニュー / キーボードは 2026-09-10 に個別確認)
watchOSButton(intent:)✅ 全アクション✅ リリース済み
visionOSButton(intent:) + Spatial UI✅ 全アクション✅ リリース済み

Extension別

Extension実行パターン備考
Home WidgetButton(intent:) / Link(destination:)Small / Medium / Large / ExtraLargePortrait。単純なアプリ起動は Link が公式推奨(公式ドキュメント)。行タップは TodoDeepLink 経由で該当 Todo の詳細へ
Control CenterControlWidgetButton(action:) / ControlWidgetToggle(isOn:action:)クイック追加 / 未完了数 / 完了トグル(対象を設定で固定)。値の供給は ControlValueProvider、kind は reverse-DNS 形式必須
Live ActivityButton(intent:)ToggleTodoCompletionIntent / QuickSnoozeTodoIntent が LiveActivityIntent に条件付き準拠
Siri / ShortcutsAppShortcutsProvider8 件。うち 5 件はフレーズにパラメータを埋め込み
SpotlightIndexedEntity + @Property(indexingKey:)iOS / macOS。名前付き index + client state バッチ
Visual IntelligenceIntentValueQuery + .visualIntelligence.semanticContentSearchiOS / macOS(#if canImport(VisualIntelligence))
集中モードSetFocusFilterIntentカテゴリ / 急ぎのみ / 完了を隠す。リストとウィジェットの両方に効く
Complication (watchOS)表示のみCircular / Corner / Rectangular / Inline

定義済み AppIntent 一覧(25 本)

すべての Intent を TodoAppIntents SPM パッケージに集約。Extension からも import TodoAppIntents で参照する。 SwiftData を書き換える Intent は allowedExecutionTargets = [.main] を宣言する(表の「本体固定」列)。

Intentプロトコル / 特徴Mode本体固定用途
AddTodoIntentOpensIntent + @AppIntent(schema: .reminders.createReminder).background✅Todo 追加
UpdateTodoIntentIntentParameter.valueState + @AppIntent(schema: .reminders.updateReminder).background✅部分更新(新値 / 明示クリア / 据え置き)
ToggleTodoCompletionIntentUndoableIntent + LiveActivityIntent(iOS).background✅完了切替(完了時に Live Activity を終了)
SetTodoCompletionIntentSetValueIntent(内部用).background✅完了状態の絶対値セット(Control のトグル用)
CompleteTodosIntentLongRunningIntent + CancellableIntent + EntityCollection.background✅バルク完了(進捗 / キャンセル対応)
DeleteTodoIntentUndoableIntent + requestConfirmation.background✅削除(確認あり。Siri / Shortcuts 用)
DeleteTodoImmediatelyIntentUndoableIntent(内部用).background✅削除(確認なし。UI は .confirmationDialog で確認してから呼ぶ)
DeleteTodosIntentDeleteIntent + UndoableIntent + @AppIntent(schema: .reminders.deleteReminders).background✅バルク削除
ToggleFavoriteIntent—.background✅お気に入り切替
SnoozeTodoIntentrequestChoice.background✅スヌーズ(期間を選ばせる)
QuickSnoozeTodoIntentLiveActivityIntent(内部用).background✅スヌーズ 30 分即実行(Live Activity のボタン用)
ToggleUrgentTodoIntent—.background✅最緊急 Todo の完了切替(Control 用)
ReorderTodosIntent内部用.background✅並び替え(UI 専用)
ShowTodosIntentIntentDialog(full:supporting:) + ShowsSnippetIntent.background—Todo 表示(filter で絞り込み。一覧はスニペットで見せ、アプリは開かない)
ShowTodoCountIntent—.background—未完了数を通知で表示(Control 用)
GetTodoSummaryIntentTransientAppEntity を返す.background—統計サマリ(Shortcuts の条件分岐に使える)
SearchEverythingIntent@UnionValue.background—Todo + Category 横断検索
ShowTodoSearchResultsIntent@AppIntent(schema: .system.searchInApp)(watchOS 除外)——Siri からアプリ内検索 UI へ
CreateSectionIntent@AppIntent(schema: .reminders.createSection)(watchOS 除外).background—リスト配下にセクションを作る
TodoSemanticContentSearchIntent@AppIntent(schema: .visualIntelligence.semanticContentSearch)——Visual Intelligence の「もっと見る」
OpenTodoIntentOpenIntent + URLRepresentableIntent + UISceneAppIntent + @AppIntent(schema: .system.open).foreground(.immediate)—Todo 詳細を開く(Spotlight / ウィジェットのタップ先)
OpenCategoryIntentOpenIntent + @AppIntent(schema: .system.open).foreground(.immediate)—カテゴリを開く(Mac の visual search 要件)
LaunchAppIntentTargetContentProvidingIntent(iOS/visionOS) + UISceneAppIntent.foreground(.immediate)—画面指定でアプリ起動
TodoFocusFilterIntentSetFocusFilterIntent.background—集中モード連携
TodoSnippetIntent / TodoSummarySnippetIntentSnippetIntent(内部用)——Siri 応答のインタラクティブ表示

Entity / Query

型種別備考
TodoAppEntityAppEntity + IndexedEntity + SyncableEntity + Transferable + URLRepresentableEntity@ComputedProperty / @DeferredProperty / @Property(indexingKey:) / IntentPerson・PlaceDescriptor への ValueRepresentation
CategoryAppEntityAppEntity@AppEntity(schema: .reminders.list)(watchOS は素の AppEntity にフォールバック)
SubTaskAppEntityAppEntity—
TodoListSummaryEntityTransientAppEntityGetTodoSummaryIntent の戻り値
TodoSectionAppEntity@AppEntity(schema: .reminders.section)カテゴリ配下のセクション(watch は WatchTodoSectionAppEntity)
TodoAttachment@Model(.externalStorage)todo に付けた画像。IntentFile とは TodoAttachments で往復
TodoOrCategory@UnionValue横断検索 / Visual Intelligence の結果型
TodoEntityQueryEntityQuery + EntityStringQuery + EnumerableEntityQuery + IndexedEntityQueryShortcuts の Find は EnumerableEntityQuery で自動生成される
CategoryEntityQuery / SubTaskEntityQueryEntityQuery + EntityStringQuery—
TodoVisualIntelligenceQueryIntentValueQuerySemanticContentDescriptor → [TodoOrCategory]

アーキテクチャ

IntentTodo/
├── IntentTodo/                  # アプリターゲット (App.init で AppDependencyManager 登録)
│   ├── TodoAppShortcuts.swift   # ★AppShortcutsProvider はここ必須(パッケージ不可)
│   └── SceneDelegate.swift      # AppIntentSceneDelegate(cold start のナビゲーション)
├── IntentTodoWidget/            # Widget + Control Center (WidgetBundle.init でも登録)
├── IntentTodoLiveActivity/      # Live Activity
├── IntentTodoWatchApp/          # watchOS アプリ + Complication
├── IntentTodoUITest/            # XCUITest + AppIntentsTesting(Intent の実経路テスト)
└── Packages/
    ├── Domain/                  # データモデル(SwiftData @Model), ActivityAttributes
    ├── Repository/              # データアクセス層
    ├── TodoAppIntents/          # ★コア:全 Intent + TodoService + Entity / Query + ヘルパー
    ├── UI/                      # iOS/iPadOS/macOS/visionOS の Views, ViewModels
    ├── LiveActivity/            # ActivityKit 管理 + ロック画面 View(iOS 限定)
    ├── WidgetUI/                # ホームウィジェットの View
    └── WatchUI/                 # watchOS の View + Complication View(watchOS 限定)

依存関係

Domain ← Repository ← TodoAppIntents ← UI / LiveActivity / WidgetUI / WatchUI ← App / Extensions

DI パターン

@Dependency var todoService: TodoService / @Dependency var navigationModel: NavigationModel で Intent から共有状態にアクセス。AppDependencyManager.shared.add(dependency:) を App.init() と WidgetBundle.init() で同期登録することで、各プロセスで @Dependency が解決される。

呼出元 / モード実行プロセス登録場所
Siri / Shortcuts / UIメインアプリApp.init()
Widget Button(intent:) + .foreground(.immediate)メインアプリApp.init()
書き込み系(allowedExecutionTargets = [.main])メインアプリに固定App.init()
読み取り系 + Widget / Control 起点ヒューリスティクスで決定(アプリ起動中は本体優先、未起動なら Extension)両方(WidgetBundle.init() も必要)

登録漏れはクラッシュせず「無音の失敗」になる(stderr に Failed to retrieve dependency of type X が出るだけで、Button(intent:) 経由では画面が何も変わらない)。そのプロセスで走る Intent が触る依存は全部登録する。

設計思想

従来の MVVM では ViewModel や UseCase にビジネスロジックを配置しますが、本プロジェクトでは App Intent がアプリ機能の唯一の入口 です。UseCase 層をパッケージとして持たない代わりに、ユースケースの宣言(名前・引数・戻り値)を App Intent が、実装(手続き・不変条件・副作用)を TodoService が受け持ちます。

Layered / Clean Architecture との対比(対応表・砂時計図・コードの置き場を決める判定ルール)は docs/APP_INTENT_DRIVEN_DESIGN.md にまとめています。

役割分担

責務担当
ユースケースの宣言(名前・パラメータ・システムへの公開)App Intents
ビジネスロジック(CRUD、バリデーション、変更後の後処理)TodoService
永続化(1 レコードの CRUD)TodoRepositoryProtocol
UI状態管理(フィルター、ソート、検索テキスト)ViewModel

Button(intent:) による宣言的なIntent実行

import AppIntents  // ← 必須

// ✅ 推奨: Button(intent:) を直接使用
Button(intent: ToggleTodoCompletionIntent(todo: entity)) {
    Image(systemName: "checkmark.circle")
}

// フォーム入力が必要な場合は Computed Property で動的生成
private var addTodoIntent: AddTodoIntent {
    AddTodoIntent(title: title, dueDate: dueDate)
}

Button(intent: addTodoIntent) {
    Text("Add")
}
  • Siri/ショートカットと同じ実行経路
  • Task/async のボイラープレートが不要
  • SwiftData の @Query と組み合わせてリアクティブな更新

セットアップ

  1. リポジトリをクローン
git clone https://github.com/touyou/IntentTodo.git
cd IntentTodo
  1. Xcode でプロジェクトを開く
open IntentTodo.xcodeproj
  1. ビルド & 実行

テスト

3 層で分担している(詳細は docs/TESTING.md)。

層場所実行方法
ユニット(Repository / TodoService / Intent の静的メタデータ)Packages/*/Tests/cd Packages/<name> && swift test
AppIntentsTesting(Intent を実経路で実行 / Query / Spotlight / onscreen annotation)IntentTodoUITest/AppIntents/Xcode の IntentTodoUITest スキーム(UI テストバンドル必須)
XCUITest(UI 経路だけで壊れるもの)IntentTodoUITest/同上
cd Packages/Domain && swift test
cd Packages/Repository && swift test
cd Packages/TodoAppIntents && swift test
cd Packages/UI && swift test

提出用スクリーンショット

./scripts/capture_screenshots.sh              # 全プラットフォーム × ja / en
./scripts/capture_screenshots.sh iphone       # 一部だけ撮り直す

DEBUG 限定の ScreenshotFixture(Domain)が in-memory ストアに ja / en それぞれのサンプルを 流し込むので、何度撮っても同じ画面になる。出力は Screenshots/<platform>/<locale>/(gitignore)。

プラットフォーム撮り方画素数
iPhone 17 Pro Max / iPad Pro 13" / Apple Watch UltraXCUITest が操作して XCUIScreen.main.screenshot() を添付1320x2868 / 2064x2752 / 422x514
MacXCUITest が起動引数 -uitest-screenshot-screen で画面を選び、ウィンドウだけを撮る2880x1800
Apple Vision Prosimctl io screenshot(部屋ごと撮る)。画面の選び方は Mac と同じ3840x2160

いずれも App Store Connect が受け付ける寸法。ASC へ入れる文言は docs/APP_STORE_LISTING.md。

App Shortcuts

8 件を IntentTodo/TodoAppShortcuts.swift(アプリターゲット直下)で定義。 フレーズにはできるだけパラメータ(AppEntity / AppEnum)を埋め込んでいる。

フレーズ(代表)機能
Add a todo in IntentTodoTodo 追加
Show my <filter> todos in IntentTodoTodo 一覧表示(フィルタ付き)
Complete <todo> in IntentTodo完了切替
Star <todo> in IntentTodoお気に入り切替
Delete <todo> in IntentTodo削除
Snooze <todo> in IntentTodoスヌーズ
Toggle urgent todo in IntentTodo最緊急 Todo の完了切替
Show todo count in IntentTodo未完了数

Agent Skills として配布

このリポジトリは、本プロジェクトで蓄積した App Intent 中心設計の知見を Agent Skills として再利用できる形で同梱しています。Claude Code / Codex / Gemini CLI / GitHub Copilot / Cursor で同じファイルが動きます。

  • 配布物: skills/ 配下の 9 skill + plugin.json(Agent Plugins)/ .claude-plugin/ / .agents/plugins/ のマニフェスト
  • 場面ごとに分割されていて、「ウィジェットにボタンを付けたい」「押しても何も起きない」「訳が反映されない」のようにやりたいこと / 症状で発火する
  • 各 skill の分担とスクリプトは skills/README.md、エージェント別のインストールと公開手順は skills/INSTALL.md を参照
skill場面
app-intents-centric-design入口。11 の非交渉ルール・導入レベル・症状の振り分け
app-intents-design-session対話でユースケースを洗い出し、Intent / Entity 集合・サーフェス割当・名前とコピーまで決める進行役
app-intents-system-surfacesどのシステムサーフェスに出すか(ウィジェット / コントロール / Watch / カメラ / 集中モード)
app-intents-execution-and-processes実行プロセス・@Dependency 登録・パッケージ配置・プラットフォーム可用性
app-intents-ui-and-feedbackButton(intent:)・ナビゲーション・dialog / snippet / 通知
app-intents-parameters-and-promptsパラメータと parameterSummary・確認 / 選択・部分更新
app-intents-entities-and-searchEntity 設計・Spotlight・App Schema・大量データ
app-intents-testingAppIntentsTesting・メタデータ検査・緑になる嘘テスト
app-intents-localizationIntent コピーと Siri フレーズのローカライズ

ドキュメント

現在のルール

  • AGENTS.md - エージェント / 開発者向けの入口(環境・非交渉ルール・全ドキュメントの目次)
  • docs/AGENTS.md - App Intents 中心設計ガイド(思想・核心原則・実装時に確認すること)
  • docs/APP_INTENT_DRIVEN_DESIGN.md - 関連概念の整理と比較(Layered / Clean Architecture との対比)
  • docs/CODING_GUIDELINES.md - Swift / SwiftUI / ローカライズ / コメントの規約
  • docs/TESTING.md - テストの 3 層と「緑になる嘘テスト」を避けるルール
  • docs/INSIGHTS.md - 開発中に得られた技術的インサイト(目次→7トピック別ファイル)

API の地図

経緯と残タスク

  • docs/devlog/ - 各ルールがどういう調査・失敗・再検証を経て今の形になったか
  • GitHub issues - これからやること(実機検証 #30 / GM SDK 棚卸し #57 / 未採用 API の消化 #68)
  • docs/presentation/ - 登壇用のスライド骨子と想定スクリプト

ドキュメントは「現在のルール(docs)/ 経緯(devlog)/ 残タスク(issue)」の三分割で運用している。 詳細は AGENTS.md の「ドキュメント運用」。

ライセンス

MIT License - 詳細は LICENSE を参照してください。

↑↓ navigate openesc close