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 Charts?
name: audit-swiftui-charts description: Audit macOS SwiftUI charts 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 Charts
AUDIT-ONLY Β· macOS-only Β· SwiftUI-only. Run this on a finished or in-progress macOS SwiftUI
project to detect β and where certain, fix β every way Swift Charts goes wrong: hallucinated chart/mark
names, charts hand-rolled from stacks of rectangles instead of Chart, the wrong *Mark for the data,
missing axes/legend/color-encoding, missing interactivity, version-floored symbols left ungated (or
needlessly over-gated), wrong-arm iOS gates, unscalable large-series plots, and missing chart
accessibility. Findings are written to disk in the toolkit's unified schema; certain mechanical defects
are fixed under the fix-safety protocol. This is never a from-scratch chart generator.
Swift Charts is macOS 13+; SectorMark, the chart*Selection family, and chartScrollableAxes are
macOS 14 (not 13); LinePlot/AreaPlot/BarPlot/PointPlot/SectorPlot/RectanglePlot/RulePlot vectorized plots are macOS 15. AI routinely mis-floors these
and reaches for iOS-shaped or invented chart types β be suspicious wherever AI wrote chart code.
Boundary / seam note (stay in lane)
- Canvas-drawn charts belong to
audit-swiftui-drawing-canvas. A chart hand-rolled withCanvas {}orPathis theirs; a chart hand-rolled from aForEachofRectangle/Capsulebars is ours (charts-02). When the bars are Canvas-drawn, note it in one line andcross_refdrawing-canvas. - The
Chart/Canvasno-accessibility-descriptor finding is intentionally double-detected withaudit-swiftui-accessibility(keep-both per the cross-ref graph): we file the chart-descriptor gap andcross_refaccessibility; do not collapse it. - Per-series color theory / WCAG contrast is
audit-swiftui-appearance-color; we own only the encoding choice (.foregroundStyle(by:)vs a hardcoded per-mark color, charts-06) andcross_ref. - Large-dataset render cost is shared with
audit-swiftui-view-performance; we own the charts-specific scale fix (vectorizedLinePlot/chartScrollableAxes, charts-10) andcross_ref. - The blanket "is every OS-floored API gated" sweep belongs to
audit-swiftui-availability-gating; this skill owns Charts gating in depth (charts-08/09) and defers non-charts gating there.
Defect index (charts-01 β¦ charts-11)
id Β· tell Β· severity Β· fix Β· open reference. Severities: hard-fail (build break / never-correct),
warning (compiles but non-native), advisory (judgment / perf). auto = mechanical single-answer
fix; flag = show the β
, dev applies.
| id | One-line tell | Sev | Fix | Reference |
|---|---|---|---|---|
| charts-01 | BarChart/LineChart/PieChart/ChartView/PieMark/DonutMark/ScatterMark/ColumnMark/.chartType( |
hard-fail | auto | charts-api-surface.md |
| charts-02 | Chart hand-rolled from a ForEach of Rectangle/Capsule bars or a GeometryReader |
warning | flag | hand-rolled-and-mark-selection.md |
| charts-03 | wrong *Mark for the data β BarMark for a continuous trend, LineMark across unordered categories |
warning | flag | hand-rolled-and-mark-selection.md |
| charts-04 | default axis cluttered/wrong β no .chartXAxis/.chartYAxis customization where needed |
advisory | flag | axes-legend-color.md |
| charts-05 | multi-series .foregroundStyle(by:) with the legend missing/hidden |
advisory | flag | axes-legend-color.md |
| charts-06 | hardcoded per-mark color repeated per category instead of .foregroundStyle(by:) |
advisory | flag | axes-legend-color.md |
| charts-07 | hand-rolled tap/drag hit-testing for selection instead of .chartXSelection (macOS 14) |
warning | flag | interactivity-and-scale.md |
| charts-08 | a version-floored symbol (SectorMark/chart*Selection/LinePlot) ungated or over-gated vs its real floor |
warning | flag | availability-gating-charts.md |
| charts-09 | #available(iOS β¦, *) gating a chart symbol in a macOS target (wrong arm) |
warning | auto | availability-gating-charts.md |
| charts-10 | thousands of BarMark/LineMark from one array (no vectorized plot / no scroll) |
advisory | flag | interactivity-and-scale.md |
| charts-11 | Chart with no VoiceOver descriptor (.accessibilityLabel/.accessibilityValue / summary) |
warning | flag | accessibility-charts.md |
One claim is FLOOR-SENSITIVE, not a fact about code: charts-08 fires for BOTH directions β a symbol
ungated below its floor and a symbol needlessly over-gated above it (e.g. chartXSelection
behind #available(macOS 15, *) when it is macOS 14, or SectorMark treated as macOS 13 when it is 14).
Confirm the floor in floors-master.md + via swiftui-ctx/Sosumi before asserting either.
The real API, at a glance
Real (exist on macOS 13.0+ unless noted): Chart, BarMark, LineMark, PointMark, AreaMark,
RuleMark, RectangleMark, AxisMarks, AxisValueLabel, AxisGridLine, .chartXAxis/.chartYAxis,
.chartLegend, .foregroundStyle(by:), .symbol(by:), .position(by:). macOS 14.0+: SectorMark
(pie/donut), .chartXSelection/.chartYSelection/.chartAngleSelection, .chartScrollableAxes,
.chartScrollPosition, .chartXVisibleDomain/.chartYVisibleDomain. macOS 15.0+: LinePlot,
AreaPlot, BarPlot, PointPlot, SectorPlot, RectanglePlot, RulePlot (vectorized function/large-series plots).
Hallucinated (never exist): BarChart, LineChart, PieChart, AreaChart, ChartView,
.chartType(...), PieMark, DonutMark, ScatterMark, ColumnMark β these are other-library /
invented shapes (PieMarkβSectorMark, ColumnMarkβBarMark, ScatterMarkβPointMark,
*Chart/ChartViewβChart { β¦ }).
β Correct (grounded reference shape)
The canonical Chart call is the swiftui-ctx consensus shape β Chart { β¦ } (45%) and
Chart(data) { β¦ } (44%) dominate; Chart(data, id:) { β¦ } is the 11% tail. A real, current
(macOS 26 SDK) call site from the corpus:
// f/deeper Β· PlatformsView.swift (consensus shape: Chart(_) { SectorMark β¦ }; SectorMark = macOS 14+)
Chart(store.platformStats) { stat in
SectorMark(
angle: .value("Chats", stat.chatCount),
innerRadius: .ratio(0.6),
angularInset: 2
)
.foregroundStyle(stat.platform.color)
.cornerRadius(4)
}
.frame(height: 220)
Source (real permalink, verify before citing in a finding):
https://github.com/f/deeper/blob/19b9f69fa0bbe2cd12dc8ba3729114a194bf1bf0/Deeper/Views/Platforms/PlatformsView.swift#L34
Β· Apple spec via Sosumi doc: https://sosumi.ai/documentation/charts/chart. Every ## Correct in a
finding is regenerated this way per the actual API β never hand-written β via swiftui-ctx lookup <api>
then swiftui-ctx file <recommended.id> --smart.
Signatures, floors, and the full βββ
rewrites: references/charts-api-surface.md. Floor values are
the reconciled truth in <swiftui-plugin-root>/references/_shared/floors-master.md and the canonical
invented-name list (incl. the Charts section) in
<swiftui-plugin-root>/references/_shared/hallucination-blacklist.md β read, never restate them.
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: charts-08 fires when a symbol's floor (14 forSectorMark/selection/scroll, 15 forLinePlot) is above the project floor and the call is ungated β or when a gate sits above the real floor. Record it. - LOCATE. Run the shared hybrid lint runner:
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-charts --dir <sources> --json /tmp/charts.json --sarif /tmp/charts.sarif. It runs this skill's tier-1 grep tells (lint/grep-tells.tsv) + tier-2 structural ast-grep rules (lint/ast-grep/*.ymlβ the hand-rolled-bars containment + wrong-arm gate-scope rules grep can't express), plus a per-file parse probe, and emits unified JSON + SARIF. Read itsparse_warningsβ a flagged file did not fully parse, so a structural miss can't masquerade as clean; 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. Whether a frame
dimension is data-driven, whether a Mark fits the data's shape, axis/legend wiring, and gate scope are
invisible to grep. Build a per-file inventory: each chart, its
*Mark(s), data shape, axes/legend, interactivity, gate, and accessibility. - DETECT. Apply the index. Assign each candidate a confidence; report a finding only at 100%
certainty (e.g. a hallucinated name, an
iOSgate arm over a chart, aSectorMarkungated under a macOS 13 floor). - VERIFY. For anything β€ ~70% confidence (a symbol you're unsure exists, a floor you can't place, a
"wrong Mark" judgment), 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 call shape),introduced_macos,deprecated+replacement,recommended/diversepermalink, andco_occurs_with; alookupexit 3 (not-found, with a did-you-meansuggestion) corroborates a hallucination β no shipping Mac app uses the symbol. (b) Spec β confirm 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.mdand the Sosumidoc:floor. The CLI contract is<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md. Promote with the citation or discard. - REPORT. Write each confirmed finding (output contract below). One finding per file, zero-padded,
ordered. Write the run's
_index.md. - FIX. Apply corrections under the fix-safety protocol
(
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md): clean-tree gate, findings-first, onlyfix_mode: auto(charts-01 1:1 mark renames, charts-09 wrong-arm gate), one conventional commit per finding citing itsrule_id, never weaken a check. The β "Correct" is not a hand-written snippet β it is the swiftui-ctx consensus shape put in## Correct, 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## Source. Leaveflag-onlyfindingsopenwith that β in## Correct. - DOUBLE-CHECK. Re-grep each fixed file to confirm the tell no longer matches; record the evidence in
## Fix applied?. Re-confirm every citation still resolves and still says the expected floor. If a fix introduced a new tell (e.g. aSectorMarkyou added now needs a macOS 14 gate), loop that file back to DETECT.
Confidence gating (load-bearing)
Report a finding only at 100% certainty. Anything β€ ~70% goes to VERIFY (step 5) before it can become
a finding β never emit a speculative finding. Auto-fix only the mechanical set (charts-01 mark renames,
charts-09 wrong-arm); everything else is fix_mode: flag-only.
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/charts/<context>/NN-slug.md(one finding per file, zero-padded, ordered). Per-run index:swiftui-audits/charts/_index.md. domain: charts. Frontmatter is the canonical schema;fix_modeisautofor charts-01/09, elseflag-only.availabilityreads fromfloors-master.md.sourceis an Apple URL + access date (fetched via Sosumi) plus aswiftui-ctxpermalink, orverify against Xcode 26 SDK. Emitcross_refon shared-seam findings (charts-02 Canvas β drawing-canvas; charts-06 β appearance-color; charts-10 β view-performance; charts-11 β accessibility).
Starter <context> folders (file here whenβ¦):
<context> |
File a finding here when⦠|
|---|---|
hallucinated-api/ |
a chart/mark name doesn't exist on macOS (charts-01) |
hand-rolled-vs-chart/ |
a chart is built from stacks/GeometryReader instead of Chart (charts-02) |
mark-selection/ |
the *Mark doesn't fit the data shape (charts-03) |
axes-legend-color/ |
axes are cluttered, the legend is missing, or color encoding is hardcoded (charts-04/05/06) |
interactivity/ |
selection is hand-rolled instead of .chartXSelection (charts-07) |
availability-gating/ |
a version-floored symbol is ungated or mis-gated, or gated on the iOS arm (charts-08/09) |
scale-performance/ |
a large series isn't vectorized/scrollable (charts-10) |
accessibility/ |
a chart has no VoiceOver descriptor (charts-11) |
New-folder rule: if a finding does not fit any existing context folder, create a new one under
swiftui-audits/charts/ 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.
Reference routing
| File | Open when |
|---|---|
references/charts-api-surface.md |
a name/signature/existence question β the real mark/plot allow-list + hallucination βββ + floors (charts-01) |
references/hand-rolled-and-mark-selection.md |
a chart built from primitives, or the wrong *Mark for the data (charts-02/03) |
references/axes-legend-color.md |
axis customization, the legend, and .foregroundStyle(by:) vs hardcoded color (charts-04/05/06) |
references/interactivity-and-scale.md |
.chartXSelection vs hand-rolled selection, and large-series vectorized/scrollable plots (charts-07/10) |
references/availability-gating-charts.md |
Charts gating depth, the corrected floors, over-gating, the wrong-arm trap (charts-08/09) |
references/accessibility-charts.md |
the chart VoiceOver descriptor gap, keep-both with accessibility (charts-11) |
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 + tier-2 structural ast-grep); 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 (incl. Β§4 Charts) |
<swiftui-plugin-root>/references/_shared/macos-arm-gating.md |
the macOS-arm gating rule + wrong-arm failure (charts-09) |
<swiftui-plugin-root>/references/_shared/finding-schema.md |
the unified finding schema + frontmatter keys + cross_ref |
<swiftui-plugin-root>/references/_shared/fix-safety-protocol.md |
the fix-safety protocol (step FIX) |
<swiftui-plugin-root>/references/_shared/sosumi-reference.md |
the Apple-doc spec fetch protocol (step VERIFY) |
<swiftui-plugin-root>/references/_shared/swiftui-ctx-reference.md |
the practice-corpus CLI contract β lookup/deprecated/file --smart for the consensus shape + permalinked example (steps VERIFY Β· FIX) |
<swiftui-plugin-root>/references/_shared/cross-ref-graph.md |
seam ownership + cross_ref targets |
Detection accelerator
bash <swiftui-plugin-root>/scripts/swiftui-lint.sh --skill audit-swiftui-charts --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, charts-01/02/03/04/05/06/07/08/09/10/11)
- tier-2 ast-grep structural rules (
lint/ast-grep/*.ymlβ charts-02 hand-rolled-bars containment, charts-09 wrong-arm gate-scope) that grep cannot express. It runs a per-file parse probe (surfaces "did not fully parse" so a structural miss can't look clean), emits unified JSON + SARIF, exits 2 on any hard-fail (charts-01/08/09) for a CI gate, 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 before reporting (step READ). The legacyscripts/charts-lint.shis a thin 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 Charts 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-charts ~/.claude/skills/A skill is a plain directory. Copy it into `.claude/skills/` in a project or in your home directory.
Score
75 / 100
Good