A SwiftUI skill for Codex and Claude

Give Codex or Claude a SwiftUI architecture skill.

Add $swiftui-semantic, then ask for normal SwiftUI work: explain a data flow, fix duplicated state, or review a change. The skill gathers indexed evidence and follows the task through verification.

  • Open sourceMIT License
  • One skill to invokeCodex or Claude Code
  • Provider independentNo embedded model API

Inside a skill run

The skill maps state before the agent edits it.

This editorial view summarizes accepted fixture evidence passed into the agent workflow. It is not a product GUI.

Manual synchronization

BindingMirroredLocally two owners
struct BindingMirrorEditor: View {
    @Binding var profileName: String
    @State private var editableName = ""

    var body: some View {
        TextField("Name", text: $editableName)
            .onAppear { editableName = profileName }
            .onChange(of: profileName) {
                editableName = profileName
            }
            .onChange(of: editableName) {
                profileName = editableName
            }
    }
}

Reading the graph

One value has two mutable representations and reciprocal copy paths.
  1. OwnerprofileName is borrowed from the parent.
  2. OwnereditableName is local State.
  3. CopyonAppear seeds the local value.
  4. BindTextField writes to the local value.
  5. SyncEach representation copies into the other.
Findings mirrored-state manual-two-way-sync

Direct Binding

GoodDirectBinding one owner
struct DirectBindingField: View {
    @Binding var name: String

    var body: some View {
        TextField("Name", text: $name)
    }
}
No mirror finding is expected. The parent remains the owner and the field receives direct write authority.

Use cases in code

Three SwiftUI patterns the skill can inspect

The finding identifies topology. The safer shape depends on the value's owner and lifetime. Behavior tests still decide whether the change is safe.

1

Keep commands visible

A custom setter can hide a method call behind value-shaped syntax.

Accepted fixture excerpt command-shaped-binding
@Bindable var model: CommandPagerModel

selection: Binding(
    get: { model.page },
    set: { model.selectPage($0) }
)
When the method only performs an identity write, expose that write directly.
Accepted clean fixture no finding
@Binding var value: Int

selection: Binding(
    get: { value },
    set: { next in value = next }
)

A method with validation or side effects needs an explicit action boundary, not deletion.

2

Narrow the component boundary

Passing one model through extracted views keeps every layer coupled to the owner.

Representative accepted topology depth 2
struct Middle: View {
    @Bindable var model: FeatureModel
    var body: some View {
        Leaf(model: model)
    }
}

struct Leaf: View {
    @Bindable var model: FeatureModel
}
Give a reusable leaf the value and action it actually consumes.
Accepted clean boundary focused input
struct GoodFocusedLeaf: View {
    let title: String
    let reload: () -> Void

    var body: some View {
        Button("Reload", action: reload)
    }
}

A screen or composition root may legitimately receive a broad model. The agent must establish that role.

3

Keep derived state derived

A stored flag creates write paths when its value is already determined by inputs.

Accepted fixture excerpt stored-derived-state
@State private var username = ""
@State private var password = ""
@State private var canSubmit = false

.onChange(of: username) { _, _ in
    canSubmit = !username.isEmpty && !password.isEmpty
}
When the value has no independent lifetime, compute it from its sources.
Safer shape, pending behavior tests computed
@State private var username = ""
@State private var password = ""

private var canSubmit: Bool {
    !username.isEmpty && !password.isEmpty
}

Debouncing, server validation, or a separate lifetime may justify stored state.

Protected case

A real local draft is not a fix target.

A local draft is valid when the UI has real commit and discard behavior. The distinction comes from action and copy topology, not button names.

Representative protected transaction no finding expected
@Binding var name: String
@State private var draft = ""

func applyEdits() { name = draft }
func abandonEdits() { draft = name }

TextField("Name", text: $draft)
Button("Apply") { applyEdits() }
Button("Discard") { abandonEdits() }
.onAppear { draft = name }
  • Separate lifetimeThe draft remains local until commit.
  • Explicit commitApply writes the draft to the external owner.
  • Explicit rollbackDiscard restores the owned value.
  • No mechanical fixThe valid transaction stays intact.

Use cases

Ask for the SwiftUI work you already need.

Invoke $swiftui-semantic in Codex or /swiftui-semantic in Claude Code, then describe the outcome. The skill selects the workflow internally.

  1. 1

    Understand unfamiliar state flow

    Ask who owns a value, why it is synchronized, or where a model crosses component boundaries.

    Explain who owns this state and why it is synchronized.
  2. 2

    Fix a data-flow problem

    Ask to remove duplicated state, callback plumbing, or a suspicious Binding without changing behavior.

    Remove this duplicated state without changing behavior.
  3. 3

    Review an agent-authored change

    Ask whether an existing diff changed ownership, write paths, dependencies, or transaction semantics.

    Review these SwiftUI changes for ownership regressions.

Semantic diff

Record the architecture change.

A compatible snapshot diff records changes to representations, relationships, metrics, and findings. This ledger summarizes the fixture refactor shown above.

Architecture fact Baseline Current Review evidence
Canonical owner Parent Binding Parent Binding Preserved
Local mirror State representation Absent Removed
Synchronization Reciprocal copy path Absent Removed
Field write Through local draft Direct Binding Explicit

Semantic surface

29 bounded rules

Each rule evaluates supported ownership and data-flow topology. A finding is evidence for review, not a command to edit.

Read the rule reference

Ownership

  • mirrored-state
  • observable-state-mirror
  • stored-derived-state
  • model-aware-descendant
  • multi-owner-component
  • cross-feature-owner-dependency

Writes and effects

  • value-setter-pair
  • command-shaped-binding
  • manual-owner-synchronization
  • hidden-command-in-lifecycle
  • view-owned-external-effect

Bindings and sync

  • manual-two-way-sync
  • callback-binding-tunnel
  • binding-factory
  • multi-source-binding

Components

  • observable-model-tunnel
  • broad-observable-input
  • service-or-repository-in-view
  • preview-requires-app-composition

Interaction and layout

  • imperative-focus-lifecycle
  • selection-corrective-loop
  • geometry-driven-product-layout
  • geometry-escapes-layout-boundary
  • geometry-triggered-model-effect
  • manual-positioning-as-layout
  • gesture-button-emulation

Platform and environment

  • environment-command-router
  • imperative-platform-view-update
  • direct-global-platform-command

Trust and limits

Know what the skill owns

The skill routes the work. The CLI extracts deterministic facts; Codex or Claude makes contextual decisions.

Released and inspectable

Source, immutable tag, archive, and MIT license are public.

No automatic source rewriting

The CLI reports evidence. It never edits project source.

Deterministic, not prescriptive

Facts are canonical. Architectural judgment remains separate.

No embedded model API

The CLI stays provider independent; the agent host controls its own data handling.

The bounded analysis is not a full type checker, control-flow engine, security audit, or performance profiler. A clean report or semantic diff does not prove runtime behavior.

Installation

Add the skill to Codex or Claude Code

The skill is the interface. It uses a local evidence engine installed through Homebrew.

1

Install the local evidence engine

macOS 13 or later, Homebrew, and Xcode 26.6.

brew install potapenko/tap/swiftui-semantic-audit
swiftui-audit --version

The formula builds the tagged package from source and installs only swiftui-audit.

2

Add swiftui-semantic to the agent

Paste this bounded setup request into Codex or Claude Code.

Install the SwiftUI Semantic workflow for release 0.4.0: the user-facing
swiftui-semantic skill and its three internal specialists.
The CLI is already managed by Homebrew; verify `swiftui-audit --version` first.
Read and follow the tagged installation guide:
https://github.com/potapenko/swiftui-semantic-audit/blob/0.4.0/docs/getting-started/installation.md
Clone only tag 0.4.0 from
https://github.com/potapenko/swiftui-semantic-audit.git into a stable user-owned path.
Before linking anything, verify the origin, tag, and exact commit
189dc44c928f7f61b393f6e4ca7d8f6f5d183a48.
Detect this agent host and link the router and its three sibling specialist skill
directories into its documented personal skill directory. Do not overwrite,
delete, move, or repoint
an existing path. Finish with the tag, commit, CLI version, installed paths,
host, and verification receipt.

You invoke one skill. Setup keeps its internal workflows available and stops on version, source, or destination conflicts.

Then ask normally. Start an explanation, refactor, or review with $swiftui-semantic in Codex or /swiftui-semantic in Claude Code. The skill handles the workflow.

Run the first audit

FAQ

Using the skill safely

Read the documentation
Which skill should I use?

Use swiftui-semantic. Describe the SwiftUI outcome you need in Codex or Claude Code; the skill selects the internal workflow and carries its evidence forward.

Is this a linter?

No. The CLI compiles supported source facts into a semantic graph and evidence-backed findings for agent reasoning. It does not score style or prescribe a wrapper.

Does it change project source?

No. The CLI is non-mutating. A coding agent may propose a focused refactor after establishing ownership and behavior, but the tool itself never rewrites code.

Why does the agent workflow require a fresh Index Store?

Compiler-backed symbol identity and cross-file relations provide the evidence level required by the bundled workflows. They stop rather than present weaker evidence as a semantic result.

Are local drafts reported as duplicate state?

Not when the graph proves a real transaction with commit and discard behavior. Missing or fake discard topology does not receive that protection.

Does a clean semantic diff prove the refactor is correct?

No. The diff verifies supported architecture facts. Relevant builds, behavior tests, product invariants, and source review remain required.

Does the CLI send source to a model provider?

No. The CLI has no embedded model API. A surrounding agent host may read source under its own product and data policies.