swift-code-reviewer-skill 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to the Swift Code Reviewer Agent Skill will be documented in
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.0] - 2026-04-10
9
+
10
+ ### Added
11
+
12
+ - **`init` command**: Scaffold review agent + `/review` slash command into any project via `npx swift-code-reviewer-skill init`
13
+ - **templates/ directory**: Bundled agent (`swift-code-reviewer.md`) and command (`review.md`) templates
14
+ - `setup` alias for `init` in both installers
15
+ - `npx skills add` as primary installation method in README
16
+
17
+ ### Changed
18
+
19
+ - README rewritten with `npx skills add` as primary install, `init` as step 2
20
+ - `install-skill.sh` and `bin/install.js` now show `init` hint after install
21
+ - Post-install message updated to guide users toward project scaffolding
22
+
8
23
  ## [1.1.1] - 2026-03-24
9
24
 
10
25
  ### Fixed
@@ -210,6 +225,7 @@ Provided complete examples for:
210
225
 
211
226
  ## Version History Summary
212
227
 
228
+ - **1.2.0** (2026-04-10): Add `init` command with agent + /review scaffolding, `npx skills` as primary install
213
229
  - **1.1.1** (2026-03-24): Fix incorrect `install-skill.sh` (was XcodeBuildMCP installer)
214
230
  - **1.1.0** (2026-03-16): Increase adjusts from Dimillian skill and more scenarios to cover
215
231
  - **1.0.0** (2026-02-10): Initial release with comprehensive review capabilities
package/README.md CHANGED
@@ -7,19 +7,43 @@ A code review skill for [Claude Code](https://docs.anthropic.com/en/docs/claude-
7
7
 
8
8
  ## Quick Start
9
9
 
10
+ ### 1. Install the skill (global, once)
11
+
10
12
  ```bash
11
- npx swift-code-reviewer-skill
13
+ npx skills add Viniciuscarvalho/swift-code-reviewer-skill
14
+ ```
15
+
16
+ ### 2. Add the review agent to your project (optional)
17
+
18
+ ```bash
19
+ cd ~/Projects/YourApp
20
+ npx swift-code-reviewer-skill init
12
21
  ```
13
22
 
14
- That's it. The skill is installed and ready to use. Run it again anytime to update to the latest version.
23
+ This scaffolds two files into your project:
24
+
25
+ ```
26
+ .claude/
27
+ agents/swift-code-reviewer.md # review agent
28
+ commands/review.md # /review slash command
29
+ ```
30
+
31
+ Existing files are never overwritten.
32
+
33
+ ### The review flow
34
+
35
+ ```
36
+ You code --> /review before push (free, local) --> done
37
+ ```
15
38
 
16
- > No cloning, no manual setup. NPX always fetches the latest version automatically.
39
+ - `/review` runs the full review checklist against your staged or unstaged Swift changes
40
+ - `@swift-code-reviewer` invokes the agent directly for deeper analysis
17
41
 
18
42
  ## Usage
19
43
 
20
44
  ![Swift Code Reviewer in action](assets/demo.png)
21
45
 
22
- Just ask Claude to review your code:
46
+ Ask Claude to review your code:
23
47
 
24
48
  ```
25
49
  Review this PR
@@ -29,6 +53,12 @@ Review all ViewModels in the Features folder
29
53
  Check if this follows our coding standards
30
54
  ```
31
55
 
56
+ Or use the slash command after running `init`:
57
+
58
+ ```
59
+ /review
60
+ ```
61
+
32
62
  The skill automatically activates, reads your `.claude/CLAUDE.md` for project standards, and generates a structured report with severity levels, code examples, and prioritized action items.
33
63
 
34
64
  ### Example Output
@@ -42,11 +72,11 @@ The skill automatically activates, reads your `.claude/CLAUDE.md` for project st
42
72
 
43
73
  ## File: LoginViewModel.swift
44
74
 
45
- **Excellent Modern API Usage** (line 12)
75
+ Pass **Excellent Modern API Usage** (line 12)
46
76
 
47
77
  - Using @Observable instead of ObservableObject
48
78
 
49
- 🟡 **Force Unwrap Detected** (line 89)
79
+ Issue **Force Unwrap Detected** (line 89)
50
80
  Current: `let user = repository.currentUser!`
51
81
  Fix:
52
82
  guard let user = repository.currentUser else {
@@ -54,7 +84,7 @@ logger.error("No current user")
54
84
  return
55
85
  }
56
86
 
57
- 🔴 **Violates Design System Standard** (line 45)
87
+ Issue **Violates Design System Standard** (line 45)
58
88
  Current: `.foregroundColor(.blue)`
59
89
  Fix: `.foregroundColor(AppColors.primary)`
60
90
 
@@ -77,12 +107,12 @@ Fix: `.foregroundColor(AppColors.primary)`
77
107
 
78
108
  ### Severity Levels
79
109
 
80
- | Icon | Severity | Action |
81
- | ---- | -------- | ----------------------- |
82
- | 🔴 | Critical | Must fix before merge |
83
- | 🟡 | High | Should fix before merge |
84
- | 🟠 | Medium | Fix in current sprint |
85
- | 🔵 | Low | Consider for future |
110
+ | Icon | Severity | Action |
111
+ | -------- | -------- | ----------------------- |
112
+ | Critical | Critical | Must fix before merge |
113
+ | High | High | Should fix before merge |
114
+ | Medium | Medium | Fix in current sprint |
115
+ | Low | Low | Consider for future |
86
116
 
87
117
  ## Platform Support
88
118
 
@@ -116,23 +146,21 @@ Add a `.claude/CLAUDE.md` to your project and the skill will validate against yo
116
146
  ## Alternative Installation
117
147
 
118
148
  <details>
119
- <summary>Clone this repository</summary>
149
+ <summary>NPX installer (installs skill only)</summary>
120
150
 
121
151
  ```bash
122
- git clone https://github.com/Viniciuscarvalho/swift-code-reviewer-skill.git ~/.claude/skills/swift-code-reviewer-skill
152
+ npx swift-code-reviewer-skill
123
153
  ```
124
154
 
125
155
  </details>
126
156
 
127
157
  <details>
128
- <summary>Manual installation</summary>
158
+ <summary>Clone this repository</summary>
129
159
 
130
160
  ```bash
131
- mkdir -p ~/.claude/skills/swift-code-reviewer-skill/references
161
+ git clone https://github.com/Viniciuscarvalho/swift-code-reviewer-skill.git ~/.claude/skills/swift-code-reviewer-skill
132
162
  ```
133
163
 
134
- Download the files from this repository into the directory, then restart Claude.
135
-
136
164
  </details>
137
165
 
138
166
  <details>
@@ -152,8 +180,9 @@ This skill optionally leverages **swift-best-practices**, **swiftui-expert-skill
152
180
 
153
181
  1. Edit `SKILL.md` for main skill logic
154
182
  2. Update reference files in `references/` for specific checklists
155
- 3. Test with real Swift/SwiftUI code
156
- 4. Submit a pull request
183
+ 3. Add/modify templates in `templates/` for agent and command scaffolding
184
+ 4. Test with real Swift/SwiftUI code
185
+ 5. Submit a pull request
157
186
 
158
187
  ## License
159
188
 
@@ -161,7 +190,7 @@ MIT License - See [LICENSE](LICENSE) file for details.
161
190
 
162
191
  ---
163
192
 
164
- **Made with ❤️ for the Swift community**
193
+ **Made with care for the Swift community**
165
194
 
166
195
  If this skill helps your code reviews, please star the repository!
167
196
 
package/SKILL.md CHANGED
@@ -1,6 +1,23 @@
1
1
  ---
2
2
  name: swift-code-reviewer
3
- description: Perform thorough code reviews for Swift/SwiftUI code, analyzing code quality, architecture, performance, security, and adherence to Swift 6+ best practices, SwiftUI patterns, navigation architecture, sheet routing, theming, async state, iOS/macOS platform guidelines, and project-specific coding standards from .claude/CLAUDE.md. Use when reviewing code changes, performing quality audits, or providing structured feedback on Swift codebases with all severity levels and positive feedback.
3
+ description: >
4
+ Multi-layer code review agent for Swift and SwiftUI projects. Analyzes PRs,
5
+ diffs, and files across six dimensions: Swift 6+ concurrency safety, SwiftUI
6
+ state management and modern APIs, performance (view updates, ForEach identity,
7
+ lazy loading), security (force unwraps, Keychain, input validation), architecture
8
+ compliance (MVVM/MVI/TCA, dependency injection), and project-specific standards
9
+ from .claude/CLAUDE.md. Outputs structured reports with Critical/High/Medium/Low
10
+ severity, positive feedback, and prioritized action items with file:line
11
+ references and before/after code examples.
12
+
13
+ ALWAYS use this skill when the user says "review this PR", "review my code",
14
+ "review my changes", "check this file", "code review", "review against our
15
+ standards", "audit this codebase", "check code quality", mentions reviewing
16
+ any .swift file, asks about Swift best practices violations in existing code,
17
+ or wants feedback on Swift/SwiftUI code — even if they don't explicitly say
18
+ "code review". Also trigger when the user asks to "check if this follows our
19
+ coding standards", "review uncommitted changes", "review all ViewModels",
20
+ or mentions reviewing navigation, sheets, theming, or async patterns in Swift.
4
21
  ---
5
22
 
6
23
  # Swift/SwiftUI Code Review Skill
@@ -775,6 +792,6 @@ For runtime analysis, recommend using Instruments or other profiling tools.
775
792
 
776
793
  ## Version
777
794
 
778
- **Version**: 1.1.1
779
- **Last Updated**: 2026-03-16
795
+ **Version**: 1.2.0
796
+ **Last Updated**: 2026-04-10
780
797
  **Compatible with**: Swift 6+, SwiftUI (iOS 17+, macOS 14+, watchOS 10+, tvOS 17+, visionOS 1+)
package/bin/install.js CHANGED
@@ -38,16 +38,7 @@ function copyRecursive(src, dest) {
38
38
  }
39
39
  }
40
40
 
41
- function install() {
42
- log('\n Swift Code Reviewer Skill Installer', colors.cyan + colors.bright);
43
- log(' ====================================\n', colors.cyan);
44
-
45
- // Determine paths
46
- const homeDir = os.homedir();
47
- const skillsDir = path.join(homeDir, '.claude', 'skills');
48
- const targetDir = path.join(skillsDir, SKILL_NAME);
49
-
50
- // Find package root (where SKILL.md is located)
41
+ function findPackageRoot() {
51
42
  let packageRoot = __dirname;
52
43
  while (!fs.existsSync(path.join(packageRoot, 'SKILL.md'))) {
53
44
  const parent = path.dirname(packageRoot);
@@ -57,14 +48,23 @@ function install() {
57
48
  }
58
49
  packageRoot = parent;
59
50
  }
51
+ return packageRoot;
52
+ }
53
+
54
+ function install() {
55
+ log('\n Swift Code Reviewer Skill Installer', colors.cyan + colors.bright);
56
+ log(' ====================================\n', colors.cyan);
57
+
58
+ const homeDir = os.homedir();
59
+ const skillsDir = path.join(homeDir, '.claude', 'skills');
60
+ const targetDir = path.join(skillsDir, SKILL_NAME);
61
+ const packageRoot = findPackageRoot();
60
62
 
61
- // Check if Claude Code skills directory exists
62
63
  if (!fs.existsSync(skillsDir)) {
63
64
  log(` Creating skills directory: ${skillsDir}`, colors.yellow);
64
65
  fs.mkdirSync(skillsDir, { recursive: true });
65
66
  }
66
67
 
67
- // Check for existing installation
68
68
  if (fs.existsSync(targetDir)) {
69
69
  log(` Updating existing installation at:`, colors.yellow);
70
70
  log(` ${targetDir}\n`, colors.yellow);
@@ -74,10 +74,8 @@ function install() {
74
74
  log(` ${targetDir}\n`, colors.blue);
75
75
  }
76
76
 
77
- // Create target directory
78
77
  fs.mkdirSync(targetDir, { recursive: true });
79
78
 
80
- // Files to copy
81
79
  const filesToCopy = [
82
80
  'SKILL.md',
83
81
  'README.md',
@@ -86,10 +84,8 @@ function install() {
86
84
  'CHANGELOG.md'
87
85
  ];
88
86
 
89
- // Directories to copy
90
87
  const dirsToCopy = ['references'];
91
88
 
92
- // Copy files
93
89
  for (const file of filesToCopy) {
94
90
  const src = path.join(packageRoot, file);
95
91
  const dest = path.join(targetDir, file);
@@ -100,7 +96,6 @@ function install() {
100
96
  }
101
97
  }
102
98
 
103
- // Copy directories
104
99
  for (const dir of dirsToCopy) {
105
100
  const src = path.join(packageRoot, dir);
106
101
  const dest = path.join(targetDir, dir);
@@ -111,10 +106,11 @@ function install() {
111
106
  }
112
107
  }
113
108
 
114
- // Success message
115
109
  log('\n Installation complete!', colors.green + colors.bright);
116
110
  log('\n The skill is now available in Claude Code.', colors.reset);
117
- log(' Use it by asking Claude to:', colors.reset);
111
+ log(' To add the review agent and /review command to a project, run:', colors.reset);
112
+ log('\n npx swift-code-reviewer-skill init\n', colors.cyan);
113
+ log(' Or use it directly by asking Claude to:', colors.reset);
118
114
  log('\n - "Review this PR"', colors.cyan);
119
115
  log(' - "Review LoginView.swift"', colors.cyan);
120
116
  log(' - "Review my uncommitted changes"', colors.cyan);
@@ -124,6 +120,69 @@ function install() {
124
120
  log(' Documentation: https://github.com/Viniciuscarvalho/swift-code-reviewer-skill\n', colors.blue);
125
121
  }
126
122
 
123
+ function init() {
124
+ log('\n Swift Code Reviewer — Project Setup', colors.cyan + colors.bright);
125
+ log(' =====================================\n', colors.cyan);
126
+
127
+ const packageRoot = findPackageRoot();
128
+ const cwd = process.cwd();
129
+
130
+ // Verify we're in a git repo (likely a real project)
131
+ if (!fs.existsSync(path.join(cwd, '.git'))) {
132
+ log(' Warning: Not a git repository. Running anyway.\n', colors.yellow);
133
+ }
134
+
135
+ const claudeDir = path.join(cwd, '.claude');
136
+ const agentsDir = path.join(claudeDir, 'agents');
137
+ const commandsDir = path.join(claudeDir, 'commands');
138
+
139
+ const templateAgentSrc = path.join(packageRoot, 'templates', 'agents', 'swift-code-reviewer.md');
140
+ const templateCommandSrc = path.join(packageRoot, 'templates', 'commands', 'review.md');
141
+
142
+ // Check templates exist
143
+ if (!fs.existsSync(templateAgentSrc)) {
144
+ log(' Error: Agent template not found. Reinstall the skill with:', colors.red);
145
+ log(' npx swift-code-reviewer-skill\n', colors.cyan);
146
+ process.exit(1);
147
+ }
148
+
149
+ fs.mkdirSync(agentsDir, { recursive: true });
150
+ fs.mkdirSync(commandsDir, { recursive: true });
151
+
152
+ let created = 0;
153
+ let skipped = 0;
154
+
155
+ // Copy agent
156
+ const agentDest = path.join(agentsDir, 'swift-code-reviewer.md');
157
+ if (fs.existsSync(agentDest)) {
158
+ log(' Skipped: .claude/agents/swift-code-reviewer.md (already exists)', colors.yellow);
159
+ skipped++;
160
+ } else {
161
+ fs.copyFileSync(templateAgentSrc, agentDest);
162
+ log(' Created: .claude/agents/swift-code-reviewer.md', colors.green);
163
+ created++;
164
+ }
165
+
166
+ // Copy command
167
+ const commandDest = path.join(commandsDir, 'review.md');
168
+ if (fs.existsSync(commandDest)) {
169
+ log(' Skipped: .claude/commands/review.md (already exists)', colors.yellow);
170
+ skipped++;
171
+ } else {
172
+ fs.copyFileSync(templateCommandSrc, commandDest);
173
+ log(' Created: .claude/commands/review.md', colors.green);
174
+ created++;
175
+ }
176
+
177
+ log(`\n Done! ${created} file(s) created, ${skipped} skipped.`, colors.green + colors.bright);
178
+
179
+ if (created > 0) {
180
+ log('\n Usage:', colors.reset);
181
+ log(' /review — run a full code review before pushing', colors.cyan);
182
+ log(' @swift-code-reviewer — invoke the agent directly\n', colors.cyan);
183
+ }
184
+ }
185
+
127
186
  function uninstall() {
128
187
  log('\n Uninstalling Swift Code Reviewer Skill', colors.yellow + colors.bright);
129
188
  log(' ======================================\n', colors.yellow);
@@ -146,11 +205,13 @@ function showHelp() {
146
205
  log(' Usage: npx swift-code-reviewer-skill [command]\n', colors.reset);
147
206
  log(' Commands:', colors.bright);
148
207
  log(' (none) Install the skill to ~/.claude/skills/', colors.reset);
208
+ log(' init Scaffold agent + /review command into current project', colors.reset);
149
209
  log(' uninstall Remove the skill from ~/.claude/skills/', colors.reset);
150
210
  log(' help Show this help message\n', colors.reset);
151
211
  log(' Examples:', colors.bright);
152
- log(' npx swift-code-reviewer-skill', colors.cyan);
153
- log(' npx swift-code-reviewer-skill uninstall\n', colors.cyan);
212
+ log(' npx swift-code-reviewer-skill # install skill globally', colors.cyan);
213
+ log(' npx swift-code-reviewer-skill init # add agent + command to project', colors.cyan);
214
+ log(' npx swift-code-reviewer-skill uninstall # remove skill\n', colors.cyan);
154
215
  }
155
216
 
156
217
  // Parse command line arguments
@@ -158,6 +219,10 @@ const args = process.argv.slice(2);
158
219
  const command = args[0];
159
220
 
160
221
  switch (command) {
222
+ case 'init':
223
+ case 'setup':
224
+ init();
225
+ break;
161
226
  case 'uninstall':
162
227
  case 'remove':
163
228
  uninstall();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swift-code-reviewer-skill",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Claude Code skill for comprehensive Swift/SwiftUI code reviews with multi-layer analysis",
5
5
  "keywords": [
6
6
  "claude",
@@ -9,9 +9,21 @@
9
9
  "swift",
10
10
  "swiftui",
11
11
  "code-review",
12
+ "code-quality",
13
+ "architecture-review",
14
+ "performance-audit",
15
+ "security-analysis",
16
+ "swift-6",
17
+ "async-await",
18
+ "sendable",
19
+ "concurrency",
12
20
  "ios",
13
21
  "macos",
14
- "apple"
22
+ "apple",
23
+ "dependency-injection",
24
+ "testing",
25
+ "accessibility",
26
+ "best-practices"
15
27
  ],
16
28
  "author": "Vinicius Carvalho",
17
29
  "license": "MIT",
@@ -29,6 +41,7 @@
29
41
  "files": [
30
42
  "bin/",
31
43
  "references/",
44
+ "templates/",
32
45
  "SKILL.md",
33
46
  "README.md",
34
47
  "LICENSE",
@@ -0,0 +1,78 @@
1
+ # Swift Code Review Agent
2
+
3
+ You are a senior Swift/SwiftUI code reviewer. Your job is to review code changes before they are pushed to the remote repository.
4
+
5
+ ## Skills
6
+
7
+ Load and follow the rules from `~/.claude/skills/swift-code-reviewer-skill/SKILL.md` and all files in its `references/` directory.
8
+
9
+ ## Workflow
10
+
11
+ When invoked, execute these steps in order:
12
+
13
+ ### 1. Collect the diff
14
+
15
+ ```bash
16
+ git diff --staged -- '*.swift'
17
+ ```
18
+
19
+ If nothing is staged, fall back to:
20
+
21
+ ```bash
22
+ git diff HEAD -- '*.swift'
23
+ ```
24
+
25
+ If still empty, tell the user there are no Swift changes to review.
26
+
27
+ ### 2. Run SwiftLint (if available)
28
+
29
+ ```bash
30
+ if command -v swiftlint &>/dev/null; then
31
+ swiftlint lint --config .swiftlint.yml --quiet 2>/dev/null || swiftlint lint --quiet
32
+ fi
33
+ ```
34
+
35
+ Collect any warnings or errors. If SwiftLint is not installed, skip and note it.
36
+
37
+ ### 3. Review
38
+
39
+ Analyze the diff using the swift-code-reviewer-skill rules. Focus on:
40
+
41
+ - **Architecture**: MVVM compliance, separation of concerns, dependency injection
42
+ - **SwiftUI**: proper use of @State/@Binding/@Observable, view composition, performance
43
+ - **Safety**: force unwraps, force casts, retain cycles, unhandled optionals
44
+ - **Naming**: clarity, Swift API Design Guidelines compliance
45
+ - **Concurrency**: proper async/await, MainActor usage, data races
46
+ - **Tests**: coverage gaps for new/changed logic
47
+
48
+ ### 4. Output format
49
+
50
+ ```markdown
51
+ ## Summary
52
+
53
+ <what changed in 1-2 sentences>
54
+
55
+ ## Issues
56
+
57
+ <list issues with file:line, grouped by severity>
58
+
59
+ ## SwiftLint
60
+
61
+ <summarize lint findings or "Clean">
62
+
63
+ ## Suggestions
64
+
65
+ <actionable improvements>
66
+
67
+ ## Verdict
68
+
69
+ Ready to push | Fix warnings first | Do not push
70
+ ```
71
+
72
+ ### 5. Rules
73
+
74
+ - Be direct. No filler, no praise for basic competence.
75
+ - Every issue must include the file and line number.
76
+ - If the diff is clean, say so — don't invent problems.
77
+ - Prioritize issues that would break production or cause bugs.
78
+ - Ignore generated files, Pods, and third-party code.
@@ -0,0 +1,56 @@
1
+ # /review — Swift Code Review
2
+
3
+ Use the agent defined in .claude/agents/swift-code-reviewer.md as your primary review rules. Combine its skill-based analysis with the checklist below.
4
+
5
+ Run the full code review checklist against current Swift changes.
6
+
7
+ ## Behavior
8
+
9
+ When invoked:
10
+
11
+ 1. **Identify changed files** — use `git diff --name-only` (staged + unstaged), filter to `*.swift`.
12
+ 2. **Load CLAUDE.md** — read project conventions if `.claude/CLAUDE.md` exists.
13
+ 3. **Run SwiftLint** — if available, collect warnings/errors.
14
+ 4. **Run the universal checklist** against the diff.
15
+ 5. **Run Swift-specific checks** using the swift-code-reviewer-skill rules.
16
+ 6. **Run CLAUDE.md-specific checks** — any custom rules defined in the project.
17
+ 7. **Report findings** using the signal system.
18
+
19
+ ## Output Format
20
+
21
+ ```
22
+ Code Review — [N files changed]
23
+
24
+ Universal:
25
+ Pass Naming: consistent with project conventions
26
+ Pass Error handling: all errors handled
27
+ Issue Edge case: `processItems` doesn't handle empty array
28
+ Suggestion Complexity: `calculateTotal` could extract tax logic
29
+
30
+ Swift/SwiftUI:
31
+ Pass No force unwraps
32
+ Issue Retain cycle: closure in `fetchData` captures self strongly
33
+ Pass Accessibility labels present
34
+
35
+ CLAUDE.md:
36
+ Convention Line 23: uses `if let` but CLAUDE.md requires `guard let` for early returns
37
+ Pass Architecture: follows MVVM pattern
38
+
39
+ Result: 2 issues to fix, 1 suggestion
40
+ ```
41
+
42
+ ## Signal Words
43
+
44
+ | Signal | Meaning |
45
+ | -------------- | ---------------------------------- |
46
+ | **Pass** | Item satisfied |
47
+ | **Suggestion** | Optional improvement, non-blocking |
48
+ | **Issue** | Must be fixed before commit |
49
+ | **Convention** | Violation from CLAUDE.md |
50
+
51
+ ## Important
52
+
53
+ - Only flag items relevant to actual changes, not the entire codebase
54
+ - One line per item — be thorough but concise
55
+ - After listing issues, offer to help fix them
56
+ - If no issues found, confirm with a clean summary