ios-feature-module
Skill1 starsChanged 14 days agoMITView on GitHub
Scaffold a complete feature module in this iOS codebase — domain model, endpoints, repository with read policies, view models, SwiftUI screens and tests — following the Features/Widgets reference implementation. Use when asked to add a new feature, screen set, resource or CRUD area to the app (for example "add a Projects feature", "we need Reports in the app", "build the Notifications section"), or when a new API resource needs an app-side home.
In this repository37 other files it gives its agents.
- AGENTS.mdAGENTS.md
- ios-accessibility-auditSkill
- ios-api-contract-migrationSkill
- ios-api-endpointSkill
- ios-app-intents-siriSkill
- ios-bug-triageSkill
- ios-build-configurationSkill
- ios-cloudkit-syncSkill
- ios-combine-patternsSkill
- ios-commit-and-prSkill
- ios-commitSkill
- ios-concurrency-auditSkill
- ios-coreml-apple-intelligenceSkill
- ios-deep-linkingSkill
- ios-dependency-assessmentSkill
- ios-design-fixSkill
- ios-knowledge-baseSkill
- ios-latest-os-adoptionSkill
- ios-localizationSkill
- ios-offline-writeSkill
- ios-performance-tuningSkill
- ios-port-from-androidSkill
- ios-port-to-androidSkill
- ios-precommitSkill
- ios-privacy-complianceSkill
- ios-push-and-background-tasksSkill
- ios-refactorSkill
- ios-release-prepSkill
- ios-sdk-upgradeSkill
- ios-secure-reviewSkill
- ios-storekit-subscriptionsSkill
- ios-swift6-concurrency-migrationSkill
- ios-swiftdataSkill
- ios-swift-testing-migrationSkill
- ios-swiftui-screenSkill
- ios-unit-testsSkill
- ios-widgetkit-live-activitiesSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
Offline stance: Must reads work offline? Must writes?
- Distinctive: line 24
Do not add an outbox unless offline writes are required.
- Very specific: line 39
If the feature has offline writes, add syncState: SyncState with a custom init(from:) using decodeIfPresent and a .synced default, and a …
- Very specific: line 58
Use .cache coders for queued payloads, never .api.
- Distinctive: line 87
Before reporting done, check each of these and say which you verified:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Scaffold a feature module
Produces a feature that matches this codebase exactly, in the order that keeps the data layer testable before any UI exists.
Before writing code
Establish these four things. Ask the user if the answer is not in the request — they are product decisions, not implementation details.
- Resource and fields. Name, fields, types, which are server-owned
(
id,reference,updatedAt) and which the user edits. - Operations. Which of list / detail / create / update / delete exist.
- Offline stance. Must reads work offline? Must writes? If stale data could
be dangerous here, say so and use
.remoteOnly. - Screens. List, detail, editor — and what each shows when empty, loading and failed.
Do not add an outbox unless offline writes are required. An unused queue is a liability.
Steps
Work in this order. Read the corresponding Features/Widgets file before writing
each one and mirror its structure.
Features/<Name>/Domain/<Name>.swift- Model:
Identifiable, Equatable, Hashable, Codable,let id,varfor the rest. - Status or enum fields:
String-backed with explicit raw values matching the API exactly (case inProgress = "in_progress"). <Name>Draft: the editable subset only, plusinit(<name>:)andvalidationMessages.- If the feature has offline writes, add
syncState: SyncStatewith a custominit(from:)usingdecodeIfPresentand a.synceddefault, and alocalID()helper.
- Model:
Features/<Name>/Data/<Name>Endpoints.swiftenum <Name>Endpointsof static functions returningEndpoint.- Paths relative, no leading slash.
enum <Name>CacheKeyswith a sharedprefixand apendingkey if offline writes are in scope.enum <Name>OutboxKindconstants if offline writes are in scope.
Features/<Name>/Data/<Name>Repository.swiftprotocol <Name>Repository: Sendablefirst — this is the seam.Live<Name>Repository: <Name>Repository, @unchecked SendablecomposingAPIClient,CacheStore,Outbox.- Reads honour
ReadPolicyand return provenance where the UI needs it. - Writes invalidate the list cache; validate the draft before any request.
- Offline writes: catch
error.isConnectivityFailure, queue, upsert an optimistic record, and conform toOutboxHandlerwithreplay(_:). - Use
.cachecoders for queued payloads, never.api.
- Repository tests — write these before the UI.
AppTemplateTests/Features/<Name>RepositoryTests.swift, usingStubAPIClient,InMemoryCacheStore,InMemoryOutbox. Cover every read policy the feature uses and every offline path. Features/<Name>/UI/<Name>ListViewModel.swift@MainActor final class ... : ObservableObject.@Published private(set) var state: LoadState<[<Name>]>, plusbanner: AppError?.onAppear()does cache-first then remote;refresh()does remote.- Cancellation checked in every catch. Long work held in a
Taskhandle and cancelled before replacement.
Features/<Name>/UI/<Name>ListView.swiftand editor view@StateObjectinitialised through_viewModel = StateObject(wrappedValue:).- Content inside
LoadStateView;.task,.refreshable. - Accessibility labels on icon-only controls.
- View-model tests — success, failure with existing content, failure with no content, cancellation ignored, each mutation and its rollback.
- Register in
AppEnvironment- Construct the repository beside
widgetRepository, expose it as alet, and callsyncCoordinator.register(...)only if it queues writes.
- Construct the repository beside
Verification
Before reporting done, check each of these and say which you verified:
- No iOS 17+ API used anywhere in the new files.
Coregained no reference to the new feature's types.- The view model imports no
URLSession,EndpointorCacheStore. - Every catch block checks
error.isCancellation. - No
print, no force-unwrap, notry!. - Sample and test data is obviously invented — no client names, no real addresses, no personal data.
- Tests exist for each offline path the feature claims to support.
project.pbxprojuntouched — new files and folders need no project change (synchronised folder groups).- Remind the user that this code needs human review, a passing test run and a clean SAST scan before commit.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

