Install
$ agentstack add skill-yusufkaran-swiftui-autotest-skill-add-accessibility ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Add Accessibility Skill
Overview
Use this skill to scan all SwiftUI files in a project, find interactive elements missing accessibility identifiers, and add them using a consistent {screen}-{type}-{name} naming convention. Also flags Dynamic Type compatibility issues without auto-fixing them.
Options
--dry-run: Don't modify files, only report what would be changed--path=: Scan only the specified directory (default: all SwiftUI files)--verbose: Log each identifier added in detail
Workflow
1) Scan & Analyze
- Find all
*.swiftfiles in the project - Filter to files containing SwiftUI views (
struct X: View,#Preview, etc.) - In each file, detect these interactive elements:
Button— buttonsTextFieldandSecureField— input fieldsImage— imagesToggle— toggle switchesSlider— slidersPicker— pickersDatePicker— date pickersNavigationLink— navigation linksTabViewtab items.onTapGestureviews — tap gesture elementsLink— external links
- For each element, check existing accessibility state:
- Has
.accessibilityIdentifier()? → SKIP - Has
.accessibilityLabel()? → SKIP - If either exists, do not touch it
2) Generate Identifiers
Naming convention: {screen}-{type}-{name}
Screen name: derived from the filename
LoginView.swift→loginOnboardingStepView.swift→onboarding-stepHomeTabView.swift→home-tab- Remove
Viewsuffix, convert camelCase to kebab-case
Type: based on the element type
| SwiftUI Element | Type | |----------------|------| | Button | button | | TextField | textfield | | SecureField | securefield | | Image | image | | Toggle | toggle | | Slider | slider | | Picker | picker | | DatePicker | datepicker | | NavigationLink | navlink | | Link | link | | .onTapGesture view | tap | | TabView item | tab |
Name: derived from the element's content
Button("Continue")→continueTextField("Email", ...)→emailImage(systemName: "gear")→gearImage("hero-banner")→hero-bannerToggle("Notifications", ...)→notifications- No content or too complex → number sequentially (
button-1,button-2)
Example results:
login-button-continue
login-textfield-email
login-securefield-password
onboarding-image-hero-banner
settings-toggle-notifications
home-tab-profile
3) Apply Changes
Add .accessibilityIdentifier("generated-id") to each element missing one:
// BEFORE
Button("Continue") {
viewModel.proceed()
}
// AFTER
Button("Continue") {
viewModel.proceed()
}
.accessibilityIdentifier("login-button-continue")
For Images, also add accessibilityLabel (for VoiceOver):
// BEFORE
Image(systemName: "gear")
// AFTER
Image(systemName: "gear")
.accessibilityIdentifier("settings-image-gear")
.accessibilityLabel("Settings")
For onTapGesture views, mark as accessibility elements:
// BEFORE
HStack {
Image("avatar")
Text(user.name)
}
.onTapGesture { showProfile() }
// AFTER
HStack {
Image("avatar")
Text(user.name)
}
.onTapGesture { showProfile() }
.accessibilityElement(children: .combine)
.accessibilityIdentifier("profile-tap-user-row")
.accessibilityAddTraits(.isButton)
4) Dynamic Type Check
Check Text elements for Dynamic Type compatibility:
- Flag (report as warnings, do NOT auto-fix):
Textwithout.lineLimit()when the content could be longTextwithout.minimumScaleFactor()in constrained areas.font(.system(size: XX))with hardcoded font sizes instead of dynamic fonts like.font(.title),.font(.body)
- Report format:
⚠️ Dynamic Type Warnings:
LoginView.swift:42 - Text("Welcome back...") → missing lineLimit or minimumScaleFactor
LoginView.swift:58 - Text(...).font(.system(size: 14)) → consider using dynamic font (.body, .caption, etc.)
SettingsView.swift:23 - Text(longString) → missing lineLimit, risk of overflow with large text
5) Summary Report
Show a summary when the scan is complete:
✅ Accessibility Scan Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Files scanned: 24
Elements found: 87
Already present: 31 (skipped)
Newly added: 56
- Button: 18
- TextField: 8
- Image: 12
- Toggle: 6
- Other: 12
⚠️ Dynamic Type Warnings: 7
(details above)
Pattern: {screen}-{type}-{name}
Important Rules
- NEVER modify or remove existing accessibility modifiers
- NEVER change the view's functionality or appearance
- Only add
.accessibilityIdentifier(),.accessibilityLabel(),.accessibilityElement(),.accessibilityAddTraits() - Do NOT wrap in
#if DEBUG— identifiers must be in production too (for real accessibility / VoiceOver) - If unsure about a name, use
{screen}-{type}-{index}format and flag it in verbose mode - Dynamic Type warnings are REPORT ONLY — do not auto-fix, leave it to the user
- In
--dry-runmode, do not modify any files — only show the plan - After modifying each file, run a compile check — if a syntax error is introduced, revert
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: yusufkaran
- Source: yusufkaran/swiftui-autotest-skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.