NOASSERTIONupdated 1mo ago
Let be the absolute plugin directory two levels above this SKILL.md. Resolve that path before running commands or opening shared references. When these instructions say swiftui-ctx, invoke /scripts/swiftui-ctx; do not assume the command is on PATH.
What can you do with Audit Swiftui Appkit Overuse?
name: audit-swiftui-appkit-overuse description: Audit macOS SwiftUI appkit overuse for correctness, current APIs, and production conventions. Use for that domain or as part of a full audit.
Bundled resource root
Let <swiftui-plugin-root> be the absolute plugin directory two levels above this SKILL.md. Resolve that path before running commands or opening shared references. When these instructions say swiftui-ctx, invoke <swiftui-plugin-root>/scripts/swiftui-ctx; do not assume the command is on PATH.
Audit SwiftUI AppKit Overuse
AUDIT-ONLY Β· macOS-only Β· SwiftUI-only. Run this on a finished or in-progress macOS SwiftUI
project to answer one question at every AppKit boundary: should this bridge exist at all? It is the
stay-in-SwiftUI enforcer β it flags every place the code reaches for AppKit
(NSViewRepresentable, NSViewControllerRepresentable, NSHostingView, NSStatusItem, NSOpenPanel,
NSItemProvider, NSGlassEffectView) when a native SwiftUI API already covers the case, and it
confirms the genuinely warranted escape hatches so they are not churned away. Findings are written to
disk in the toolkit's unified schema; this skill is flag-only by default β it never auto-rewrites a
bridge (deleting a representable is too blast-heavy for the fix-safety floor).
This is the WHETHER-to-bridge half of a pair: audit-swiftui-appkit-interop owns HOW a justified
bridge is implemented correctly (updateNSView, Coordinator, first-responder, @Sendable boundary).
Every overuse finding cross_refs interop, and vice versa.
Boundary / seam note (stay in lane)
- HOW a bridge is wired β missing
updateNSView, dead Coordinator, responder-chain, Swift-6@Sendablerace β isaudit-swiftui-appkit-interop. This skill decides whether the bridge should exist; once it confirms one is warranted (status: justified), interop owns its correctness. Emit across_refon every shared site. - AppKit
NSGlassEffectViewas a glass surface: this skill flags the bridge (use SwiftUI glass); the SwiftUI glass placement/grouping rules areaudit-swiftui-liquid-glass. cross_ref it. NSOpenPanel/NSSavePanelandNSItemProvider: this skill owns whether to bridge (usefileImporter/Transferable);audit-swiftui-sandbox-filesowns security-scoped-bookmark and drag-payload correctness once the SwiftUI API is in place. cross_ref it.MenuBarExtrascene vs a hand-builtNSStatusItem: this skill flags the bridge; the scene's activation/placement traps belong toaudit-swiftui-scenes-windows. cross_ref it.NSOutlineView/NSTableViewrender ceiling: when a large-data grid is the justification for a bridge,audit-swiftui-view-performanceowns the cost argument. cross_ref it.
The one design rule
Default: stay in SwiftUI. Bridge only the one subsystem that genuinely has no native equal. Every
NSViewRepresentable is a maintenance liability (a make/update/Coordinator handshake, a
responder-chain edge, a Swift-6 isolation boundary). It earns its keep only when SwiftUI has no
equivalent control, no equivalent capability, or not at the project's deployment floor.
The WHETHER test (apply to every bridge β full decision tree in
references/whether-to-bridge.md): (1) Is there a native SwiftUI control/API for this exact thing?
β if yes, the bridge is overuse (flag). (2) Does that native API exist at the project's deployment
floor? β if no (e.g. rich-text TextEditor(text:selection:) needs macOS 26), the bridge is
justified for now. (3) Does the AppKit view add capability SwiftUI structurally lacks
(hierarchical outline, cell-level grid perf, behind-window vibrancy, precise first-responder)? β if
yes, status: justified. Otherwise: flag as overuse.
Defect index (over-01 β¦ over-07)
id Β· tell Β· severity Β· fix Β· open reference. Severities: hard-fail (never-correct on a Mac),
warning (compiles but a native API fits), advisory (judgment / context-dependent). All findings
are fix_mode: flag-only β show the SwiftUI β
, the dev rewrites. (Removing a representable is never
mechanical.)
| id | One-line tell | Sev | Fix | Reference |
|---|---|---|---|---|
| over-01 | a NSViewRepresentable wrapping a 1:1-native control β NSButton/NSTextField/NSSwitch/NSSlider/NSColorWell/NSDatePicker/NSProgressIndicator/NSStepper/NSComboBox/NSPopUpButton/NSSegmentedControl |
warning | flag | native-control-equivalents.md |
| over-02 | NSStatusItem / NSStatusBar.system to put an item in the menu bar |
warning | flag | scene-and-system-bridges.md |
| over-03 | NSOpenPanel / NSSavePanel for a simple import/export |
warning | flag | scene-and-system-bridges.md |
| over-04 | NSItemProvider / NSPasteboard.writeObjects for drag/drop/clipboard of a model type |
advisory | flag | scene-and-system-bridges.md |
| over-05 | AppKit NSGlassEffectView / NSGlassEffectContainerView bridged for glass |
warning | flag | native-control-equivalents.md |
| over-06 | a whole window / large subtree wrapped β NSHostingView/NSHostingController reverse-bridge in a SwiftUI-first app, or a representable returning a composed NSStackView/container |
advisory | flag | scene-and-system-bridges.md |
| over-07 | an NSTextView bridge for plain or lightly-styled text on a macOS-26 floor |
advisory | flag | justified-escape-hatches.md |
Justified escape hatches β CONFIRM, never flag (record status: justified, a positive note;
detail + the macOS-26 inflection in references/justified-escape-hatches.md): rich-text NSTextView
below macOS 26, NSOutlineView (hierarchical disclosure SwiftUI lacks), NSTableView-grade data
grids (cell-level perf / column reordering past Table's ceiling β cross_ref view-performance),
behind-window NSVisualEffectView (.ultraThinMaterial composites inside the window β cross_ref
appkit-interop), and precise first-responder / field-editor control. An audited bridge that matches
one of these is correct: emit status: justified, not a defect.
The native SwiftUI surface, at a glance
NSButton β Button Β· NSTextField (plain) β TextField/SecureField Β· NSTextView (macOS 26
rich) β TextEditor(text:selection:) Β· NSSwitch β Toggle Β· NSSlider β Slider Β· NSStepper β
Stepper Β· NSColorWell β ColorPicker Β· NSDatePicker β DatePicker Β· NSProgressIndicator β
ProgressView (macOS 11+) Β· NSComboBox/NSPopUpButton/NSSegmentedControl β Picker (with .menu/.segmented
style) Β· NSStatusItem β MenuBarExtra scene Β· NSOpenPanel/NSSavePanel β
fileImporter/fileExporter/fileMover Β· NSItemProvider/NSPasteboard β Transferable +
.draggable/.dropDestination/.copyable Β· NSGlassEffectView β .glassEffect(_:in:).
These are existence/floor claims β confirm the replacement actually exists in VERIFY via
swiftui-ctx lookup + Sosumi; floor values are the reconciled truth in
<swiftui-plugin-root>/references/_shared/floors-master.md (read, never restate). MenuBarExtra is
macOS 13+; TextEditor(text:selection:) rich text is macOS 26.
Grounded β
example β NSStatusItem β MenuBarExtra (over-02)
This is the canonical correct shape a FIX cites for the most common overuse. It is not hand-written:
the trailing-closure form is the swiftui-ctx consensus shape ({ }, 50% of 1.8k+ real call sites,
swiftui-ctx lookup MenuBarExtra), and the snippet is the real recommended example
(swiftui-ctx file ex_259054c919 --smart). Replace a bridged NSStatusItem/NSStatusBar.system with:
// β
MenuBarExtra is a Scene (macOS 13+) β no NSStatusItem bridge needed.
MenuBarExtra {
MenuBarPopoverView(manager: manager, openLibrary: { showLibraryWindow() })
} label: {
Image(systemName: "play.rectangle.fill")
}
.menuBarExtraStyle(.window)
- Real permalink (## Source): https://github.com/kageroumado/phosphene/blob/757cae705aaf36ac13ba973919a181ea89fb2e3c/Phosphene/PhospheneApp.swift#L11 (repo
kageroumado/phosphene, 737β ,min_macos: 26). - Sosumi
doc:(## Source): https://sosumi.ai/documentation/swiftui/menubarextra β confirmsMenuBarExtramacOS 13.0+.
Re-fetch both in FIX (step 7) for the actual bridge under audit; never paste this verbatim without
re-running swiftui-ctx for the specific over-NN API in scope.
The 8-step audit workflow (execute verbatim)
- ORIENT.
tree/findthe SwiftUI sources. Read the deployment target (project.pbxprojMACOSX_DEPLOYMENT_TARGET, orPackage.swiftplatforms:). It is load-bearing: over-07 (rich-text bridge) is justified below macOS 26 and flaggable at/above it; theMenuBarExtra/fileImporterfloors (macOS 13/11) gate over-02/03. Record it. - LOCATE. Run the shared hybrid lint runner:
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-appkit-overuse --dir <sources> --json /tmp/over.json --sarif /tmp/over.sarif. It runs this skill's tier-1 grep tells (lint/grep-tells.tsv) + the tier-2 structural ast-grep rule (lint/ast-grep/*.ymlβ a representable whosemakeNSViewconstructs a trivial control, which grep can't prove), plus a per-file parse probe, emitting unified JSON + SARIF. Read itsparse_warningsβ a flagged file did not fully parse; READ those by hand. The runner only LOCATES β never treat a hit as a finding. Engine + rule-file format + degradation:<swiftui-plugin-root>/references/_shared/lint-architecture.md. - READ. Open every located file in full β never pattern-match-and-patch blind. A class name
appearing is not a verdict: an
NSTextFieldbridge may be a justified first-responder hatch, not a plain-field overuse. Build a per-bridge inventory: each representable/system call + what it wraps + the native candidate + whether that candidate exists at the floor. - DETECT. Apply the WHETHER test + the index. Assign each candidate a confidence; report a
finding only at 100% certainty (a 1:1 control wrapper with a floor-met native equal = over-01; a
warranted escape hatch =
status: justified). When in doubt whether the native API exists/covers the case β VERIFY. - VERIFY. For any β€ ~70%-confidence call (does the SwiftUI replacement exist? at this floor? does it
really cover the AppKit control's behavior?), run both evidence sources. (a) Practice β
bash <swiftui-plugin-root>/scripts/swiftui-ctx lookup <api> --json(andswiftui-ctx deprecated <api>for a currency rule): read itsconsensus(the canonical shape),recommendedpermalink,introduced_macos, andco_occurs_with; alookupexit 3 (not-found) means no shipping Mac app uses that SwiftUI name β re-check it isn't a hallucination. For a multi-API pattern useswiftui-ctx recipe <name>(e.g.recipe menubar-app,recipe draggable-reorder,recipe nsview-bridge). (b) Spec β confirm the floor via Sosumi:curl -sSL https://sosumi.ai/<apple-path>usingreferences/source-directory.mdfor the path and<swiftui-plugin-root>/references/_shared/sosumi-reference.mdfor the protocol (neverWebFetchdeveloper.apple.com). Cross-checkintroduced_macosagainstfloors-master.md. The CLI contract is<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md. Promote with the citation or discard. Deeper corpus evidence (WHETHER-to-bridge): when a bridge looks like overuse, prove real apps don't need it βbash <swiftui-plugin-root>/scripts/swiftui-ctx bridges <kind-or-name> --json(stable envelope +next_actions, e.g.bridges ColorWell) shows what the 957-repo corpus actually wraps (4,698 bridges) vs does natively, thenlookupthe native replacement to prove it exists andrecipe nsview-bridgefor the justified pattern. Real over-01 datum:swiftui-ctx bridges ColorWellsurfacesFred78290/caker'sNSViewRepresentablenamedColorWell(permalinked) whilelookup ColorPickerconfirms the nativeColorPickerhas existed since macOS 11.0 (51% consensus(_, selection)) β that bridge is overuse. - REPORT. Write each confirmed finding (output contract below). One finding per bridge site,
zero-padded, ordered. Record
status: justifiednotes for warranted hatches. Write the run's_index.md. - FIX. Flag-only under the fix-safety protocol
(
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md) β never auto-delete a representable. Leave each findingopenwith the SwiftUI β in## Correct. The β is not a hand-written snippet β it is the swiftui-ctx consensus shape for the native replacement, backed by a real macOS-26 example fetched withbash <swiftui-plugin-root>/scripts/swiftui-ctx file <recommended.id> --smartwhose GitHub permalink (plus the Sosumidoc:) goes in## Sourceas the canonical example. - DOUBLE-CHECK. Re-confirm every citation still resolves and the replacement's floor still matches
the project's target (a
fileImporterβ is useless if the floor is below macOS 11). Re-verify eachstatus: justifiednote still holds (e.g. the floor really is < macOS 26 for an over-07 hatch). If a recommendation would itself need a new gate, note it in## Correct.
Confidence gating (load-bearing)
Report a finding only at 100% certainty β a bridge is overuse only when the native SwiftUI API
provably exists at the project's floor and covers the control's behavior. Anything β€ ~70% goes to
VERIFY (step 5) first. Never flag a bridge whose native equal you have not confirmed. All findings are
fix_mode: flag-only; there is no auto-fix in this domain.
Output contract
Inherits the toolkit's unified contract (full schema + body sections + frontmatter keys:
<swiftui-plugin-root>/references/_shared/finding-schema.md β do not restate it). Specialized for this
domain:
- Findings:
swiftui-audits/appkit-overuse/<context>/NN-slug.md(one finding per bridge site, zero-padded, ordered). Per-run index:swiftui-audits/appkit-overuse/_index.md. domain: appkit-overuse.fix_modeisflag-onlyfor every finding.statusisopenfor a defect,justifiedfor a confirmed warranted escape hatch (the schema's appkit-overuse additive value).cross_refcarries the interop/glass/sandbox/scenes/perf seam.sourceis an Apple URL + access date (via Sosumi) orverify against Xcode 26 SDK.
Starter <context> folders (file here whenβ¦):
<context> |
File a finding here when⦠|
|---|---|
native-control-wrappers/ |
a representable wraps a 1:1 SwiftUI control (over-01) |
system-affordances/ |
a menu-bar item, file panel, or pasteboard/drag bridge has a native equal (over-02, over-03, over-04) |
appkit-glass/ |
an NSGlassEffectView is bridged where SwiftUI glass fits (over-05) |
over-wrapped-scene/ |
a whole window or large subtree is bridged when SwiftUI scenes/layout fit (over-06) |
floor-gated-bridge/ |
a bridge is only needed below a floor β e.g. rich-text NSTextView pre-26 (over-07) |
justified-hatch/ |
a bridge is CONFIRMED warranted (status: justified) β outline/grid/vibrancy/first-responder/pre-26 rich text |
New-folder rule: if a finding does not fit any existing context folder, create a new one under
swiftui-audits/appkit-overuse/ with a lowercase-hyphen slug naming the sub-category, and note it in
the run's _index.md. Prefer an existing folder when the fit is reasonable; consistency across runs is
a hard requirement. Two runs over the same code produce structurally identical trees.
Go-beyond artifact (optional):
swiftui-audits/appkit-overuse/_bridge-ledger.mdβ every AppKit bridge in the project classifiedoveruse/justifiedwith the WHETHER-test verdict and the native candidate, so a reviewer sees the whole AppKit surface at a glance. Seereferences/whether-to-bridge.md.
Reference routing
| File | Open when |
|---|---|
references/whether-to-bridge.md |
the core WHETHER decision tree, the two-sided framing, the bridge-ledger artifact |
references/native-control-equivalents.md |
the AppKit-control β SwiftUI-control map + NSGlassEffectViewβglass (over-01, over-05) |
references/scene-and-system-bridges.md |
menu-bar, file-panel, pasteboard/drag, and whole-window bridges (over-02/03/04/06) |
references/justified-escape-hatches.md |
the confirm-don't-flag set + the macOS-26 rich-text inflection (over-07, status: justified) |
references/source-directory.md |
step VERIFY β the Apple/WWDC/practitioner source map fetched via Sosumi |
lint/grep-tells.tsv + lint/ast-grep/*.yml |
step LOCATE β this skill's declarative lint rule set fed to the shared runner (tier-1 grep tells + the tier-2 structural rule); edit here to tune detection |
Shared toolkit references (point in, never restate):
| Shared file | For |
|---|---|
<swiftui-plugin-root>/references/_shared/floors-master.md |
every floor/availability value (the reconciled truth) |
<swiftui-plugin-root>/references/_shared/hallucination-blacklist.md |
the canonical invented-name list (confirm a SwiftUI replacement is real) |
<swiftui-plugin-root>/references/_shared/macos-arm-gating.md |
the macOS-arm gating rule (replacements that need a new gate) |
<swiftui-plugin-root>/references/_shared/finding-schema.md |
the unified finding schema + the status: justified additive value |
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md |
the fix-safety protocol (step 7) β this domain is flag-only |
<swiftui-plugin-root>/references/_shared/sosumi-reference.md |
the Apple-doc spec fetch protocol (step 5 VERIFY) |
<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md |
the practice-corpus CLI contract β lookup/recipe/file --smart for the consensus shape + permalinked example (steps 5 VERIFY Β· 7 FIX) |
<swiftui-plugin-root>/references/_shared/cross-ref-graph.md |
seam ownership + cross_ref targets (interop β overuse handshake) |
Detection accelerator
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-appkit-overuse --dir <files-or-dir> [--json out.json] [--sarif out.sarif] β the toolkit's one shared hybrid lint engine, fed this
skill's declarative rules: tier-1 grep tells (lint/grep-tells.tsv, over-01β¦over-07 by flat symbol
presence) + the tier-2 ast-grep structural rule (lint/ast-grep/over-01-wraps-native-control.yml β
a makeNSView that constructs a trivial native control, which grep cannot prove). It runs a per-file
parse probe (surfaces "did not fully parse"), emits unified JSON + SARIF, and degrades to
grep-only with a notice if ast-grep is unreachable (npx --package @ast-grep/cli ast-grep; faster:
brew install ast-grep). It only LOCATES β always READ each hit in full and apply the WHETHER test
before reporting (step 3), since a bridge may be a justified hatch. The thin scripts/over-lint.sh is a
pointer to this runner. Engine + rule-file format + JSON/SARIF shape + safety rails:
<swiftui-plugin-root>/references/_shared/lint-architecture.md.
Install
Add Audit Swiftui Appkit Overuse to your client. Pick the one you use.
npx skills add yigitkonur/plugin-swiftuiInstalls every skill in the repository, then prompts for which to keep.
/plugin marketplace add yigitkonur/plugin-swiftuiAdds the repository as a plugin marketplace; install individual plugins with `/plugin install`.
git clone https://github.com/yigitkonur/plugin-swiftui
cp -r plugins/swiftui/skills/audit-swiftui-appkit-overuse ~/.claude/skills/A skill is a plain directory. Copy it into `.claude/skills/` in a project or in your home directory.
Score
80 / 100
Excellent