@kennethsolomon/shipkit 3.10.0 → 3.10.2
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 +29 -45
- package/commands/sk/autopilot.md +2 -2
- package/commands/sk/security-check.md +2 -2
- package/commands/sk/status.md +4 -9
- package/package.json +1 -1
- package/skills/.claude/settings.local.json +20 -1
- package/skills/sk:accessibility/SKILL.md +10 -1
- package/skills/sk:autopilot/SKILL.md +26 -45
- package/skills/sk:brainstorming/SKILL.md +6 -6
- package/skills/sk:context/SKILL.md +11 -15
- package/skills/sk:dashboard/SKILL.md +3 -4
- package/skills/sk:dashboard/server.js +0 -65
- package/skills/sk:debug/__pycache__/debug_conductor.cpython-314.pyc +0 -0
- package/skills/sk:debug/debug_conductor.py +0 -8
- package/skills/sk:debug/lib/__pycache__/findings_writer.cpython-314.pyc +0 -0
- package/skills/sk:debug/lib/__pycache__/lessons_writer.cpython-314.pyc +0 -0
- package/skills/sk:debug/lib/__pycache__/step_runner.cpython-314.pyc +0 -0
- package/skills/sk:debug/lib/findings_writer.py +2 -2
- package/skills/sk:debug/lib/lessons_writer.py +2 -2
- package/skills/sk:debug/lib/step_runner.py +8 -10
- package/skills/sk:e2e/SKILL.md +3 -3
- package/skills/sk:fast-track/SKILL.md +0 -9
- package/skills/sk:frontend-design/SKILL.md +232 -0
- package/skills/sk:gates/SKILL.md +2 -3
- package/skills/sk:lint/SKILL.md +5 -5
- package/skills/sk:perf/SKILL.md +3 -3
- package/skills/sk:retro/SKILL.md +1 -2
- package/skills/sk:review/SKILL.md +2 -2
- package/skills/sk:setup-claude/SKILL.md +1 -2
- package/skills/sk:setup-claude/scripts/__pycache__/apply_setup_claude.cpython-314.pyc +0 -0
- package/skills/sk:setup-claude/scripts/apply_setup_claude.py +12 -4
- package/skills/sk:setup-claude/templates/.claude/statusline.sh +1 -15
- package/skills/sk:setup-claude/templates/CLAUDE.md.template +61 -137
- package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +2 -13
- package/skills/sk:setup-claude/templates/hooks/pre-compact.sh +1 -12
- package/skills/sk:setup-claude/templates/hooks/session-start.sh +0 -11
- package/skills/sk:setup-claude/templates/hooks/session-stop.sh +0 -7
- package/skills/sk:setup-claude/tests/__pycache__/test_apply_setup_claude.cpython-314.pyc +0 -0
- package/skills/sk:setup-claude/tests/test_apply_setup_claude.py +2 -33
- package/skills/sk:setup-optimizer/SKILL.md +9 -7
- package/skills/sk:setup-optimizer/lib/__pycache__/discover.cpython-314.pyc +0 -0
- package/skills/sk:setup-optimizer/lib/discover.py +9 -10
- package/skills/sk:skill-creator/scripts/__pycache__/generate_report.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/__pycache__/improve_description.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/__pycache__/package_skill.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/__pycache__/run_eval.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/__pycache__/run_loop.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/__pycache__/utils.cpython-314.pyc +0 -0
- package/skills/sk:skill-creator/scripts/generate_report.py +2 -0
- package/skills/sk:skill-creator/scripts/improve_description.py +2 -0
- package/skills/sk:skill-creator/scripts/package_skill.py +4 -0
- package/skills/sk:skill-creator/scripts/run_eval.py +3 -1
- package/skills/sk:skill-creator/scripts/run_loop.py +2 -0
- package/skills/sk:skill-creator/scripts/utils.py +2 -0
- package/skills/sk:start/SKILL.md +9 -11
- package/skills/sk:test/SKILL.md +5 -5
- package/skills/sk:setup-claude/templates/tasks/workflow-status.md.template +0 -28
|
@@ -75,7 +75,6 @@ class DebugConductor:
|
|
|
75
75
|
if not self._can_proceed(step):
|
|
76
76
|
print(f"\n⛔ BLOCKED: {self._gate_reason(step)}")
|
|
77
77
|
print("\nRun /debug again to continue from this step.")
|
|
78
|
-
self._save_progress()
|
|
79
78
|
return
|
|
80
79
|
|
|
81
80
|
# Run step and update state
|
|
@@ -94,7 +93,6 @@ class DebugConductor:
|
|
|
94
93
|
proceed = input(f"\n✅ Step {step_num} complete. Continue to step {step_num + 1}? (y/n): ").strip().lower()
|
|
95
94
|
if proceed not in ['y', 'yes', '']:
|
|
96
95
|
print(f"Pausing after step {step_num}. Run /debug again to continue.")
|
|
97
|
-
self._save_progress()
|
|
98
96
|
return
|
|
99
97
|
|
|
100
98
|
print("\n" + "="*70)
|
|
@@ -161,12 +159,6 @@ class DebugConductor:
|
|
|
161
159
|
return "No confirmed hypothesis yet—cannot propose fix."
|
|
162
160
|
return "Precondition not met for this step."
|
|
163
161
|
|
|
164
|
-
def _save_progress(self):
|
|
165
|
-
"""Save current state for resumption (optional)."""
|
|
166
|
-
# Could implement checkpoint system here
|
|
167
|
-
pass
|
|
168
|
-
|
|
169
|
-
|
|
170
162
|
def main():
|
|
171
163
|
"""Entry point for /debug skill."""
|
|
172
164
|
conductor = DebugConductor()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -44,8 +44,8 @@ class FindingsWriter:
|
|
|
44
44
|
self._append_entry(entry)
|
|
45
45
|
print(f"\n✅ Findings written to {self.findings_path}")
|
|
46
46
|
return True
|
|
47
|
-
except
|
|
48
|
-
print(f"\n❌ Error writing findings: {e}")
|
|
47
|
+
except OSError as e:
|
|
48
|
+
print(f"\n❌ Error writing findings to {self.findings_path}: {e}")
|
|
49
49
|
return False
|
|
50
50
|
|
|
51
51
|
def _ensure_file_exists(self):
|
|
@@ -66,8 +66,8 @@ class LessonsWriter:
|
|
|
66
66
|
self._append_lesson(entry)
|
|
67
67
|
print(f"\n✅ New lesson added to {self.lessons_path}")
|
|
68
68
|
return True
|
|
69
|
-
except
|
|
70
|
-
print(f"\n❌ Error writing lesson: {e}")
|
|
69
|
+
except OSError as e:
|
|
70
|
+
print(f"\n❌ Error writing lesson to {self.lessons_path}: {e}")
|
|
71
71
|
return False
|
|
72
72
|
|
|
73
73
|
def _ensure_file_exists(self):
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Execute individual debug steps (3-11)."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shlex
|
|
3
6
|
import subprocess
|
|
4
|
-
from typing import Dict
|
|
5
7
|
from pathlib import Path
|
|
6
|
-
import
|
|
8
|
+
from typing import Dict
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class StepRunner:
|
|
@@ -42,8 +44,7 @@ class StepRunner:
|
|
|
42
44
|
# Recent commits
|
|
43
45
|
print("📋 Recent commits:")
|
|
44
46
|
result = subprocess.run(
|
|
45
|
-
"git log --oneline -10",
|
|
46
|
-
shell=True,
|
|
47
|
+
["git", "log", "--oneline", "-10"],
|
|
47
48
|
capture_output=True,
|
|
48
49
|
text=True
|
|
49
50
|
)
|
|
@@ -52,8 +53,7 @@ class StepRunner:
|
|
|
52
53
|
# Recent diffs
|
|
53
54
|
print("\n📋 Recent file changes:")
|
|
54
55
|
result = subprocess.run(
|
|
55
|
-
"git diff HEAD~3 --stat",
|
|
56
|
-
shell=True,
|
|
56
|
+
["git", "diff", "HEAD~3", "--stat"],
|
|
57
57
|
capture_output=True,
|
|
58
58
|
text=True
|
|
59
59
|
)
|
|
@@ -107,8 +107,7 @@ class StepRunner:
|
|
|
107
107
|
|
|
108
108
|
try:
|
|
109
109
|
result = subprocess.run(
|
|
110
|
-
command,
|
|
111
|
-
shell=True,
|
|
110
|
+
shlex.split(command),
|
|
112
111
|
capture_output=True,
|
|
113
112
|
text=True,
|
|
114
113
|
timeout=30
|
|
@@ -277,8 +276,7 @@ class StepRunner:
|
|
|
277
276
|
if command:
|
|
278
277
|
try:
|
|
279
278
|
result = subprocess.run(
|
|
280
|
-
command,
|
|
281
|
-
shell=True,
|
|
279
|
+
shlex.split(command),
|
|
282
280
|
capture_output=True,
|
|
283
281
|
text=True,
|
|
284
282
|
timeout=30
|
package/skills/sk:e2e/SKILL.md
CHANGED
|
@@ -184,17 +184,17 @@ If any fail → apply Fix & Retest Protocol.
|
|
|
184
184
|
|
|
185
185
|
When this gate requires a fix, classify it before committing:
|
|
186
186
|
|
|
187
|
-
**a. Style/config/wording change** (CSS tweak, copy change, selector fix) →
|
|
187
|
+
**a. Style/config/wording change** (CSS tweak, copy change, selector fix) → include in the gate's squash commit and re-run `/sk:e2e`. Do not ask the user.
|
|
188
188
|
|
|
189
189
|
**b. Logic change** (new branch, modified condition, new data path, query change, new function, API change) → trigger protocol:
|
|
190
190
|
1. Update or add failing unit tests for the new behavior
|
|
191
191
|
2. Re-run `/sk:test` — must pass at 100% coverage
|
|
192
|
-
3.
|
|
192
|
+
3. Commit tests + fix together with `fix(e2e): [description]`.
|
|
193
193
|
4. Re-run `/sk:e2e` from scratch
|
|
194
194
|
|
|
195
195
|
**Exception:** Formatter auto-fixes are never logic changes — bypass protocol automatically.
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
> Squash gate commits — collect all fixes for the pass, then one commit: `fix(e2e): resolve failing E2E scenarios`. Do not commit after each individual fix.
|
|
198
198
|
|
|
199
199
|
**This gate cannot be skipped.** All scenarios must pass before proceeding to `/sk:update-task`.
|
|
200
200
|
|
|
@@ -61,15 +61,6 @@ Before proceeding, check the scope of planned changes:
|
|
|
61
61
|
### 6. Finalize
|
|
62
62
|
- Run `/sk:finish-feature` for changelog + PR
|
|
63
63
|
|
|
64
|
-
## Workflow Status
|
|
65
|
-
|
|
66
|
-
Fast-track updates `tasks/workflow-status.md` with abbreviated steps:
|
|
67
|
-
- Steps 1-2 (read): done
|
|
68
|
-
- Steps 3-6 (explore, design, accessibility, plan): skipped (fast-track)
|
|
69
|
-
- Steps 7-11 (branch, implement, commit): done
|
|
70
|
-
- Steps 12-17 (gates): handled by `/sk:gates`
|
|
71
|
-
- Steps 18-21 (update, finalize, sync, release): done as applicable
|
|
72
|
-
|
|
73
64
|
## Model Routing
|
|
74
65
|
|
|
75
66
|
| Profile | Model |
|
|
@@ -63,6 +63,235 @@ Interpret creatively and make unexpected choices that feel genuinely designed fo
|
|
|
63
63
|
|
|
64
64
|
Remember: Claude is capable of extraordinary creative thinking. Don't hold back on the design direction — show what can be envisioned when thinking outside the box and committing fully to a distinctive aesthetic.
|
|
65
65
|
|
|
66
|
+
## UX Quality Constraints
|
|
67
|
+
|
|
68
|
+
Apply these rules as hard constraints during design. They are organized by priority — address CRITICAL issues first, then HIGH, then MEDIUM. Skip categories irrelevant to the current design (e.g., Charts for a landing page).
|
|
69
|
+
|
|
70
|
+
| Priority | Category | Impact | Key Rule |
|
|
71
|
+
|---|---|---|---|
|
|
72
|
+
| 1 | Accessibility | CRITICAL | Contrast 4.5:1, keyboard nav, aria-labels, focus rings |
|
|
73
|
+
| 2 | Touch & Interaction | CRITICAL | Min 44×44px targets, tap feedback, no hover-only |
|
|
74
|
+
| 3 | Performance | HIGH | WebP/AVIF images, lazy load, skeleton screens, no layout shift |
|
|
75
|
+
| 4 | Style Selection | HIGH | Match style to product type, SVG icons (never emoji), one primary CTA |
|
|
76
|
+
| 5 | Layout & Responsive | HIGH | Mobile-first, breakpoints 375/768/1024/1440, no horizontal scroll |
|
|
77
|
+
| 6 | Typography & Color | MEDIUM | Base 16px body, line-height 1.5, semantic color tokens |
|
|
78
|
+
| 7 | Animation | MEDIUM | 150–300ms duration, transform/opacity only, respect prefers-reduced-motion |
|
|
79
|
+
| 8 | Forms & Feedback | MEDIUM | Visible labels, error near field, loading → success/error on submit |
|
|
80
|
+
| 9 | Navigation | HIGH | Bottom nav ≤5 items, predictable back, deep linking |
|
|
81
|
+
| 10 | Charts & Data | LOW | Match chart to data type, accessible colors, legend visible |
|
|
82
|
+
|
|
83
|
+
### 1. Accessibility (CRITICAL)
|
|
84
|
+
|
|
85
|
+
- Minimum 4.5:1 contrast ratio for normal text (large text 3:1)
|
|
86
|
+
- Visible focus rings on all interactive elements (2–4px outline)
|
|
87
|
+
- Descriptive alt text on all meaningful images
|
|
88
|
+
- `aria-label` on icon-only buttons
|
|
89
|
+
- Tab order matches visual order; full keyboard navigation supported
|
|
90
|
+
- `label[for]` on every form input — never placeholder-only
|
|
91
|
+
- Never convey information by color alone (add icon or text)
|
|
92
|
+
- Respect `prefers-reduced-motion` — reduce or disable animations when set
|
|
93
|
+
- Sequential heading hierarchy h1→h6, no skipped levels
|
|
94
|
+
- Screen reader logical reading order; meaningful accessibilityLabel/Hint
|
|
95
|
+
- Skip-to-main-content link for keyboard users
|
|
96
|
+
|
|
97
|
+
### 2. Touch & Interaction (CRITICAL)
|
|
98
|
+
|
|
99
|
+
- Minimum 44×44pt (iOS) / 48×48dp (Android) tap target — expand hitSlop if icon is smaller
|
|
100
|
+
- Minimum 8px gap between adjacent touch targets
|
|
101
|
+
- Never rely on hover-only for primary interactions — use click/tap
|
|
102
|
+
- Disable buttons during async operations; show spinner or progress
|
|
103
|
+
- Add `cursor-pointer` to all clickable elements (web)
|
|
104
|
+
- Provide visual feedback on press within 100ms (ripple, opacity, elevation)
|
|
105
|
+
- Use `touch-action: manipulation` to eliminate 300ms tap delay (web)
|
|
106
|
+
- Avoid horizontal swipe on scrollable content — prefer vertical scroll
|
|
107
|
+
- Don't block system gestures (back swipe, Control Center, home indicator)
|
|
108
|
+
|
|
109
|
+
### 3. Performance (HIGH)
|
|
110
|
+
|
|
111
|
+
- Use WebP/AVIF with `srcset`/`sizes`; lazy load non-hero images
|
|
112
|
+
- Declare `width`/`height` or `aspect-ratio` on images to prevent CLS
|
|
113
|
+
- Use `font-display: swap` or `optional` to avoid FOIT
|
|
114
|
+
- Preload only critical fonts — avoid preloading every weight variant
|
|
115
|
+
- Lazy load non-hero components via dynamic import / route-level splitting
|
|
116
|
+
- Load third-party scripts `async`/`defer`
|
|
117
|
+
- Reserve space for async content to avoid layout jumps (CLS < 0.1)
|
|
118
|
+
- Virtualize lists with 50+ items
|
|
119
|
+
- Use skeleton/shimmer for loads >300ms — never a blank frame
|
|
120
|
+
- Keep per-frame work <16ms (60fps); move heavy tasks off main thread
|
|
121
|
+
- Debounce/throttle scroll, resize, and input handlers
|
|
122
|
+
|
|
123
|
+
### 4. Style Selection (HIGH)
|
|
124
|
+
|
|
125
|
+
- Match style to product type and industry — no random style mixing
|
|
126
|
+
- Use SVG icons (Heroicons, Lucide) — never emojis as structural icons
|
|
127
|
+
- Use one icon set throughout — consistent stroke width, corner radius, filled vs outline
|
|
128
|
+
- Each screen has exactly one primary CTA; secondary actions are visually subordinate
|
|
129
|
+
- Apply a consistent elevation/shadow scale — no arbitrary shadow values
|
|
130
|
+
- Design light and dark variants together; don't assume light values work in dark mode
|
|
131
|
+
- Blur signals background dismissal (modals, sheets) — not decoration
|
|
132
|
+
- Respect platform idioms (iOS HIG vs Material Design) for navigation, controls, motion
|
|
133
|
+
|
|
134
|
+
### 5. Layout & Responsive (HIGH)
|
|
135
|
+
|
|
136
|
+
- `<meta name="viewport" content="width=device-width, initial-scale=1">` — never disable zoom
|
|
137
|
+
- Design mobile-first; scale up to 768, 1024, 1440
|
|
138
|
+
- No horizontal scroll on mobile; all content fits viewport width
|
|
139
|
+
- Use 4pt/8dp incremental spacing system throughout
|
|
140
|
+
- Consistent `max-w-6xl`/`7xl` container on desktop
|
|
141
|
+
- Define a z-index scale (e.g., 0 / 10 / 20 / 40 / 100 / 1000) — no arbitrary values
|
|
142
|
+
- Fixed navbars/bottom bars must pad underlying scroll content
|
|
143
|
+
- Use `min-h-dvh` instead of `100vh` on mobile
|
|
144
|
+
- Establish hierarchy via size, spacing, contrast — not color alone
|
|
145
|
+
- Core content first on mobile; fold or hide secondary content
|
|
146
|
+
|
|
147
|
+
### 6. Typography & Color (MEDIUM)
|
|
148
|
+
|
|
149
|
+
- Minimum 16px body text on mobile (prevents iOS auto-zoom)
|
|
150
|
+
- Line-height 1.5–1.75 for body text
|
|
151
|
+
- 60–75 characters per line on desktop; 35–60 on mobile
|
|
152
|
+
- Consistent type scale (e.g., 12 / 14 / 16 / 18 / 24 / 32)
|
|
153
|
+
- Bold headings (600–700), regular body (400), medium labels (500)
|
|
154
|
+
- Define semantic color tokens (`--color-primary`, `--color-error`, `--color-surface`) — never raw hex in components
|
|
155
|
+
- Dark mode: use desaturated/lighter tonal variants, not inverted colors; test contrast independently
|
|
156
|
+
- All foreground/background pairs must meet 4.5:1 (AA); use a contrast checker
|
|
157
|
+
- Use tabular/monospaced figures for prices, data columns, and timers
|
|
158
|
+
- Use whitespace intentionally to group related items and separate sections
|
|
159
|
+
|
|
160
|
+
### 7. Animation (MEDIUM)
|
|
161
|
+
|
|
162
|
+
- Duration: 150–300ms for micro-interactions; complex transitions ≤400ms; never >500ms
|
|
163
|
+
- Animate `transform` and `opacity` only — never `width`, `height`, `top`, `left`
|
|
164
|
+
- Use ease-out for entering elements; ease-in for exiting
|
|
165
|
+
- Every animation expresses cause-effect — no purely decorative motion
|
|
166
|
+
- State changes (hover, active, expanded, modal) animate smoothly — no snapping
|
|
167
|
+
- Page transitions maintain spatial continuity (shared element, directional slide)
|
|
168
|
+
- Exit animations should be 60–70% of enter duration to feel responsive
|
|
169
|
+
- Stagger list/grid item entrance by 30–50ms per item
|
|
170
|
+
- Animations must be interruptible — user tap cancels in-progress animation immediately
|
|
171
|
+
- Never block user input during an animation
|
|
172
|
+
- Scale feedback on press: subtle 0.95–1.05 scale on tappable cards/buttons
|
|
173
|
+
- `prefers-reduced-motion` must reduce or disable animations entirely
|
|
174
|
+
|
|
175
|
+
### 8. Forms & Feedback (MEDIUM)
|
|
176
|
+
|
|
177
|
+
- Every input has a visible label — never placeholder-only
|
|
178
|
+
- Show errors immediately below the related field (not only at the top)
|
|
179
|
+
- Mark required fields (asterisk or explicit label)
|
|
180
|
+
- Submit button: loading state → success or error state
|
|
181
|
+
- Auto-dismiss toasts in 3–5s; toasts must not steal focus (`aria-live="polite"`)
|
|
182
|
+
- Confirm before destructive actions (modals, undo toasts)
|
|
183
|
+
- Validate on blur, not on every keystroke
|
|
184
|
+
- Use semantic input types (`email`, `tel`, `number`) for correct mobile keyboard
|
|
185
|
+
- Provide show/hide toggle on password fields
|
|
186
|
+
- Error messages state the cause + how to fix — not just "Invalid input"
|
|
187
|
+
- Multi-step forms show a step indicator and allow back navigation
|
|
188
|
+
- After submit error, auto-focus the first invalid field
|
|
189
|
+
|
|
190
|
+
### 9. Navigation (HIGH)
|
|
191
|
+
|
|
192
|
+
- Bottom navigation: maximum 5 items with both icon and text label
|
|
193
|
+
- Back navigation is predictable and restores scroll/filter state
|
|
194
|
+
- All key screens are deep-linkable via URL/route
|
|
195
|
+
- Current location is visually highlighted in navigation (color, weight, indicator)
|
|
196
|
+
- Modals have a clear close affordance; support swipe-down to dismiss on mobile
|
|
197
|
+
- Never use modals for primary navigation flows
|
|
198
|
+
- Large screens (≥1024px) prefer sidebar; small screens use bottom/top nav
|
|
199
|
+
- Don't mix Tab + Sidebar + Bottom Nav at the same hierarchy level
|
|
200
|
+
- Dangerous actions (logout, delete account) are visually separated from normal nav
|
|
201
|
+
- After route change, move focus to main content region for screen readers
|
|
202
|
+
|
|
203
|
+
### 10. Charts & Data (when applicable)
|
|
204
|
+
|
|
205
|
+
- Match chart type to data: trend → line, comparison → bar, proportion → pie/donut
|
|
206
|
+
- Avoid pie/donut for >5 categories — use bar chart instead
|
|
207
|
+
- Use accessible color palettes; never red/green only (colorblind users)
|
|
208
|
+
- Always show a legend near the chart (not below a scroll fold)
|
|
209
|
+
- Provide tooltips/data labels on hover (web) or tap (mobile)
|
|
210
|
+
- Label all axes with units; avoid rotated labels on mobile
|
|
211
|
+
- Charts must reflow on small screens (horizontal bar instead of vertical, fewer ticks)
|
|
212
|
+
- Show skeleton/shimmer while chart data loads — never an empty axis frame
|
|
213
|
+
- Grid lines should be low-contrast (e.g., `gray-200`) so they don't compete with data
|
|
214
|
+
- Provide a text summary or `aria-label` describing the chart's key insight
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Professional UI Anti-Patterns
|
|
219
|
+
|
|
220
|
+
These are frequently overlooked issues that make UI look unprofessional. Flag any of these in the design spec so implementation avoids them.
|
|
221
|
+
|
|
222
|
+
### Icons & Visual Elements
|
|
223
|
+
- **No emoji as icons** — use Heroicons, Lucide, or equivalent SVG sets
|
|
224
|
+
- **No raster icons** — SVG only; PNGs blur and can't adapt to dark mode
|
|
225
|
+
- **No mixed icon styles** — pick one set; consistent stroke width and fill style throughout
|
|
226
|
+
- **No inconsistent sizing** — define icon size tokens (sm/md/lg = 16/20/24pt)
|
|
227
|
+
- **Pressed states must not shift layout** — use opacity/color/elevation, not transforms that reflow siblings
|
|
228
|
+
|
|
229
|
+
### Interaction
|
|
230
|
+
- **No tap-only no-feedback** — every tappable element responds visually within 100ms
|
|
231
|
+
- **No hover-only states on mobile** — hover states are fine for desktop, never the only affordance
|
|
232
|
+
- **No disabled elements that look enabled** — use `opacity: 0.38–0.5` + `cursor: not-allowed` + semantic `disabled` attribute
|
|
233
|
+
- **No precision-required targets** — avoid requiring taps on thin edges or pixel-perfect areas
|
|
234
|
+
|
|
235
|
+
### Light/Dark Mode
|
|
236
|
+
- **No hardcoded hex in components** — use semantic tokens that map per theme
|
|
237
|
+
- **No light-mode-only testing** — always verify dark mode contrast independently
|
|
238
|
+
- **No weak modal scrims** — use 40–60% black so background doesn't compete with foreground
|
|
239
|
+
- **No color-only state indicators** — always pair color with icon or label
|
|
240
|
+
|
|
241
|
+
### Layout & Spacing
|
|
242
|
+
- **No safe-area violations** — respect notch, Dynamic Island, and gesture bar on mobile
|
|
243
|
+
- **No scroll content hidden behind fixed bars** — add correct insets
|
|
244
|
+
- **No random spacing** — every gap follows the 4/8dp rhythm
|
|
245
|
+
- **No edge-to-edge paragraphs on tablets** — constrain long-form text width for readability
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Pre-Delivery Checklist
|
|
250
|
+
|
|
251
|
+
Include this checklist at the end of every design output. Implementation must pass all applicable items before shipping.
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
### Pre-Delivery Checklist
|
|
255
|
+
|
|
256
|
+
**Accessibility**
|
|
257
|
+
- [ ] All text contrast ≥4.5:1 (normal) or ≥3:1 (large/UI)
|
|
258
|
+
- [ ] Focus rings visible on all interactive elements
|
|
259
|
+
- [ ] All images/icons have alt text or aria-label
|
|
260
|
+
- [ ] No color-only information conveyance
|
|
261
|
+
- [ ] prefers-reduced-motion respected
|
|
262
|
+
|
|
263
|
+
**Touch & Interaction**
|
|
264
|
+
- [ ] All tap targets ≥44×44pt
|
|
265
|
+
- [ ] Every tappable element has pressed-state feedback
|
|
266
|
+
- [ ] No hover-only interactions on mobile
|
|
267
|
+
- [ ] cursor-pointer on all clickable web elements
|
|
268
|
+
|
|
269
|
+
**Layout**
|
|
270
|
+
- [ ] No horizontal scroll at 375px
|
|
271
|
+
- [ ] Safe areas respected (notch, gesture bar, tab bar)
|
|
272
|
+
- [ ] Scroll content not hidden behind fixed bars
|
|
273
|
+
- [ ] 4/8dp spacing rhythm consistent throughout
|
|
274
|
+
|
|
275
|
+
**Typography & Color**
|
|
276
|
+
- [ ] Body text ≥16px on mobile
|
|
277
|
+
- [ ] Semantic color tokens used (no raw hex in components)
|
|
278
|
+
- [ ] Dark mode contrast verified independently
|
|
279
|
+
|
|
280
|
+
**Performance**
|
|
281
|
+
- [ ] Images use WebP/AVIF with declared dimensions
|
|
282
|
+
- [ ] Skeleton/shimmer shown for loads >300ms
|
|
283
|
+
- [ ] No layout shift from async content (CLS < 0.1)
|
|
284
|
+
|
|
285
|
+
**Animation**
|
|
286
|
+
- [ ] All transitions 150–300ms
|
|
287
|
+
- [ ] Only transform/opacity animated (no width/height/top/left)
|
|
288
|
+
- [ ] Animations interruptible; no input blocking
|
|
289
|
+
|
|
290
|
+
**Icons**
|
|
291
|
+
- [ ] No emojis used as icons (SVG only)
|
|
292
|
+
- [ ] Consistent icon family and stroke style throughout
|
|
293
|
+
```
|
|
294
|
+
|
|
66
295
|
## Output Format
|
|
67
296
|
|
|
68
297
|
End every `/sk:frontend-design` session with a structured summary:
|
|
@@ -93,6 +322,9 @@ End every `/sk:frontend-design` session with a structured summary:
|
|
|
93
322
|
|
|
94
323
|
### Implementation Notes
|
|
95
324
|
[Specific Tailwind classes, CSS patterns, or gotchas for /sk:execute-plan]
|
|
325
|
+
|
|
326
|
+
### Pre-Delivery Checklist
|
|
327
|
+
[Copy the checklist from the UX Quality Constraints section above and mark which items are covered by this design, and which need special attention during implementation]
|
|
96
328
|
```
|
|
97
329
|
|
|
98
330
|
After presenting the design summary, you **MUST** stop and ask — do not continue or summarize further:
|
package/skills/sk:gates/SKILL.md
CHANGED
|
@@ -65,11 +65,10 @@ All gates passed. Run /sk:update-task
|
|
|
65
65
|
|
|
66
66
|
## Failure Handling
|
|
67
67
|
|
|
68
|
-
- Each agent handles its own fix →
|
|
68
|
+
- Each agent handles its own fix → re-run loop internally
|
|
69
|
+
- **Squash gate commits:** When a gate requires fixes, collect all fixes for that pass, then make ONE commit: `fix(<gate>): resolve <gate> issues`. Do not commit after each individual fix.
|
|
69
70
|
- If any agent fails after 3 attempts → stop all gates and report to user
|
|
70
71
|
- Do NOT proceed to the next batch if the current batch has unresolved failures
|
|
71
|
-
- Update `tasks/workflow-status.md` for each gate as it completes:
|
|
72
|
-
- Steps 12-17 marked `done` with attempt count in Notes
|
|
73
72
|
|
|
74
73
|
## 3-Strike Protocol
|
|
75
74
|
|
package/skills/sk:lint/SKILL.md
CHANGED
|
@@ -111,10 +111,10 @@ If any analyzer reports errors or the dep audit blocks:
|
|
|
111
111
|
2. Re-run formatters (fixes may need formatting)
|
|
112
112
|
3. Re-launch all analyzers in parallel
|
|
113
113
|
4. Re-run dep audit if any dependency was fixed
|
|
114
|
-
5.
|
|
115
|
-
6.
|
|
114
|
+
5. Re-run from step 3 until every tool exits clean
|
|
115
|
+
6. Once all tools pass clean, make ONE squash commit: `fix(lint): resolve lint and dep audit issues` — do NOT ask the user
|
|
116
116
|
|
|
117
|
-
>
|
|
117
|
+
> Squash gate commits — collect all fixes for the pass, then one commit. Do not commit after each individual fix.
|
|
118
118
|
|
|
119
119
|
### 7. Report Results
|
|
120
120
|
|
|
@@ -171,8 +171,8 @@ Read `.shipkit/config.json` from the project root if it exists.
|
|
|
171
171
|
|
|
172
172
|
| Profile | Model |
|
|
173
173
|
|---------|-------|
|
|
174
|
-
| `full-sail` |
|
|
175
|
-
| `quality` |
|
|
174
|
+
| `full-sail` | opus (inherit) |
|
|
175
|
+
| `quality` | opus (inherit) |
|
|
176
176
|
| `balanced` | haiku |
|
|
177
177
|
| `budget` | haiku |
|
|
178
178
|
|
package/skills/sk:perf/SKILL.md
CHANGED
|
@@ -12,8 +12,8 @@ Run this skill after implementing and passing lint/tests, but before `/sk:review
|
|
|
12
12
|
|
|
13
13
|
## Hard Rules
|
|
14
14
|
|
|
15
|
-
- **Fix all critical and high in-scope findings** (files in `git diff main..HEAD --name-only`) immediately after the audit.
|
|
16
|
-
- **Medium/low in-scope findings:** fix them in the same
|
|
15
|
+
- **Fix all critical and high in-scope findings** (files in `git diff main..HEAD --name-only`) immediately after the audit. Re-run the audit until critical/high = 0. Once clean, make ONE squash commit: `fix(perf): resolve performance findings`.
|
|
16
|
+
- **Medium/low in-scope findings:** fix them in the same pass if straightforward, otherwise log to `tasks/tech-debt.md`.
|
|
17
17
|
- **Pre-existing findings** (files outside the current branch diff): log to `tasks/tech-debt.md` using this format — do NOT fix inline:
|
|
18
18
|
```
|
|
19
19
|
### [YYYY-MM-DD] Found during: sk:perf
|
|
@@ -21,7 +21,7 @@ Run this skill after implementing and passing lint/tests, but before `/sk:review
|
|
|
21
21
|
Issue: description of the performance issue
|
|
22
22
|
Severity: critical | high | medium | low
|
|
23
23
|
```
|
|
24
|
-
- **
|
|
24
|
+
- **Squash gate commits** — collect all fixes for the pass, then one commit. Do not commit after each individual fix.
|
|
25
25
|
- **Every finding must cite a specific file and line number.**
|
|
26
26
|
- **Every finding must include an estimated impact** (high/medium/low) and a recommendation.
|
|
27
27
|
- **Auto-detect the stack** — only run checks relevant to what's present.
|
package/skills/sk:retro/SKILL.md
CHANGED
|
@@ -23,7 +23,6 @@ Read these files to build the retrospective:
|
|
|
23
23
|
|------|----------------|
|
|
24
24
|
| `tasks/todo.md` | Planned tasks — count total, completed, dropped |
|
|
25
25
|
| `tasks/progress.md` | Work log — errors, resolutions, session timestamps |
|
|
26
|
-
| `tasks/workflow-status.md` | Step-by-step status — attempt counts, skip reasons |
|
|
27
26
|
| `tasks/findings.md` | Design decisions — were they validated? |
|
|
28
27
|
| `tasks/lessons.md` | New lessons added during this task |
|
|
29
28
|
| `tasks/tech-debt.md` | Tech debt logged during gates |
|
|
@@ -51,7 +50,7 @@ git rev-list main..HEAD --count
|
|
|
51
50
|
|--------|-----|
|
|
52
51
|
| **Completion rate** | Completed tasks / Planned tasks * 100 |
|
|
53
52
|
| **Velocity** | Commits per day, files changed per day |
|
|
54
|
-
| **Gate performance** |
|
|
53
|
+
| **Gate performance** | Count fix commits per gate from git log (e.g., `fix(lint):`, `fix(test):`) |
|
|
55
54
|
| **Blocker count** | Count "FAIL", "error", "blocked", "3-Strike" entries in tasks/progress.md |
|
|
56
55
|
| **Rework rate** | Count fix commits (fix(lint):, fix(test):, etc.) vs feature commits |
|
|
57
56
|
|
|
@@ -450,14 +450,14 @@ After presenting the review report, fix **all** findings regardless of severity
|
|
|
450
450
|
Severity: critical | high | medium | low
|
|
451
451
|
```
|
|
452
452
|
|
|
453
|
-
After all in-scope fixes are applied:
|
|
453
|
+
After all in-scope fixes are applied: make ONE squash commit with `fix(review): address review findings`. Do not ask the user. Re-run `/sk:review` from scratch.
|
|
454
454
|
|
|
455
455
|
Loop until the review is completely clean (0 findings across all severities for in-scope code).
|
|
456
456
|
|
|
457
457
|
When clean:
|
|
458
458
|
> "Review complete — 0 findings. Run `/sk:finish-feature` to finalize the branch and create a PR."
|
|
459
459
|
|
|
460
|
-
|
|
460
|
+
> Squash gate commits — collect all fixes for the pass, then one commit. Do not commit after each individual fix.
|
|
461
461
|
|
|
462
462
|
### Fix & Retest Protocol
|
|
463
463
|
|
|
@@ -22,7 +22,7 @@ After bootstrapping a project, the recommended workflow becomes:
|
|
|
22
22
|
## What Gets Bootstrapped In The Target Repo
|
|
23
23
|
|
|
24
24
|
### Planning / Memory Files (in `tasks/`)
|
|
25
|
-
- `tasks/todo.md` — plan + checkboxes + results
|
|
25
|
+
- `tasks/todo.md` — plan + checkboxes + results (also tracks workflow progress via checkboxes)
|
|
26
26
|
- `tasks/findings.md` — discoveries + decisions
|
|
27
27
|
- `tasks/progress.md` — chronological work log + test results
|
|
28
28
|
- `tasks/lessons.md` — durable “don’t repeat mistakes” log (**never overwrite**)
|
|
@@ -352,7 +352,6 @@ Rendered from `templates/.claude/settings.json.template`. Contains:
|
|
|
352
352
|
Copied from `templates/.claude/statusline.sh` (made executable). Displays:
|
|
353
353
|
- Context window usage percentage
|
|
354
354
|
- Current model
|
|
355
|
-
- Current workflow step (from `tasks/workflow-status.md`)
|
|
356
355
|
- Git branch
|
|
357
356
|
- Current task name
|
|
358
357
|
|
|
Binary file
|
|
@@ -271,7 +271,16 @@ def _write_file_if_missing(dest: Path, content: str) -> Tuple[str, Path]:
|
|
|
271
271
|
if dest.exists():
|
|
272
272
|
return ("skipped", dest)
|
|
273
273
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
274
|
-
|
|
274
|
+
# Atomic write: write to temp file then rename to avoid TOCTOU race
|
|
275
|
+
import tempfile
|
|
276
|
+
fd, tmp_path = tempfile.mkstemp(dir=dest.parent, suffix=".tmp")
|
|
277
|
+
try:
|
|
278
|
+
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
|
279
|
+
f.write(content)
|
|
280
|
+
Path(tmp_path).replace(dest)
|
|
281
|
+
except BaseException:
|
|
282
|
+
Path(tmp_path).unlink(missing_ok=True)
|
|
283
|
+
raise
|
|
275
284
|
return ("created", dest)
|
|
276
285
|
|
|
277
286
|
|
|
@@ -282,7 +291,7 @@ def _write_file_if_generated(dest: Path, content: str, template_path: Optional[P
|
|
|
282
291
|
return ("created", dest)
|
|
283
292
|
try:
|
|
284
293
|
existing = dest.read_text(encoding="utf-8")
|
|
285
|
-
except
|
|
294
|
+
except (OSError, UnicodeDecodeError):
|
|
286
295
|
return ("skipped", dest)
|
|
287
296
|
if GENERATED_MARKER in existing:
|
|
288
297
|
# Check if content is identical (fast path)
|
|
@@ -311,7 +320,7 @@ def _plan_file_if_generated(dest: Path, content: str) -> str:
|
|
|
311
320
|
return "created"
|
|
312
321
|
try:
|
|
313
322
|
existing = dest.read_text(encoding="utf-8")
|
|
314
|
-
except
|
|
323
|
+
except (OSError, UnicodeDecodeError):
|
|
315
324
|
return "skipped"
|
|
316
325
|
if GENERATED_MARKER not in existing:
|
|
317
326
|
return "skipped"
|
|
@@ -442,7 +451,6 @@ def apply(
|
|
|
442
451
|
add("templates/tasks/progress.md.template", "tasks/progress.md", "missing")
|
|
443
452
|
add("templates/tasks/lessons.md.template", "tasks/lessons.md", "missing")
|
|
444
453
|
add("templates/tasks/security-findings.md.template", "tasks/security-findings.md", "missing")
|
|
445
|
-
add("templates/tasks/workflow-status.md.template", "tasks/workflow-status.md", "missing")
|
|
446
454
|
add("templates/tasks/cross-platform.md.template", "tasks/cross-platform.md", "missing")
|
|
447
455
|
|
|
448
456
|
# commands (update if generated)
|
|
@@ -26,20 +26,6 @@ fi
|
|
|
26
26
|
# Branch
|
|
27
27
|
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "none")
|
|
28
28
|
|
|
29
|
-
# Current workflow step
|
|
30
|
-
STEP="—"
|
|
31
|
-
if [ -f "tasks/workflow-status.md" ]; then
|
|
32
|
-
NEXT_LINE=$(grep -E ">>\s*next\s*<<" "tasks/workflow-status.md" 2>/dev/null | head -1)
|
|
33
|
-
if [ -n "$NEXT_LINE" ]; then
|
|
34
|
-
# Extract step number and name from table row
|
|
35
|
-
STEP_NUM=$(echo "$NEXT_LINE" | grep -oE '^\|[[:space:]]*[0-9]+' | grep -oE '[0-9]+')
|
|
36
|
-
STEP_NAME=$(echo "$NEXT_LINE" | sed 's/.*| *>> next << *|.*//' | sed 's/|.*//;s/^ *//;s/ *$//')
|
|
37
|
-
if [ -n "$STEP_NUM" ]; then
|
|
38
|
-
STEP="Step ${STEP_NUM}"
|
|
39
|
-
fi
|
|
40
|
-
fi
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
29
|
# Task name from todo.md
|
|
44
30
|
TASK="—"
|
|
45
31
|
if [ -f "tasks/todo.md" ]; then
|
|
@@ -47,4 +33,4 @@ if [ -f "tasks/todo.md" ]; then
|
|
|
47
33
|
fi
|
|
48
34
|
|
|
49
35
|
# Output single line
|
|
50
|
-
echo "[${CTX_PCT}%] ${MODEL} | ${
|
|
36
|
+
echo "[${CTX_PCT}%] ${MODEL} | ${BRANCH} | ${TASK}"
|