@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.
Files changed (57) hide show
  1. package/README.md +29 -45
  2. package/commands/sk/autopilot.md +2 -2
  3. package/commands/sk/security-check.md +2 -2
  4. package/commands/sk/status.md +4 -9
  5. package/package.json +1 -1
  6. package/skills/.claude/settings.local.json +20 -1
  7. package/skills/sk:accessibility/SKILL.md +10 -1
  8. package/skills/sk:autopilot/SKILL.md +26 -45
  9. package/skills/sk:brainstorming/SKILL.md +6 -6
  10. package/skills/sk:context/SKILL.md +11 -15
  11. package/skills/sk:dashboard/SKILL.md +3 -4
  12. package/skills/sk:dashboard/server.js +0 -65
  13. package/skills/sk:debug/__pycache__/debug_conductor.cpython-314.pyc +0 -0
  14. package/skills/sk:debug/debug_conductor.py +0 -8
  15. package/skills/sk:debug/lib/__pycache__/findings_writer.cpython-314.pyc +0 -0
  16. package/skills/sk:debug/lib/__pycache__/lessons_writer.cpython-314.pyc +0 -0
  17. package/skills/sk:debug/lib/__pycache__/step_runner.cpython-314.pyc +0 -0
  18. package/skills/sk:debug/lib/findings_writer.py +2 -2
  19. package/skills/sk:debug/lib/lessons_writer.py +2 -2
  20. package/skills/sk:debug/lib/step_runner.py +8 -10
  21. package/skills/sk:e2e/SKILL.md +3 -3
  22. package/skills/sk:fast-track/SKILL.md +0 -9
  23. package/skills/sk:frontend-design/SKILL.md +232 -0
  24. package/skills/sk:gates/SKILL.md +2 -3
  25. package/skills/sk:lint/SKILL.md +5 -5
  26. package/skills/sk:perf/SKILL.md +3 -3
  27. package/skills/sk:retro/SKILL.md +1 -2
  28. package/skills/sk:review/SKILL.md +2 -2
  29. package/skills/sk:setup-claude/SKILL.md +1 -2
  30. package/skills/sk:setup-claude/scripts/__pycache__/apply_setup_claude.cpython-314.pyc +0 -0
  31. package/skills/sk:setup-claude/scripts/apply_setup_claude.py +12 -4
  32. package/skills/sk:setup-claude/templates/.claude/statusline.sh +1 -15
  33. package/skills/sk:setup-claude/templates/CLAUDE.md.template +61 -137
  34. package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +2 -13
  35. package/skills/sk:setup-claude/templates/hooks/pre-compact.sh +1 -12
  36. package/skills/sk:setup-claude/templates/hooks/session-start.sh +0 -11
  37. package/skills/sk:setup-claude/templates/hooks/session-stop.sh +0 -7
  38. package/skills/sk:setup-claude/tests/__pycache__/test_apply_setup_claude.cpython-314.pyc +0 -0
  39. package/skills/sk:setup-claude/tests/test_apply_setup_claude.py +2 -33
  40. package/skills/sk:setup-optimizer/SKILL.md +9 -7
  41. package/skills/sk:setup-optimizer/lib/__pycache__/discover.cpython-314.pyc +0 -0
  42. package/skills/sk:setup-optimizer/lib/discover.py +9 -10
  43. package/skills/sk:skill-creator/scripts/__pycache__/generate_report.cpython-314.pyc +0 -0
  44. package/skills/sk:skill-creator/scripts/__pycache__/improve_description.cpython-314.pyc +0 -0
  45. package/skills/sk:skill-creator/scripts/__pycache__/package_skill.cpython-314.pyc +0 -0
  46. package/skills/sk:skill-creator/scripts/__pycache__/run_eval.cpython-314.pyc +0 -0
  47. package/skills/sk:skill-creator/scripts/__pycache__/run_loop.cpython-314.pyc +0 -0
  48. package/skills/sk:skill-creator/scripts/__pycache__/utils.cpython-314.pyc +0 -0
  49. package/skills/sk:skill-creator/scripts/generate_report.py +2 -0
  50. package/skills/sk:skill-creator/scripts/improve_description.py +2 -0
  51. package/skills/sk:skill-creator/scripts/package_skill.py +4 -0
  52. package/skills/sk:skill-creator/scripts/run_eval.py +3 -1
  53. package/skills/sk:skill-creator/scripts/run_loop.py +2 -0
  54. package/skills/sk:skill-creator/scripts/utils.py +2 -0
  55. package/skills/sk:start/SKILL.md +9 -11
  56. package/skills/sk:test/SKILL.md +5 -5
  57. 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()
@@ -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 Exception as e:
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 Exception as e:
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 sys
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
@@ -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) → auto-commit with `fix(e2e): resolve failing E2E scenarios` and re-run `/sk:e2e`. Do not ask the user.
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. Auto-commit tests + fix together with `fix(e2e): [description]`.
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
- Gates own their commits — the fix-commit-rerun loop is fully internal. No manual commit step needed after this gate.
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:
@@ -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 → auto-commit → re-run loop internally
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
 
@@ -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. Auto-commit with message `fix(lint): resolve lint and dep audit issues` — do NOT ask the user
115
- 6. Re-run from step 3 until every tool exits clean
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
- > Gates own their commits — the fix-commit-rerun loop is fully internal. No manual commit step needed after this gate.
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` | sonnet |
175
- | `quality` | sonnet |
174
+ | `full-sail` | opus (inherit) |
175
+ | `quality` | opus (inherit) |
176
176
  | `balanced` | haiku |
177
177
  | `budget` | haiku |
178
178
 
@@ -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. Auto-commit with `fix(perf): resolve [severity] performance findings`. Re-run the audit until critical/high = 0.
16
- - **Medium/low in-scope findings:** fix them in the same commit if straightforward, otherwise log to `tasks/tech-debt.md`.
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
- - **Gates own their commits** — the fix-commit-rerun loop is fully internal. No manual commit step needed after this gate.
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.
@@ -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** | Extract attempt counts from workflow-status.md Notes (e.g., "clean on attempt 3") |
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: auto-commit with `fix(review): address review findings`. Do not ask the user. Re-run `/sk:review` from scratch.
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
- **Note:** Gates own their commits — the fix-commit-rerun loop is fully internal. No manual commit step needed after this gate.
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
 
@@ -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
- dest.write_text(content, encoding="utf-8")
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 Exception:
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 Exception:
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} | ${STEP} | ${BRANCH} | ${TASK}"
36
+ echo "[${CTX_PCT}%] ${MODEL} | ${BRANCH} | ${TASK}"