WHEN designing features App Intent-first so Siri/Shortcuts, widgets, and SwiftUI share logic; NOT UI-first; reuse intents across app.
View on GitHubplugins/app/skills/app-intent-driven-development/SKILL.md
February 1, 2026
Select agents to install to:
npx add-skill https://github.com/mintuz/claude-plugins/blob/main/plugins/app/skills/app-intent-driven-development/SKILL.md -a claude-code --skill app-intent-driven-developmentInstallation paths:
.claude/skills/app-intent-driven-development/# App Intent–First Driven Development
Design features as App Intents first, then reuse those intents across Shortcuts, widgets, and SwiftUI views so automation and UI stay in lockstep.
## Core Ideas
- **Entities first**: model the data users act on (events, categories, records) as `AppEntity` so intents, widgets, and the app share one source of truth.
- **Intent-first feature**: build the App Intent + entity query before UI; SwiftUI screens call those intents instead of duplicating service code.
- **Single action, single intent**: keep intents focused; avoid mega-intents that are hard to compose in Shortcuts.
- **Predictable UI**: supply `DisplayRepresentation`, `typeDisplayRepresentation`, and icons so Siri/Shortcuts can render rich cards without opening the app.
- **Fast queries**: `EntityQuery` must be quick and cancellable; avoid blocking the main actor.
- **Reuse business logic**: intents call the same services your views use; do not fork logic inside the intent.
## Minimal Entity Blueprint
```swift
import AppIntents
struct TaskEntity: AppEntity, Identifiable {
static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Task")
static let defaultQuery = TaskQuery()
let id: UUID
let title: String
let isComplete: Bool
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: title,
subtitle: isComplete ? "Completed" : "Open",
image: .init(systemName: isComplete ? "checkmark.circle.fill" : "circle")
)
}
}
struct TaskQuery: EntityQuery {
func entities(for identifiers: [UUID]) async throws -> [TaskEntity] {
try await TaskStore.shared.fetch(ids: identifiers) // fast path
}
func suggestedEntities() async throws -> [TaskEntity] {
try await TaskStore.shared.fetchRecent()
}
}
```
**Key points:** stable identifier, meaningful representation, and fast queries that avoid launching heavy app flows.
## Intent Pattern
``