agentleFS
SajidisrarSajidisrar/ios-claude-skills/skills/ios-feature-module/SKILL.md

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.

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
  1. Very specific:

    Offline stance: Must reads work offline? Must writes?

    line 19
  2. Distinctive:

    Do not add an outbox unless offline writes are required.

    line 24
  3. Very specific:

    If the feature has offline writes, add syncState: SyncState with a custom init(from:) using decodeIfPresent and a .synced default, and a …

    line 39
  4. Very specific:

    Use .cache coders for queued payloads, never .api.

    line 58
  5. Distinctive:

    Before reporting done, check each of these and say which you verified:

    line 87

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.

  1. Resource and fields. Name, fields, types, which are server-owned (id, reference, updatedAt) and which the user edits.
  2. Operations. Which of list / detail / create / update / delete exist.
  3. Offline stance. Must reads work offline? Must writes? If stale data could be dangerous here, say so and use .remoteOnly.
  4. 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.

  1. Features/<Name>/Domain/<Name>.swift
    • Model: Identifiable, Equatable, Hashable, Codable, let id, var for 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, plus init(<name>:) and validationMessages.
    • If the feature has offline writes, add syncState: SyncState with a custom init(from:) using decodeIfPresent and a .synced default, and a localID() helper.
  2. Features/<Name>/Data/<Name>Endpoints.swift
    • enum <Name>Endpoints of static functions returning Endpoint.
    • Paths relative, no leading slash.
    • enum <Name>CacheKeys with a shared prefix and a pending key if offline writes are in scope.
    • enum <Name>OutboxKind constants if offline writes are in scope.
  3. Features/<Name>/Data/<Name>Repository.swift
    • protocol <Name>Repository: Sendable first — this is the seam.
    • Live<Name>Repository: <Name>Repository, @unchecked Sendable composing APIClient, CacheStore, Outbox.
    • Reads honour ReadPolicy and 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 to OutboxHandler with replay(_:).
    • Use .cache coders for queued payloads, never .api.
  4. Repository tests — write these before the UI. AppTemplateTests/Features/<Name>RepositoryTests.swift, using StubAPIClient, InMemoryCacheStore, InMemoryOutbox. Cover every read policy the feature uses and every offline path.
  5. Features/<Name>/UI/<Name>ListViewModel.swift
    • @MainActor final class ... : ObservableObject.
    • @Published private(set) var state: LoadState<[<Name>]>, plus banner: AppError?.
    • onAppear() does cache-first then remote; refresh() does remote.
    • Cancellation checked in every catch. Long work held in a Task handle and cancelled before replacement.
  6. Features/<Name>/UI/<Name>ListView.swift and editor view
    • @StateObject initialised through _viewModel = StateObject(wrappedValue:).
    • Content inside LoadStateView; .task, .refreshable.
    • Accessibility labels on icon-only controls.
  7. View-model tests — success, failure with existing content, failure with no content, cancellation ignored, each mutation and its rollback.
  8. Register in AppEnvironment
    • Construct the repository beside widgetRepository, expose it as a let, and call syncCoordinator.register(...) only if it queues writes.

Verification

Before reporting done, check each of these and say which you verified:

  • No iOS 17+ API used anywhere in the new files.
  • Core gained no reference to the new feature's types.
  • The view model imports no URLSession, Endpoint or CacheStore.
  • Every catch block checks error.isCancellation.
  • No print, no force-unwrap, no try!.
  • 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.pbxproj untouched — 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.