@kennethsolomon/shipkit 3.1.0 → 3.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/README.md +1 -0
- package/commands/sk/security-check.md +16 -15
- package/package.json +1 -1
- package/skills/sk:accessibility/SKILL.md +13 -8
- package/skills/sk:perf/SKILL.md +12 -11
- package/skills/sk:seo-audit/SKILL.md +283 -0
package/README.md
CHANGED
|
@@ -204,6 +204,7 @@ Requirement changes → /sk:change → re-enter at correct step
|
|
|
204
204
|
| `/sk:test` | Auto-detect and run all test suites, verify 100% coverage on new code |
|
|
205
205
|
| `/sk:security-check` | OWASP security audit across changed code |
|
|
206
206
|
| `/sk:perf` | Performance audit: bundle size, N+1 queries, Core Web Vitals |
|
|
207
|
+
| `/sk:seo-audit` | SEO audit — dual-mode (source templates + dev server), ask-before-fix, checklist output to `tasks/seo-findings.md` |
|
|
207
208
|
| `/sk:review` | Rigorous self-review across 7 dimensions |
|
|
208
209
|
|
|
209
210
|
### Shipping
|
|
@@ -108,7 +108,7 @@ Detect the project stack from `CLAUDE.md`, `package.json`, `composer.json`, `pyp
|
|
|
108
108
|
|
|
109
109
|
## Generate Report
|
|
110
110
|
|
|
111
|
-
Write findings to `tasks/security-findings.md` using this format
|
|
111
|
+
Write findings to `tasks/security-findings.md` using this format. **Never overwrite** `tasks/security-findings.md` — append new audits with a date header. Old run checkboxes stay as-is (audit trail); only update findings from the current run.
|
|
112
112
|
|
|
113
113
|
```markdown
|
|
114
114
|
# Security Audit — YYYY-MM-DD
|
|
@@ -119,42 +119,43 @@ Write findings to `tasks/security-findings.md` using this format:
|
|
|
119
119
|
|
|
120
120
|
## Critical (must fix before deploy)
|
|
121
121
|
|
|
122
|
-
- **[FILE:LINE]** Description of vulnerability
|
|
122
|
+
- [ ] **[FILE:LINE]** Description of vulnerability
|
|
123
123
|
**Standard:** OWASP A03 — Injection (CWE-89)
|
|
124
124
|
**Risk:** What could happen if exploited
|
|
125
125
|
**Recommendation:** How to fix it
|
|
126
|
+
- [x] **[FILE:LINE]** Description *(resolved)*
|
|
126
127
|
|
|
127
128
|
## High (fix before production)
|
|
128
129
|
|
|
129
|
-
- **[FILE:LINE]** Description
|
|
130
|
+
- [ ] **[FILE:LINE]** Description
|
|
130
131
|
**Standard:** ...
|
|
131
132
|
**Risk:** ...
|
|
132
133
|
**Recommendation:** ...
|
|
133
134
|
|
|
134
135
|
## Medium (should fix)
|
|
135
136
|
|
|
136
|
-
- **[FILE:LINE]** Description
|
|
137
|
+
- [ ] **[FILE:LINE]** Description
|
|
137
138
|
**Standard:** ...
|
|
138
139
|
**Recommendation:** ...
|
|
139
140
|
|
|
140
141
|
## Low / Informational
|
|
141
142
|
|
|
142
|
-
- **[FILE:LINE]** Description
|
|
143
|
+
- [ ] **[FILE:LINE]** Description
|
|
143
144
|
**Recommendation:** ...
|
|
144
145
|
|
|
145
146
|
## Passed Checks
|
|
146
147
|
|
|
147
|
-
-
|
|
148
|
+
- [Categories with no findings]
|
|
148
149
|
|
|
149
150
|
## Summary
|
|
150
151
|
|
|
151
|
-
| Severity |
|
|
152
|
-
|
|
153
|
-
| Critical | N |
|
|
154
|
-
| High | N |
|
|
155
|
-
| Medium | N |
|
|
156
|
-
| Low | N |
|
|
157
|
-
| **Total** | **N** |
|
|
152
|
+
| Severity | Open | Resolved this run |
|
|
153
|
+
|----------|------|-------------------|
|
|
154
|
+
| Critical | N | N |
|
|
155
|
+
| High | N | N |
|
|
156
|
+
| Medium | N | N |
|
|
157
|
+
| Low | N | N |
|
|
158
|
+
| **Total** | **N** | **N** |
|
|
158
159
|
```
|
|
159
160
|
|
|
160
161
|
## When Done
|
|
@@ -162,12 +163,12 @@ Write findings to `tasks/security-findings.md` using this format:
|
|
|
162
163
|
Tell the user:
|
|
163
164
|
|
|
164
165
|
> "Security audit complete. Findings saved to `tasks/security-findings.md`.
|
|
165
|
-
> - **Critical:** N | **High:** N | **Medium:** N | **Low:** N
|
|
166
|
+
> - **Critical:** N open (N resolved) | **High:** N open (N resolved) | **Medium:** N open | **Low:** N open
|
|
166
167
|
>
|
|
167
168
|
> Review the findings, then run `/sk:finish-feature` when ready to finalize."
|
|
168
169
|
|
|
169
170
|
If there are Critical or High findings:
|
|
170
|
-
> "There are critical/high findings that
|
|
171
|
+
> "There are critical/high findings that MUST be fixed before merging. These are HARD GATE items — `- [ ]` findings block all forward progress. Fix them, then re-run `/sk:security-check` to verify."
|
|
171
172
|
|
|
172
173
|
**Do not auto-fix.** The user decides what to address.
|
|
173
174
|
|
package/package.json
CHANGED
|
@@ -89,20 +89,25 @@ Write findings to `tasks/accessibility-findings.md`:
|
|
|
89
89
|
|
|
90
90
|
## Failures (must fix)
|
|
91
91
|
|
|
92
|
-
- **[Component/File:Line]** Description
|
|
92
|
+
- [ ] **[Component/File:Line]** Description
|
|
93
|
+
**Criterion:** WCAG X.X.X — [Name]
|
|
94
|
+
**Impact:** [Who is affected and how]
|
|
95
|
+
**Recommendation:** [How to fix]
|
|
96
|
+
|
|
97
|
+
- [x] **[Component/File:Line]** Description *(resolved)*
|
|
93
98
|
**Criterion:** WCAG X.X.X — [Name]
|
|
94
99
|
**Impact:** [Who is affected and how]
|
|
95
100
|
**Recommendation:** [How to fix]
|
|
96
101
|
|
|
97
102
|
## Warnings (should fix)
|
|
98
103
|
|
|
99
|
-
- **[Component/File:Line]** Description
|
|
104
|
+
- [ ] **[Component/File:Line]** Description
|
|
100
105
|
**Criterion:** WCAG X.X.X — [Name]
|
|
101
106
|
**Recommendation:** [How to fix]
|
|
102
107
|
|
|
103
108
|
## Manual Checks Required
|
|
104
109
|
|
|
105
|
-
- [Things that require human/screen reader testing]
|
|
110
|
+
- [ ] [Things that require human/screen reader testing]
|
|
106
111
|
|
|
107
112
|
## Passed Checks
|
|
108
113
|
|
|
@@ -110,11 +115,11 @@ Write findings to `tasks/accessibility-findings.md`:
|
|
|
110
115
|
|
|
111
116
|
## Summary
|
|
112
117
|
|
|
113
|
-
| Level |
|
|
114
|
-
|
|
115
|
-
| Failures | N
|
|
116
|
-
| Warnings | N
|
|
117
|
-
| Manual | N
|
|
118
|
+
| Level | Open | Resolved this run |
|
|
119
|
+
|----------|------|-------------------|
|
|
120
|
+
| Failures | N | N |
|
|
121
|
+
| Warnings | N | N |
|
|
122
|
+
| Manual | N | N |
|
|
118
123
|
```
|
|
119
124
|
|
|
120
125
|
**Never overwrite** `tasks/accessibility-findings.md` — append new audits with a date header.
|
package/skills/sk:perf/SKILL.md
CHANGED
|
@@ -120,24 +120,25 @@ Write findings to `tasks/perf-findings.md`:
|
|
|
120
120
|
|
|
121
121
|
## Critical
|
|
122
122
|
|
|
123
|
-
- **[FILE:LINE]** Description
|
|
123
|
+
- [ ] **[FILE:LINE]** Description
|
|
124
124
|
**Impact:** What happens at scale
|
|
125
125
|
**Recommendation:** How to fix
|
|
126
|
+
- [x] **[FILE:LINE]** Description *(resolved)*
|
|
126
127
|
|
|
127
128
|
## High
|
|
128
129
|
|
|
129
|
-
- **[FILE:LINE]** Description
|
|
130
|
+
- [ ] **[FILE:LINE]** Description
|
|
130
131
|
**Impact:** ...
|
|
131
132
|
**Recommendation:** ...
|
|
132
133
|
|
|
133
134
|
## Medium
|
|
134
135
|
|
|
135
|
-
- **[FILE:LINE]** Description
|
|
136
|
+
- [ ] **[FILE:LINE]** Description
|
|
136
137
|
**Recommendation:** ...
|
|
137
138
|
|
|
138
139
|
## Low
|
|
139
140
|
|
|
140
|
-
- **[FILE:LINE]** Description
|
|
141
|
+
- [ ] **[FILE:LINE]** Description
|
|
141
142
|
**Recommendation:** ...
|
|
142
143
|
|
|
143
144
|
## Passed Checks
|
|
@@ -146,13 +147,13 @@ Write findings to `tasks/perf-findings.md`:
|
|
|
146
147
|
|
|
147
148
|
## Summary
|
|
148
149
|
|
|
149
|
-
| Severity |
|
|
150
|
-
|
|
151
|
-
| Critical | N |
|
|
152
|
-
| High | N |
|
|
153
|
-
| Medium | N |
|
|
154
|
-
| Low | N |
|
|
155
|
-
| **Total** | **N** |
|
|
150
|
+
| Severity | Open | Resolved this run |
|
|
151
|
+
|----------|------|-------------------|
|
|
152
|
+
| Critical | N | N |
|
|
153
|
+
| High | N | N |
|
|
154
|
+
| Medium | N | N |
|
|
155
|
+
| Low | N | N |
|
|
156
|
+
| **Total** | **N** | **N** |
|
|
156
157
|
```
|
|
157
158
|
|
|
158
159
|
**Never overwrite** `tasks/perf-findings.md` — append new audits with a date header.
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sk:seo-audit
|
|
3
|
+
description: "SEO audit for web projects. Dual-mode: scans source templates + optionally fetches from running dev server. Ask-before-fix for mechanical issues. Outputs checklist findings to tasks/seo-findings.md."
|
|
4
|
+
license: Complete terms in LICENSE.txt
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /sk:seo-audit
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Standalone optional command — audits any web project for SEO issues regardless of framework (Laravel, Next.js, Nuxt, plain HTML, etc.). Run at any point after implementation is complete. NOT a numbered workflow step — invoke it independently like `/sk:debug`.
|
|
12
|
+
|
|
13
|
+
Two modes:
|
|
14
|
+
- **Source mode** (always runs): scans template files directly for SEO signals
|
|
15
|
+
- **Server mode** (optional): fetches from a running dev server to validate rendered output
|
|
16
|
+
|
|
17
|
+
Run when: before shipping a client site, after adding new pages, or any time you want to check SEO health.
|
|
18
|
+
|
|
19
|
+
## Hard Rules
|
|
20
|
+
|
|
21
|
+
- **Never auto-apply fixes without explicit user confirmation.**
|
|
22
|
+
- **Every finding must cite a specific `file:line`.**
|
|
23
|
+
- **Every finding is a checkbox:** `- [ ]` (open) or `- [x]` (auto-fixed this run)
|
|
24
|
+
- **Append to `tasks/seo-findings.md`** — never overwrite (use date header per run)
|
|
25
|
+
- **Degrade gracefully** if no server is running — skip Phase 2, note it in report
|
|
26
|
+
- **Structured data validation requires external tools** (Google Rich Results Test) — flag it, don't skip silently
|
|
27
|
+
|
|
28
|
+
## Before You Start
|
|
29
|
+
|
|
30
|
+
1. Read `tasks/findings.md` if it exists — look for site context, target audience, business type (helps tailor content strategy recommendations)
|
|
31
|
+
2. Read `tasks/lessons.md` if it exists — apply any SEO-related lessons
|
|
32
|
+
3. Check if `tasks/seo-findings.md` exists — if yes, read the last dated section to identify previously flagged items (used to populate "Passed Checks" in the new report)
|
|
33
|
+
|
|
34
|
+
## Mode Detection
|
|
35
|
+
|
|
36
|
+
### Source Mode — Always Active
|
|
37
|
+
|
|
38
|
+
Scan the project for template files:
|
|
39
|
+
|
|
40
|
+
| Extension | Framework |
|
|
41
|
+
|-----------|-----------|
|
|
42
|
+
| `.blade.php` | Laravel |
|
|
43
|
+
| `.jsx`, `.tsx` | React / Next.js |
|
|
44
|
+
| `.vue` | Vue / Nuxt |
|
|
45
|
+
| `.html` | Plain HTML / static |
|
|
46
|
+
| `.ejs` | Express / Node |
|
|
47
|
+
| `.njk` | Nunjucks |
|
|
48
|
+
| `.twig` | Twig / Symfony |
|
|
49
|
+
| `.erb` | Ruby on Rails |
|
|
50
|
+
| `.astro` | Astro |
|
|
51
|
+
|
|
52
|
+
Print: `"Source mode: found N template files ([extensions detected])"`
|
|
53
|
+
|
|
54
|
+
### Server Mode — Optional
|
|
55
|
+
|
|
56
|
+
Probe ports in parallel (background curl processes) to avoid 14-second worst-case serial timeout:
|
|
57
|
+
- Ports: 3000, 5173, 8000, 8080, 4321, 4000, 8888
|
|
58
|
+
- Command: `curl -s -I --max-time 2 http://localhost:PORT` (HEAD request to capture both status code and headers)
|
|
59
|
+
- Use the first port that returns HTTP 200 **and** has a `Content-Type: text/html` response header
|
|
60
|
+
|
|
61
|
+
If a port returns 200 but no `Content-Type: text/html` header, skip it — it is likely a non-HTTP service (e.g., a database, gRPC server) and not a web app. Try the next port.
|
|
62
|
+
|
|
63
|
+
If any port qualifies: `"Server mode: detected running dev server at http://localhost:PORT"`
|
|
64
|
+
|
|
65
|
+
If none respond or qualify: `"Server mode: no dev server detected — skipping Phase 2. Start your dev server and re-run for full audit."`
|
|
66
|
+
|
|
67
|
+
> Note: confirm the detected URL looks correct before trusting Phase 2 results.
|
|
68
|
+
|
|
69
|
+
## Phase 1 — Source Audit
|
|
70
|
+
|
|
71
|
+
### Technical SEO
|
|
72
|
+
|
|
73
|
+
- `robots.txt` — exists in project root or `public/`; does NOT contain `Disallow: /` blocking all crawlers
|
|
74
|
+
- `sitemap.xml` — exists in project root or `public/`; referenced in `robots.txt` via `Sitemap:` directive
|
|
75
|
+
- `<html lang="">` — present on all layout/root templates (not empty)
|
|
76
|
+
- Canonical tags — `<link rel="canonical">` present on key page templates
|
|
77
|
+
- No accidental `<meta name="robots" content="noindex">` on public-facing pages
|
|
78
|
+
- No hardcoded `http://` asset URLs in templates (mixed content risk)
|
|
79
|
+
|
|
80
|
+
### On-Page SEO
|
|
81
|
+
|
|
82
|
+
- `<title>` — present in `<head>`, unique across pages, 50–60 characters
|
|
83
|
+
- `<meta name="description">` — present in `<head>`, unique across pages, 150–160 characters
|
|
84
|
+
- Exactly one `<h1>` per page template (not zero, not two+)
|
|
85
|
+
- Heading hierarchy not skipped (no jumping from `<h2>` to `<h4>`)
|
|
86
|
+
- All `<img>` tags have `alt` attribute (even if empty for decorative — but flag empty alt on non-decorative images)
|
|
87
|
+
- Internal `<a>` link text is descriptive — flag anchors with text: "click here", "here", "read more", "link", "this"
|
|
88
|
+
- Image filenames are descriptive — flag patterns like `img001`, `IMG_`, `photo`, `image`, `DSC_`, `screenshot` with no context
|
|
89
|
+
|
|
90
|
+
### Content Signals
|
|
91
|
+
|
|
92
|
+
- Open Graph tags: `og:title`, `og:description`, `og:url`, `og:image` all present in layout
|
|
93
|
+
- Twitter Card tags: `twitter:card` present
|
|
94
|
+
- JSON-LD structured data block: look for `<script type="application/ld+json">` — note presence/absence; do NOT validate schema (requires external tool)
|
|
95
|
+
- Page `<html lang="">` matches expected locale
|
|
96
|
+
|
|
97
|
+
## Phase 2 — Server Audit (Optional)
|
|
98
|
+
|
|
99
|
+
If server detected:
|
|
100
|
+
|
|
101
|
+
1. Fetch `/` and discover up to 4 additional pages (from `<a>` href values in homepage, or from sitemap.xml)
|
|
102
|
+
2. For each page fetched, extract and compare:
|
|
103
|
+
- Rendered `<title>` vs source template value
|
|
104
|
+
- Rendered `<meta name="description">` vs source template value
|
|
105
|
+
- Rendered `<h1>` vs source template value
|
|
106
|
+
- Rendered OG tags vs source template
|
|
107
|
+
3. Flag mismatches: `"/about — Source template declares <title>About Us</title> but rendered output shows <title>My App</title> — framework may be overriding"`
|
|
108
|
+
4. Check HTTP status codes — flag any key page returning non-200
|
|
109
|
+
5. Check for redirect chains on common pages (/ → /home → /index is a chain)
|
|
110
|
+
|
|
111
|
+
> Note in report: "Structured data detected but NOT validated — use Google Rich Results Test (https://search.google.com/test/rich-results) to verify schema markup."
|
|
112
|
+
|
|
113
|
+
## Phase 3 — Ask Before Fix
|
|
114
|
+
|
|
115
|
+
After completing Phase 1 (and Phase 2 if run):
|
|
116
|
+
|
|
117
|
+
1. Collect all auto-fixable findings (see Mechanical Fixes Reference below)
|
|
118
|
+
2. Display numbered list:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
Found N auto-fixable issues:
|
|
122
|
+
1. Missing <title> in resources/views/layouts/app.blade.php
|
|
123
|
+
2. Missing alt attribute on <img> in resources/views/home.blade.php:42
|
|
124
|
+
3. Missing robots.txt
|
|
125
|
+
... (all N items)
|
|
126
|
+
|
|
127
|
+
Apply mechanical fixes? [y/N]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
3. Wait for user response
|
|
131
|
+
4. On `y`: apply each fix in order, log `"Fixed: [description] in [file:line]"`, mark as `- [x]` in report. On individual fix failure: log the error, mark that item `- [ ]`, and continue with remaining fixes.
|
|
132
|
+
5. On `n`: mark all as `- [ ]` in report with Fix instructions
|
|
133
|
+
|
|
134
|
+
## Mechanical Fixes Reference
|
|
135
|
+
|
|
136
|
+
What this skill CAN auto-apply when user confirms:
|
|
137
|
+
|
|
138
|
+
| Issue | Fix Applied |
|
|
139
|
+
|-------|------------|
|
|
140
|
+
| Missing `<title>` in `<head>` | Add `<title>TODO: Add page title (50-60 chars)</title>` |
|
|
141
|
+
| Missing `<meta name="description">` | Add `<meta name="description" content="TODO: Add description (150-160 chars)">` |
|
|
142
|
+
| `<img>` missing `alt` attribute | Add `alt="TODO: Describe this image for screen readers"` |
|
|
143
|
+
| Missing `<link rel="canonical">` | Add `<link rel="canonical" href="TODO: Add canonical URL">` |
|
|
144
|
+
| Missing `robots.txt` | Create `robots.txt`: `User-agent: *\nAllow: /\nSitemap: /sitemap.xml` |
|
|
145
|
+
| Missing `sitemap.xml` | Create `sitemap.xml` scaffold with homepage entry |
|
|
146
|
+
| Multiple `<h1>` on same page | Demote 2nd, 3rd... `<h1>` to `<h2>` |
|
|
147
|
+
| Missing OG tags | Add `og:title`, `og:description`, `og:url` block (with TODO placeholders) |
|
|
148
|
+
| Missing `<html lang="">` | Add `lang="en"` — **note in output: verify correct language code** |
|
|
149
|
+
|
|
150
|
+
Things this skill CANNOT auto-apply (report only):
|
|
151
|
+
- Content quality improvements
|
|
152
|
+
- Keyword targeting
|
|
153
|
+
- Title/description CONTENT (only adds TODOs)
|
|
154
|
+
- Schema markup content (only flags missing)
|
|
155
|
+
- Backlink strategy
|
|
156
|
+
- `<meta name="robots" content="noindex">` removal — only the developer can confirm whether a page is intentionally noindexed
|
|
157
|
+
|
|
158
|
+
## Generate Report
|
|
159
|
+
|
|
160
|
+
Write to `tasks/seo-findings.md` — append with date header, never overwrite.
|
|
161
|
+
|
|
162
|
+
```markdown
|
|
163
|
+
# SEO Audit — YYYY-MM-DD
|
|
164
|
+
|
|
165
|
+
**Mode:** Source only | Source + Server (`http://localhost:PORT`)
|
|
166
|
+
**Templates scanned:** N files ([detected extensions])
|
|
167
|
+
**Pages fetched:** N | none — server not detected
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Critical
|
|
172
|
+
|
|
173
|
+
- [x] `resources/views/layouts/app.blade.php` — Missing `<title>` tag *(auto-fixed — add real title)*
|
|
174
|
+
- [ ] `resources/views/about.blade.php:1` — Missing `<meta name="description">`
|
|
175
|
+
**Impact:** Google may auto-generate a description from page content, often poorly.
|
|
176
|
+
**Fix:** Add `<meta name="description" content="150-160 char description">` in `<head>`
|
|
177
|
+
|
|
178
|
+
## High
|
|
179
|
+
|
|
180
|
+
- [ ] `public/robots.txt` — File missing
|
|
181
|
+
**Impact:** Search engines have no crawl guidance — may index unwanted pages.
|
|
182
|
+
**Fix:** Create `robots.txt` with `User-agent: *`, `Allow: /`, `Sitemap:` directive
|
|
183
|
+
|
|
184
|
+
## Medium
|
|
185
|
+
|
|
186
|
+
- [ ] `resources/views/home.blade.php:42` — `<img src="hero.jpg">` missing alt attribute
|
|
187
|
+
**Impact:** Accessibility violation + missed keyword opportunity.
|
|
188
|
+
**Fix:** Add descriptive `alt="..."` text
|
|
189
|
+
|
|
190
|
+
## Low
|
|
191
|
+
|
|
192
|
+
- [ ] Image filename `IMG_4521.jpg` — not descriptive
|
|
193
|
+
**Impact:** Minor missed keyword signal.
|
|
194
|
+
**Fix:** Rename to describe the image content
|
|
195
|
+
|
|
196
|
+
## Content Strategy — Manual Action
|
|
197
|
+
|
|
198
|
+
- [ ] No JSON-LD structured data detected — consider adding schema markup (Article / Product / LocalBusiness / FAQPage) based on your content type. Validate at: https://search.google.com/test/rich-results
|
|
199
|
+
- [ ] `og:image` missing — social shares will have no preview image. Add a default OG image in your layout.
|
|
200
|
+
- [ ] Submit `sitemap.xml` to Google Search Console for faster indexing
|
|
201
|
+
- [ ] Title tags are present but content is generic ("TODO") — research target keywords for each page
|
|
202
|
+
|
|
203
|
+
## Passed Checks
|
|
204
|
+
|
|
205
|
+
- `robots.txt` exists and allows crawling *(was: missing — fixed in 2026-03-10 audit)*
|
|
206
|
+
- All `<img>` tags have alt attributes
|
|
207
|
+
- Single `<h1>` per page
|
|
208
|
+
|
|
209
|
+
(or "First run — no prior baseline to compare against")
|
|
210
|
+
|
|
211
|
+
## Applied Fixes
|
|
212
|
+
|
|
213
|
+
- Fixed: Added `<title>` placeholder to `resources/views/layouts/app.blade.php`
|
|
214
|
+
- Fixed: Created `public/robots.txt`
|
|
215
|
+
|
|
216
|
+
(or "No fixes applied this run")
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Summary
|
|
221
|
+
|
|
222
|
+
| Severity | Open | Fixed this run |
|
|
223
|
+
|----------|------|----------------|
|
|
224
|
+
| Critical | 1 | 1 |
|
|
225
|
+
| High | 1 | 0 |
|
|
226
|
+
| Medium | 3 | 0 |
|
|
227
|
+
| Low | 2 | 0 |
|
|
228
|
+
| Content Strategy | 4 | — |
|
|
229
|
+
| **Total** | **11** | **1** |
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Never overwrite** `tasks/seo-findings.md` — append new audits with a date header.
|
|
233
|
+
|
|
234
|
+
## When Done
|
|
235
|
+
|
|
236
|
+
If Critical or High items are open:
|
|
237
|
+
> "SEO audit complete. **N critical/high issues** need attention before this site will rank well. Findings and checklist in `tasks/seo-findings.md`."
|
|
238
|
+
|
|
239
|
+
If only Medium/Low/Content Strategy open:
|
|
240
|
+
> "Technical SEO is solid. **N medium/low polish items** and **N content strategy items** noted in `tasks/seo-findings.md`. Check off items as you address them."
|
|
241
|
+
|
|
242
|
+
If all clean:
|
|
243
|
+
> "SEO audit passed — no issues found. `tasks/seo-findings.md` updated with clean baseline."
|
|
244
|
+
|
|
245
|
+
If fixes were declined (`n`):
|
|
246
|
+
> "SEO audit complete. **N auto-fixable issues** left open (fixes declined). Checklist in `tasks/seo-findings.md` — check off items as you manually address them."
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Fix & Retest Protocol
|
|
251
|
+
|
|
252
|
+
When applying an SEO fix, classify it before committing:
|
|
253
|
+
|
|
254
|
+
**a. Template/config change** (adding a meta tag, fixing alt text, scaffolding robots.txt, adding lang attribute, creating sitemap.xml) → commit and re-run `/sk:seo-audit`. No test update needed.
|
|
255
|
+
|
|
256
|
+
**b. Logic change** (changing how a framework generates meta tags, modifying a layout component's data-fetching or rendering logic, changing routing that affects canonical URLs) → trigger protocol:
|
|
257
|
+
1. Update or add failing unit tests for the new behavior
|
|
258
|
+
2. Re-run `/sk:test` — must pass at 100% coverage
|
|
259
|
+
3. Commit (tests + fix together in one commit)
|
|
260
|
+
4. Re-run `/sk:seo-audit` to verify the fix resolved the finding
|
|
261
|
+
|
|
262
|
+
**Common logic-change SEO fixes:**
|
|
263
|
+
- Changing a Next.js `generateMetadata()` function → update tests asserting metadata output
|
|
264
|
+
- Modifying a Laravel controller that sets page title → update feature tests
|
|
265
|
+
- Changing a Vue component that injects `<head>` tags → update component tests
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Model Routing
|
|
270
|
+
|
|
271
|
+
Read `.shipkit/config.json` from the project root if it exists.
|
|
272
|
+
|
|
273
|
+
- If `model_overrides["sk:seo-audit"]` is set, use that model — it takes precedence.
|
|
274
|
+
- Otherwise use the `profile` field. Default: `balanced`.
|
|
275
|
+
|
|
276
|
+
| Profile | Model |
|
|
277
|
+
|---------|-------|
|
|
278
|
+
| `full-sail` | sonnet |
|
|
279
|
+
| `quality` | sonnet |
|
|
280
|
+
| `balanced` | sonnet |
|
|
281
|
+
| `budget` | haiku |
|
|
282
|
+
|
|
283
|
+
> `opus` = inherit (uses the current session model). When spawning sub-agents via the Agent tool, pass `model: "<resolved-model>"`.
|