@softspark/ai-toolkit 4.30.2 → 4.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/README.md +27 -28
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/agents/code-reviewer.md +14 -0
- package/app/agents/frontend-specialist.md +27 -24
- package/app/agents/infrastructure-validator.md +2 -2
- package/app/claude-app/skills/ai-toolkit-rules/SKILL.md +44 -1
- package/app/personas/frontend-lead.md +20 -12
- package/app/rules/claude-toolkit-rules.md +4 -1
- package/app/rules/edit-discipline.md +37 -0
- package/app/skills/app-builder/SKILL.md +37 -6
- package/app/skills/claude-toolkit-rules/SKILL.md +37 -0
- package/app/skills/design-engineering/SKILL.md +87 -102
- package/app/skills/design-engineering/reference/animation-recipes.md +67 -0
- package/app/skills/design-engineering/reference/component-craft.md +28 -0
- package/app/skills/documentation-standards/SKILL.md +1 -1
- package/app/skills/edit-discipline/SKILL.md +50 -0
- package/app/skills/git-conventions/SKILL.md +18 -0
- package/app/skills/output-mode/SKILL.md +41 -0
- package/app/skills/quality-gates/SKILL.md +23 -0
- package/app/skills/review/SKILL.md +10 -0
- package/kb/procedures/{ecosystem-sync-sop.md → sop-ecosystem-sync.md} +2 -2
- package/kb/procedures/{post-release-testing-sop.md → sop-post-release-testing.md} +3 -3
- package/kb/procedures/sop-pre-commit.md +96 -0
- package/kb/procedures/{release-preparation-sop.md → sop-release.md} +87 -26
- package/kb/reference/architecture-overview.md +1 -1
- package/kb/reference/copilot-compatibility.md +1 -1
- package/kb/reference/licensing.md +2 -2
- package/kb/reference/quick-wins-implementation-summary.md +1 -1
- package/kb/reference/supported-tools-registry.md +2 -2
- package/kb/troubleshooting/plugin-double-load.md +1 -1
- package/llms-full.txt +974 -806
- package/llms.txt +6 -5
- package/manifest.json +1 -1
- package/package.json +2 -1
- package/scripts/doctor.py +1 -1
- package/scripts/generate_toolkit_rules_skills.py +189 -0
- package/scripts/validate.py +1 -1
- /package/kb/procedures/{maintenance-sop.md → sop-maintenance.md} +0 -0
- /package/kb/procedures/{release-verification-sop.md → sop-release-verification.md} +0 -0
|
@@ -16,15 +16,71 @@ Based on Emil Kowalski's design engineering philosophy — UI polish, component
|
|
|
16
16
|
- **Invisible details create love.** Most UI refinements users never consciously register — but combined they produce something stunning.
|
|
17
17
|
- **Beauty differentiates.** When functionality is table stakes, aesthetic excellence becomes genuine leverage.
|
|
18
18
|
|
|
19
|
-
## Anti-Slop Visual Checklist
|
|
19
|
+
## Anti-Slop Visual & Structural Checklist
|
|
20
20
|
|
|
21
|
-
Defaults that signal machine-generated UI. Each is a falsifiable
|
|
21
|
+
Defaults that signal machine-generated UI ("AI slop"). Each is a falsifiable rule to uphold:
|
|
22
22
|
|
|
23
|
-
- **Avoid** full-bleed saturated gradient backgrounds (purple-to-pink hero washes)
|
|
24
|
-
- **Avoid** emoji as load-bearing decoration
|
|
25
|
-
- **Avoid** the
|
|
23
|
+
- **Avoid** full-bleed saturated gradient backgrounds (purple-to-pink/blue hero washes) and gradient headlines (`background-clip: text`). Use solid ink or warm neutral tinting.
|
|
24
|
+
- **Avoid** emoji as load-bearing decoration (emoji as icons, bullet markers, or section badges). Use a real icon set (Lucide/Phosphor/Heroicons) or typographic hierarchy.
|
|
25
|
+
- **Avoid** the 3-equal-column card grid with icon-above-heading tiles, nested cards-in-cards, or cards with thick coloured left-edge side stripes.
|
|
26
26
|
- **Avoid** hand-drawn fake imagery in SVG (synthetic "photos", invented logos, faux screenshots). Use a real asset or an honest labeled placeholder.
|
|
27
|
-
- **Avoid**
|
|
27
|
+
- **Avoid** fake re-drawn UI chrome (mock browser bars with traffic-light dots, mock IDE title bars, faux phone frames). Let content stand cleanly or use real screenshots in a `<figure>`.
|
|
28
|
+
- **Avoid** default-attractor sameness (Hero → 3 features → CTA → footer). Pick intentional macrostructures and vary heading placement, column rhythm, and divider language.
|
|
29
|
+
- **Avoid** the overused default font stack (Inter/Roboto on system-ui with no pairing). Apply the **2+1 rule** (display + body + at most 1 outlier face in <=2 slots).
|
|
30
|
+
- **Avoid** italic headers: headings and display type are always roman (`font-style: normal`). Never use single-word italic emphasis inside a headline.
|
|
31
|
+
|
|
32
|
+
## Pre-Emit Self-Critique (Six Axes)
|
|
33
|
+
|
|
34
|
+
Before marking any UI output complete, score it 1–5 on these six axes (score <3 on any axis triggers a revision pass):
|
|
35
|
+
|
|
36
|
+
| # | Axis | Assessment |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| **P** | **Philosophy** | Clear position and intent ("why"), not just arbitrary decoration |
|
|
39
|
+
| **H** | **Hierarchy** | Clear primary / secondary / tertiary weight distinguishable in 2 seconds |
|
|
40
|
+
| **E** | **Execution** | Exact rule weights, contrast ratios, focus rings, zero layout shifts |
|
|
41
|
+
| **S** | **Specificity** | Tailored specifically to this brief, not a generic interchangeable template |
|
|
42
|
+
| **R** | **Restraint** | Removed anything unearned (decorative bloat, redundant cards, excess padding) |
|
|
43
|
+
| **V** | **Variety** | Structurally distinct from previous layouts in the project (not just a color swap) |
|
|
44
|
+
|
|
45
|
+
## The 8 Interactive States Discipline
|
|
46
|
+
|
|
47
|
+
Every interactive element (button, input, select, card, tab, switch) must explicitly handle all 8 states in code. Styling only default + hover is an immediate defect:
|
|
48
|
+
|
|
49
|
+
| State | Trigger | Required Treatment |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **1. Default** | At rest | Clean base styling, defined token bindings |
|
|
52
|
+
| **2. Hover** | Pointer over (`@media (hover: hover)`) | Subtle background shift (4–6%) or 1px translate, no layout jump |
|
|
53
|
+
| **3. Focus** | Keyboard navigation | Visible `:focus-visible` ring (2px solid, 1–2px offset), instant appearance |
|
|
54
|
+
| **4. Active** | Pressed | Pressed-in feel: slight darken, `transform: translateY(1px)` or `scale(0.98)` |
|
|
55
|
+
| **5. Disabled** | Inactive (`disabled`, `aria-disabled`) | 3 channels: `opacity: 0.55`, `cursor: not-allowed`, muted token color |
|
|
56
|
+
| **6. Loading** | Async in-flight (`data-state="loading"`) | Inline spinner replacing icon/badge, label preserved, submit disabled |
|
|
57
|
+
| **7. Error** | Validation failure (`aria-invalid="true"`) | Distinct error token border/message, helper text replaced, error icon |
|
|
58
|
+
| **8. Success** | Operation completed (`data-state="success"`) | Quiet confirmation: subtle green/accent indicator or checkmark, auto-dismiss |
|
|
59
|
+
|
|
60
|
+
## Input Fields & Zero Layout Shift
|
|
61
|
+
|
|
62
|
+
Input fields, textareas, and selects are where almost-right UIs break:
|
|
63
|
+
|
|
64
|
+
- **Constant border width (1px everywhere)**: Never change `border-width` between default, hover, focus, error, or disabled states. State changes go to `background-color`, `outline`, `box-shadow`, or `border-color`.
|
|
65
|
+
- **Reserved transparent outline**: Initialize with `outline: 2px solid transparent; outline-offset: 1px;` so activating `:focus-visible` never shifts layout or thrashes paint.
|
|
66
|
+
- **Matched component heights**: Input height MUST equal adjacent button height (base floor 44px for touch targets).
|
|
67
|
+
- **Reserved helper-text slot**: Allocate `min-height: 1lh` for helper/error text so appearing validation messages do not push downstream page content.
|
|
68
|
+
|
|
69
|
+
## Responsive Non-Negotiables
|
|
70
|
+
|
|
71
|
+
Verify every layout at **320px, 375px, 414px, and 768px**:
|
|
72
|
+
|
|
73
|
+
- **No horizontal scroll**: Apply `overflow-x: clip` (never `hidden`) on **both** `html` and `body`.
|
|
74
|
+
- **Single-line clickable affordances**: Buttons, primary nav links, footer links, and CTAs must never wrap to two lines. Shorten label or reflow parent container.
|
|
75
|
+
- **Image grid tracks**: Always use `minmax(0, 1fr)` instead of bare `1fr` to prevent image intrinsic dimensions from blowing out the grid.
|
|
76
|
+
- **Header wrapping**: Display headers must include `overflow-wrap: anywhere; min-width: 0;`.
|
|
77
|
+
|
|
78
|
+
## Locked Tokens Discipline
|
|
79
|
+
|
|
80
|
+
- All colors and typography must bind to declared tokens (`var(--color-accent)`, `var(--font-display)`).
|
|
81
|
+
- Never improvise inline hex / rgb / OKLCH values in components mid-build.
|
|
82
|
+
- Keep accent footprint under **~5%** of viewport area (accent is for focal emphasis, not surface fill).
|
|
83
|
+
- Tint neutral surfaces toward the primary anchor hue (minimum 0.005 chroma in OKLCH) — avoid flat `#000` / `#fff`.
|
|
28
84
|
|
|
29
85
|
## Minimum-Scale Floors
|
|
30
86
|
|
|
@@ -38,13 +94,13 @@ Accessibility-grounded hard thresholds. Going below these is a defect, not a sty
|
|
|
38
94
|
|
|
39
95
|
Treat these as the lower bound, not the target. Captions and footnotes may approach the floor; primary content should sit comfortably above it.
|
|
40
96
|
|
|
41
|
-
## Context-First Discipline
|
|
97
|
+
## Context-First & Pre-Flight Discipline
|
|
42
98
|
|
|
43
|
-
High-fidelity work MUST be rooted in real context before any pixels are produced
|
|
99
|
+
High-fidelity work MUST be rooted in real context before any pixels are produced:
|
|
44
100
|
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
101
|
+
- **Run Pre-Flight Scan**: Inspect existing `design.md`, package font stacks, palette tokens (`:root`, Tailwind `@theme`), motion libraries (`framer-motion`, `motion`, `gsap`), and spacing scale.
|
|
102
|
+
- **Preserve existing design systems**: Never overwrite established tokens or typography unless explicitly asked.
|
|
103
|
+
- **Lift exact values**: Copy real token variable names and spacing classes straight from source. Do NOT reconstruct token values from memory.
|
|
48
104
|
|
|
49
105
|
## Question-Budget Gate
|
|
50
106
|
|
|
@@ -158,66 +214,9 @@ Exception: modals keep centered origin (viewport-anchored, not trigger-anchored)
|
|
|
158
214
|
|
|
159
215
|
Initial tooltip includes delay; subsequent hovers skip both delay and animation via `[data-instant]` attribute — perceived speed without defeating accidental activation prevention.
|
|
160
216
|
|
|
161
|
-
##
|
|
162
|
-
|
|
163
|
-
### Percentage translations
|
|
164
|
-
|
|
165
|
-
```css
|
|
166
|
-
/* Moves by own height — perfect for toasts, drawers */
|
|
167
|
-
transform: translateY(100%);
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
No hardcoded pixel values needed.
|
|
171
|
-
|
|
172
|
-
### Scale affects children
|
|
173
|
-
|
|
174
|
-
Unlike `width`/`height`, `scale()` proportionally scales content, icons, and text. Intentional feature, not a bug.
|
|
175
|
-
|
|
176
|
-
### 3D transforms
|
|
177
|
-
|
|
178
|
-
```css
|
|
179
|
-
.orbit {
|
|
180
|
-
transform-style: preserve-3d;
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
Enables orbit animations and coin flips without JavaScript.
|
|
185
|
-
|
|
186
|
-
## Clip-path Animation
|
|
187
|
-
|
|
188
|
-
`clip-path: inset(top right bottom left)` creates rectangular clipping regions:
|
|
189
|
-
|
|
190
|
-
### Tab color transitions
|
|
191
|
-
|
|
192
|
-
Stack tab lists, clip the active copy, animate clip-path on change for seamless color shifting.
|
|
193
|
-
|
|
194
|
-
### Hold-to-delete
|
|
195
|
-
|
|
196
|
-
```css
|
|
197
|
-
.delete-overlay {
|
|
198
|
-
clip-path: inset(0 100% 0 0);
|
|
199
|
-
transition: clip-path 200ms ease-out; /* fast snap-back on release */
|
|
200
|
-
}
|
|
201
|
-
.delete-button:active .delete-overlay {
|
|
202
|
-
clip-path: inset(0 0 0 0);
|
|
203
|
-
transition: clip-path 2s linear; /* slow fill while holding */
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Image reveals
|
|
208
|
-
|
|
209
|
-
```css
|
|
210
|
-
.reveal {
|
|
211
|
-
clip-path: inset(0 0 100% 0); /* hidden */
|
|
212
|
-
}
|
|
213
|
-
.reveal.visible {
|
|
214
|
-
clip-path: inset(0 0 0 0); /* revealed */
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### Comparison sliders
|
|
217
|
+
## Advanced Animation Techniques
|
|
219
218
|
|
|
220
|
-
|
|
219
|
+
For advanced transform mastery, 3D orbits, and clip-path animation recipes (tabs, hold-to-delete, image reveals, sliders), see [reference/animation-recipes.md](reference/animation-recipes.md).
|
|
221
220
|
|
|
222
221
|
## Performance Rules
|
|
223
222
|
|
|
@@ -274,21 +273,7 @@ Touch triggers false hover positives — always gate hover animations.
|
|
|
274
273
|
|
|
275
274
|
## Building Loved Components
|
|
276
275
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
1. **Developer experience first** — minimal setup friction, insert once, use globally
|
|
280
|
-
2. **Excellent defaults** — ship beautifully configured out-of-box
|
|
281
|
-
3. **Identity through naming** — a memorable name resonates
|
|
282
|
-
4. **Invisible edge cases** — pause timers when hidden, handle pointer capture during drag
|
|
283
|
-
5. **Transitions over keyframes** — rapid additions cause keyframe restart from zero; transitions retarget smoothly
|
|
284
|
-
|
|
285
|
-
### Cohesion
|
|
286
|
-
|
|
287
|
-
Animation personality should match component identity. Playful components can bounce; professional dashboards stay crisp.
|
|
288
|
-
|
|
289
|
-
### Asymmetric timing
|
|
290
|
-
|
|
291
|
-
Deliberate actions stay slow (2s linear for hold-to-delete), system responses snap fast (200ms ease-out for release).
|
|
276
|
+
For component craftsmanship principles (developer experience, defaults, edge cases, asymmetric timing), see [reference/component-craft.md](reference/component-craft.md).
|
|
292
277
|
|
|
293
278
|
## Review Checklist
|
|
294
279
|
|
|
@@ -326,26 +311,25 @@ Visual work ships through two passes, mirroring the toolkit's verification-befor
|
|
|
326
311
|
|
|
327
312
|
- **MUST** specify exact properties in `transition` (`transition: transform 200ms ease-out`) — never `transition: all`
|
|
328
313
|
- **MUST** use `ease-out` (or a custom curve) on UI appearances; `ease-in` delays feedback at the moment the user's attention peaks
|
|
329
|
-
- **NEVER** animate `height`, `width`, `margin`, or `top/left` — animate `transform` and `opacity` only
|
|
330
|
-
- **
|
|
331
|
-
- **
|
|
332
|
-
- **
|
|
333
|
-
- **MUST**
|
|
334
|
-
- **MUST**
|
|
335
|
-
- **
|
|
336
|
-
- **
|
|
337
|
-
- **MUST**
|
|
338
|
-
- **MUST**
|
|
339
|
-
- **
|
|
340
|
-
- **
|
|
314
|
+
- **NEVER** animate `height`, `width`, `margin`, or `top/left` — animate `transform` and `opacity` only
|
|
315
|
+
- **CRITICAL**: exit is faster than enter. A 2s linear enter (hold-to-delete) needs a 200ms ease-out exit
|
|
316
|
+
- **MANDATORY**: any animation longer than 300ms for UI feedback needs an explicit justification
|
|
317
|
+
- **MUST** implement all 8 interactive states (default, hover, focus-visible, active, disabled, loading, error, success) for every interactive element
|
|
318
|
+
- **MUST** keep `border-width: 1px` constant across all input states (default/hover/focus/error/disabled) with a reserved transparent outline to guarantee zero layout shift
|
|
319
|
+
- **MUST** apply `overflow-x: clip` on both `html` and `body` to eliminate horizontal viewport scrolling on mobile (320px–768px)
|
|
320
|
+
- **MUST** ensure clickable affordance text (buttons, nav links, CTAs) remains single-line across all viewports
|
|
321
|
+
- **MUST** keep all display headings roman (`font-style: normal`) — never use single-word italic emphasis inside headlines
|
|
322
|
+
- **MUST** adhere to the 2+1 typography rule (max 3 families, outlier face used in at most 2 slots)
|
|
323
|
+
- **MUST** lock all colors to named CSS variable tokens — never improvise inline hex/rgb/OKLCH values mid-render
|
|
324
|
+
- **MUST** lift exact values (hex, spacing, font stack, radii) from real source — never reconstruct tokens from memory
|
|
325
|
+
- **MUST** keep mobile touch targets at 44px+ minimum floor
|
|
326
|
+
- **NEVER** ship slop defaults (purple/blue gradient hero washes, gradient text headlines, emoji as icons, cards-in-cards, side-stripe cards, centered-everything 100vh heroes)
|
|
327
|
+
- **NEVER** add filler (dummy stats, fake testimonials, invented logos, lorem) — use honest labeled placeholders
|
|
328
|
+
- **MUST** run pre-emit self-critique scoring (P/H/E/S/R/V) before completing UI implementation
|
|
341
329
|
|
|
342
330
|
## Gotchas
|
|
343
331
|
|
|
344
|
-
|
|
345
|
-
- Framer Motion's `x={100}` prop is a shortcut for `transform: translateX(100px)`, but under load it falls back to the main thread. Use the longhand `style={{ transform: "translateX(100px)" }}` for guaranteed compositor path.
|
|
346
|
-
- `@media (prefers-reduced-motion: reduce)` is widely supported but often forgotten. Users with vestibular disorders or pointer-device sensitivity will notice; include a reduced-motion override for every non-trivial animation.
|
|
347
|
-
- Chrome's Performance tab samples animations, but the sampling rate is 1kHz — sub-millisecond jank is invisible. For micro-animations, prefer `performance.mark` and `measure` with explicit timestamps.
|
|
348
|
-
- CSS keyframe animations re-trigger on every class toggle. On rapidly-updating state (drag, hover), transitions are cheaper and smoother; keyframes are for one-shot entries/exits.
|
|
332
|
+
For compositor edge cases, Framer Motion GPU optimizations, and reduced-motion gotchas, see [reference/animation-recipes.md](reference/animation-recipes.md).
|
|
349
333
|
|
|
350
334
|
## When NOT to Load
|
|
351
335
|
|
|
@@ -354,3 +338,4 @@ Visual work ships through two passes, mirroring the toolkit's verification-befor
|
|
|
354
338
|
- For **information architecture** and user flows — use `/ux-designer` agent
|
|
355
339
|
- For generic CSS patterns without motion — this skill is motion-specific
|
|
356
340
|
- For **brand voice** / content tone — use `/brand-voice`
|
|
341
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Animation Recipes & Advanced Techniques
|
|
2
|
+
|
|
3
|
+
Supplementary reference for `design-engineering` skill covering transform techniques, clip-path animations, and advanced interaction recipes.
|
|
4
|
+
|
|
5
|
+
## Transform Mastery
|
|
6
|
+
|
|
7
|
+
### Percentage Translations
|
|
8
|
+
```css
|
|
9
|
+
/* Moves by own height — perfect for toasts, drawers */
|
|
10
|
+
transform: translateY(100%);
|
|
11
|
+
```
|
|
12
|
+
No hardcoded pixel values needed.
|
|
13
|
+
|
|
14
|
+
### Scale Affects Children
|
|
15
|
+
Unlike `width`/`height`, `scale()` proportionally scales content, icons, and text. Intentional feature, not a bug.
|
|
16
|
+
|
|
17
|
+
### 3D Transforms
|
|
18
|
+
```css
|
|
19
|
+
.orbit {
|
|
20
|
+
transform-style: preserve-3d;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
Enables orbit animations and coin flips without JavaScript.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Clip-Path Animation
|
|
28
|
+
|
|
29
|
+
`clip-path: inset(top right bottom left)` creates rectangular clipping regions:
|
|
30
|
+
|
|
31
|
+
### Tab Color Transitions
|
|
32
|
+
Stack tab lists, clip the active copy, animate clip-path on change for seamless color shifting.
|
|
33
|
+
|
|
34
|
+
### Hold-to-Delete
|
|
35
|
+
```css
|
|
36
|
+
.delete-overlay {
|
|
37
|
+
clip-path: inset(0 100% 0 0);
|
|
38
|
+
transition: clip-path 200ms ease-out; /* fast snap-back on release */
|
|
39
|
+
}
|
|
40
|
+
.delete-button:active .delete-overlay {
|
|
41
|
+
clip-path: inset(0 0 0 0);
|
|
42
|
+
transition: clip-path 2s linear; /* slow fill while holding */
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Image Reveals
|
|
47
|
+
```css
|
|
48
|
+
.reveal {
|
|
49
|
+
clip-path: inset(0 0 100% 0); /* hidden */
|
|
50
|
+
}
|
|
51
|
+
.reveal.visible {
|
|
52
|
+
clip-path: inset(0 0 0 0); /* revealed */
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Comparison Sliders
|
|
57
|
+
Overlay images, clip top one by adjusting right inset based on drag position.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Gotchas & Performance Edge Cases
|
|
62
|
+
|
|
63
|
+
- `transform: translateX(-50%)` on an element that will animate `opacity` triggers a paint on every frame because the browser cannot composite the layer. Add `will-change: transform, opacity` during animation only.
|
|
64
|
+
- Framer Motion's `x={100}` prop falls back to the main thread under load. Use `style={{ transform: "translateX(100px)" }}` for guaranteed GPU compositor path.
|
|
65
|
+
- `@media (prefers-reduced-motion: reduce)` is widely supported but often forgotten; include reduced-motion overrides for every non-trivial animation.
|
|
66
|
+
- Chrome's Performance tab samples animations at 1kHz — sub-millisecond jank is invisible. Prefer `performance.mark` and `measure` with explicit timestamps.
|
|
67
|
+
- CSS keyframe animations re-trigger on every class toggle; transitions are cheaper and smoother on rapidly-updating state (drag, hover).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Component Craft & Design Principles
|
|
2
|
+
|
|
3
|
+
Supplementary reference for `design-engineering` skill covering principles for loved UI components and microinteraction cohesion.
|
|
4
|
+
|
|
5
|
+
## Building Loved Components
|
|
6
|
+
|
|
7
|
+
Five core principles (inspired by Sonner):
|
|
8
|
+
|
|
9
|
+
1. **Developer experience first** — minimal setup friction, insert once, use globally
|
|
10
|
+
2. **Excellent defaults** — ship beautifully configured out-of-box
|
|
11
|
+
3. **Identity through naming** — a memorable name resonates
|
|
12
|
+
4. **Invisible edge cases** — pause timers when hidden, handle pointer capture during drag
|
|
13
|
+
5. **Transitions over keyframes** — rapid additions cause keyframe restart from zero; transitions retarget smoothly
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Personality & Cohesion
|
|
18
|
+
|
|
19
|
+
Animation personality should match component identity:
|
|
20
|
+
- **Playful components**: Can use slightly softer curves or playful timing.
|
|
21
|
+
- **Professional tools & dashboards**: Stay crisp, deterministic, and fast (150–200ms).
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Asymmetric Timing
|
|
26
|
+
|
|
27
|
+
- **Deliberate user actions**: Stay controlled/slow (e.g., 2s linear for hold-to-delete).
|
|
28
|
+
- **System feedback / release**: Snaps fast (e.g., 200ms ease-out).
|
|
@@ -47,7 +47,7 @@ and never authoritative on its own.
|
|
|
47
47
|
|----------|-----------|---------|----------|
|
|
48
48
|
| `reference` | `kb/reference/` | Technical specifications, catalogs, architecture notes, API docs | `agents-catalog.md`, `architecture-overview.md` |
|
|
49
49
|
| `howto` | `kb/howto/` | Step-by-step task guides | `use-corrective-rag.md`, `configure-mcp-server.md` |
|
|
50
|
-
| `procedures` | `kb/procedures/` | SOPs a person follows: release, migration, review | `maintenance
|
|
50
|
+
| `procedures` | `kb/procedures/` | SOPs a person follows: release, migration, review | `sop-maintenance.md`, `sop-release.md` |
|
|
51
51
|
| `troubleshooting` | `kb/troubleshooting/` | Problem resolution, debugging guides | `database-connection-issues.md` |
|
|
52
52
|
| `best-practices` | `kb/best-practices/` | Guidelines, recommendations, standards | `security-checklist.md` |
|
|
53
53
|
| `decisions` | `kb/decisions/` | Architecture decision records and design rationale | `adr-004-kb-migration.md` |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edit-discipline
|
|
3
|
+
description: "Change files with the edit and write tools, never by rewriting them through bash (sed, awk, tee, heredoc, redirection), and show `git diff` before reporting a file-changing task as done. Triggers: edit, write, modify, refactor, patch, fix, diff, review changes."
|
|
4
|
+
effort: low
|
|
5
|
+
user-invocable: false
|
|
6
|
+
allowed-tools: Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Edit Discipline
|
|
10
|
+
|
|
11
|
+
This rule comes from `app/rules/edit-discipline.md` in ai-toolkit. It applies to
|
|
12
|
+
every task in this workspace, not only when it is loaded.
|
|
13
|
+
|
|
14
|
+
# Edit Discipline & Reviewable Changes
|
|
15
|
+
|
|
16
|
+
## Edit files with the editing tools, not the shell
|
|
17
|
+
|
|
18
|
+
Use the `edit` and `write` tools to change a file. Do not rewrite tracked files
|
|
19
|
+
through `bash` with `sed`, `awk`, `tee`, a heredoc, or `>` redirection.
|
|
20
|
+
|
|
21
|
+
This is not a style preference. A shell rewrite is opaque to the host: the
|
|
22
|
+
session records a command, not a change. An `edit` call records which file
|
|
23
|
+
changed and how, so the interface can render it, a reviewer can read it, and a
|
|
24
|
+
later turn can cite it. A `sed` line records none of that, and the only way to
|
|
25
|
+
find out what happened is to read the file again.
|
|
26
|
+
|
|
27
|
+
The shell remains correct for what it is for: running builds, tests, linters,
|
|
28
|
+
git, package managers, and generators that own their own output.
|
|
29
|
+
|
|
30
|
+
## Show the change before calling the work done
|
|
31
|
+
|
|
32
|
+
Before reporting a file-changing task as finished, show what changed:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git diff -- <paths> # tracked files
|
|
36
|
+
git status --short # what is new or removed
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Paste the diff into the reply, or state precisely why it is too large and
|
|
40
|
+
summarise it by file with the counts. A task that reports success without
|
|
41
|
+
showing the change asks the reader to take the result on trust, and the reader
|
|
42
|
+
is the one who has to decide whether to commit it.
|
|
43
|
+
|
|
44
|
+
For an untracked file, show the content you wrote, not a description of it.
|
|
45
|
+
|
|
46
|
+
## Why both halves matter together
|
|
47
|
+
|
|
48
|
+
Editing through the tools makes a change *recordable*; showing the diff makes it
|
|
49
|
+
*reviewed*. Either alone leaves the person deciding whether to ship blind to
|
|
50
|
+
something they are accountable for.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-conventions
|
|
3
|
+
description: "Conventional Commits only (feat, fix, docs, refactor, test, chore); no AI co-authorship trailer and no AI signature in a commit message. Triggers: commit, git, message, changelog, release, pull request."
|
|
4
|
+
effort: low
|
|
5
|
+
user-invocable: false
|
|
6
|
+
allowed-tools: Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Git Conventions
|
|
10
|
+
|
|
11
|
+
This rule comes from `app/rules/git-conventions.md` in ai-toolkit. It applies to
|
|
12
|
+
every task in this workspace, not only when it is loaded.
|
|
13
|
+
|
|
14
|
+
# Git Conventions
|
|
15
|
+
|
|
16
|
+
- Do NOT add `Co-Authored-By: Claude` or any AI co-authorship to commits
|
|
17
|
+
- Do NOT add Claude signatures or attribution to commit messages
|
|
18
|
+
- Conventional commits format: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: output-mode
|
|
3
|
+
description: "Answer concisely: lead with the result, no preamble, tables over prose, no trailing restatement of a diff the reader can already see. Triggers: response style, verbosity, summary, explanation, report."
|
|
4
|
+
effort: low
|
|
5
|
+
user-invocable: false
|
|
6
|
+
allowed-tools: Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Output Mode
|
|
10
|
+
|
|
11
|
+
This rule comes from `app/rules/output-mode.md` in ai-toolkit. It applies to
|
|
12
|
+
every task in this workspace, not only when it is loaded.
|
|
13
|
+
|
|
14
|
+
# Output Mode
|
|
15
|
+
|
|
16
|
+
`output-mode: concise`
|
|
17
|
+
|
|
18
|
+
Default response mode for this project is **concise**. The `brand-voice` skill (when present in ai-toolkit) auto-loads its `concise` rules; assistants without that skill should still apply the directives below.
|
|
19
|
+
|
|
20
|
+
## Concise Mode Directives
|
|
21
|
+
|
|
22
|
+
- **No preamble.** Skip "I'll now...", "Sure, let me...", "Great question!" and similar warm-ups. Start with the answer.
|
|
23
|
+
- **Lead with the result.** Conclusion or output first; explanation only if asked or non-obvious.
|
|
24
|
+
- **Max 3 sentences per closed question.** Yes/no, single-fact, or "where is X" answers stay under three sentences.
|
|
25
|
+
- **Tables and lists over prose** when comparing options, listing steps, or showing values.
|
|
26
|
+
- **No trailing summaries.** If the diff or output already shows what changed, do not restate it.
|
|
27
|
+
- **Drop filler adjectives.** No "nice", "great", "powerful", "robust" unless the user asked for evaluation.
|
|
28
|
+
- **Cite file paths as `path:line`** instead of paragraphs describing where things live.
|
|
29
|
+
- **Reserve longer prose** for: architecture proposals, trade-off analyses, plans with risks. Everything else: terse.
|
|
30
|
+
|
|
31
|
+
## When to escalate to verbose
|
|
32
|
+
|
|
33
|
+
- User explicitly asks: "explain in detail", "walk me through", "give me the full picture".
|
|
34
|
+
- Reporting a non-obvious failure mode where missing context would mislead.
|
|
35
|
+
- Architecture / RFC / ADR / trade-off documents — those have their own structure.
|
|
36
|
+
|
|
37
|
+
## How to override
|
|
38
|
+
|
|
39
|
+
- Per-session: `/brand-voice default` (or `/brand-voice strict` for even tighter)
|
|
40
|
+
- Per-project: change this rule's `output-mode:` value in the project's `CLAUDE.md`
|
|
41
|
+
- Permanent removal: re-run `ai-toolkit install --skip rules` or strip the `<!-- TOOLKIT:output-mode -->` block manually
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quality-gates
|
|
3
|
+
description: "Plan before work over an hour, and hold the gates: ruff clean, mypy --strict clean, pytest coverage above 70 percent, no secrets in code. Triggers: quality, lint, mypy, pytest, coverage, gate, definition of done."
|
|
4
|
+
effort: low
|
|
5
|
+
user-invocable: false
|
|
6
|
+
allowed-tools: Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Quality Gates
|
|
10
|
+
|
|
11
|
+
This rule comes from `app/rules/quality-gates.md` in ai-toolkit. It applies to
|
|
12
|
+
every task in this workspace, not only when it is loaded.
|
|
13
|
+
|
|
14
|
+
# Quality Gates & Mandatory Practices
|
|
15
|
+
|
|
16
|
+
## MANDATORY PRACTICES
|
|
17
|
+
1. **Plan First:** Tasks >1h require Plan, Success Criteria, and Pre-Mortem.
|
|
18
|
+
2. **Quality Gates:**
|
|
19
|
+
* `ruff check .` (0 errors)
|
|
20
|
+
* `mypy --strict src/` (0 errors)
|
|
21
|
+
* `pytest --cov=src` (>70% coverage)
|
|
22
|
+
* **Type Safety:** 100% public APIs, >60% internal.
|
|
23
|
+
3. **Security:** No secrets in code, sanitization, auth z/n.
|
|
@@ -146,6 +146,16 @@ After all reviewers complete:
|
|
|
146
146
|
- [ ] No memory leaks
|
|
147
147
|
- [ ] Optimized loops
|
|
148
148
|
|
|
149
|
+
### Frontend & UI Craft (Anti-Slop Gates)
|
|
150
|
+
- [ ] No gradient text headlines (`background-clip: text`) or saturated purple/blue hero washes
|
|
151
|
+
- [ ] No cliché 3-column card grids with icon-above-title tiles, card-in-card nesting, or side-stripe cards
|
|
152
|
+
- [ ] Interactive elements implement all 8 states (default, hover, focus-visible, active, disabled, loading, error, success)
|
|
153
|
+
- [ ] Input fields maintain constant 1px `border-width` across all states (zero layout shift) and reserve 2px transparent outline
|
|
154
|
+
- [ ] Mobile responsive: `overflow-x: clip` on `html` and `body`; no buttons/links wrapping to 2 lines; image grid tracks use `minmax(0, 1fr)`
|
|
155
|
+
- [ ] Typography: headings are roman (`font-style: normal`, no italic emphasis in headers); max 3 font families (2+1 rule)
|
|
156
|
+
- [ ] Content honesty: no invented metrics ("+47% conversion"), fake testimonials, or placeholder stock logos
|
|
157
|
+
- [ ] No fake re-drawn browser/OS chrome; no emoji used as load-bearing icons
|
|
158
|
+
|
|
149
159
|
### Testing
|
|
150
160
|
- [ ] Tests for new code
|
|
151
161
|
- [ ] Edge cases covered
|
|
@@ -253,5 +253,5 @@ jobs:
|
|
|
253
253
|
|
|
254
254
|
- [Supported Tools Registry](../reference/supported-tools-registry.md) — human-readable per-tool breakdown
|
|
255
255
|
- [MCP Editor Compatibility](../reference/mcp-editor-compatibility.md) — MCP-specific adapter table
|
|
256
|
-
- [Maintenance SOP](maintenance
|
|
257
|
-
- [Release Preparation SOP](release
|
|
256
|
+
- [Maintenance SOP](sop-maintenance.md) — general toolkit upkeep
|
|
257
|
+
- [Release Preparation SOP](sop-release.md) — run the doctor before tagging
|
|
@@ -16,7 +16,7 @@ actually install, from npm, rather than the working tree.
|
|
|
16
16
|
|
|
17
17
|
Sibling procedures exist for `jira-mcp` and `legal-pl-pack`; this is the
|
|
18
18
|
ai-toolkit equivalent. It complements
|
|
19
|
-
[Release Verification](release-verification
|
|
19
|
+
[Release Verification](sop-release-verification.md), which checks the toolkit
|
|
20
20
|
from the maintainer's own installed copy. The difference that matters: this one
|
|
21
21
|
never writes to the maintainer's `~/.claude` or `~/.softspark`.
|
|
22
22
|
|
|
@@ -310,6 +310,6 @@ print(f'removed {sb} ({n} files)')
|
|
|
310
310
|
|
|
311
311
|
## Related
|
|
312
312
|
|
|
313
|
-
- [Release Preparation](release
|
|
314
|
-
- [Release Verification](release-verification
|
|
313
|
+
- [Release Preparation](sop-release.md) — run before tagging
|
|
314
|
+
- [Release Verification](sop-release-verification.md) — the maintainer-install checks
|
|
315
315
|
- [rtk-pack Retirement](../history/completed/rtk-pack-retirement-20260727.md) — what happened the one time this SOP was written and not run
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "SOP: Pre-Commit Gate"
|
|
3
|
+
category: procedures
|
|
4
|
+
service: ai-toolkit
|
|
5
|
+
tags: [pre-commit, quality-gate, shellcheck, bats, validation, secrets]
|
|
6
|
+
version: "1.0.0"
|
|
7
|
+
created: "2026-09-02"
|
|
8
|
+
last_updated: "2026-09-02"
|
|
9
|
+
description: "The local gate to run before every commit to ai-toolkit: staged-file and secret scan, ShellCheck, Python syntax, toolkit validation, and the Bats suite. Runs the same checks CI runs, so main does not go red after a push."
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# SOP: Pre-Commit Gate
|
|
13
|
+
|
|
14
|
+
## Why this exists
|
|
15
|
+
|
|
16
|
+
CI runs on `main` and on pull requests, but it runs *after* the push. Every
|
|
17
|
+
check below already exists in `.github/workflows/ci.yml`; running them locally
|
|
18
|
+
first is what keeps `main` green and keeps a release from becoming a debug
|
|
19
|
+
session. The v4.5.1 postmortem in `sop-release.md` is the case
|
|
20
|
+
where a hook lint failure published while reddening `main` CI.
|
|
21
|
+
|
|
22
|
+
This gate is not a substitute for `sop-release.md`. That SOP gates
|
|
23
|
+
a *tag*; this one gates a *commit*.
|
|
24
|
+
|
|
25
|
+
## Prerequisites
|
|
26
|
+
|
|
27
|
+
`shellcheck`, `python3` and `bats` must be on `PATH`. The suite is the one
|
|
28
|
+
check that silently does nothing when its runner is absent, so install it
|
|
29
|
+
before relying on this gate:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
brew install bats-core shellcheck # macOS
|
|
33
|
+
sudo apt-get install -y bats shellcheck # Debian / Ubuntu
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## The gate
|
|
37
|
+
|
|
38
|
+
Run all five from the repository root. Each mirrors a CI job.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# 1. Staged files: secrets, large blobs, commit-type suggestion
|
|
42
|
+
python3 app/skills/commit/scripts/pre-commit-check.py
|
|
43
|
+
|
|
44
|
+
# 2. ShellCheck hooks -- the CI job that has published while red before
|
|
45
|
+
shellcheck --severity=warning app/hooks/*.sh app/plugins/*/hooks/*.sh
|
|
46
|
+
|
|
47
|
+
# 3. Python syntax across every script the toolkit ships
|
|
48
|
+
python3 -m py_compile scripts/*.py app/skills/*/scripts/*.py
|
|
49
|
+
|
|
50
|
+
# 4. Toolkit integrity: agents, skills, registry drift, content quality
|
|
51
|
+
npm run validate
|
|
52
|
+
|
|
53
|
+
# 5. The suite. Run it ONCE -- see the single-run discipline below
|
|
54
|
+
npm test
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A non-zero exit from any of them is a stop, not a warning to note and push past.
|
|
58
|
+
|
|
59
|
+
## Single-run discipline
|
|
60
|
+
|
|
61
|
+
`npm test` runs the Bats suite with `--jobs 4`. Running it repeatedly to see
|
|
62
|
+
whether a failure is "flaky" hides real ordering bugs and wastes minutes. Run
|
|
63
|
+
it once. If it fails, read the failure and fix the cause; if the same test
|
|
64
|
+
passes on a re-run without a code change, that instability is itself the bug
|
|
65
|
+
and belongs in an issue, not in a retry.
|
|
66
|
+
|
|
67
|
+
## What this gate does not cover
|
|
68
|
+
|
|
69
|
+
- **Cross-platform.** The suite here runs on your machine only. Both
|
|
70
|
+
`ubuntu-latest` and `macos-latest` must be green before a tag; that gate
|
|
71
|
+
lives in `sop-release.md`, Phase 7, and is bound to the exact
|
|
72
|
+
release commit.
|
|
73
|
+
- **Required files.** The `required-files` CI job checks that every file the
|
|
74
|
+
module template mandates is present and that the version is in sync across
|
|
75
|
+
all four manifests. It is cheap and runs on every push.
|
|
76
|
+
- **Provenance and SARIF.** Release-time concerns; see
|
|
77
|
+
`sop-release.md`.
|
|
78
|
+
|
|
79
|
+
## Commit message
|
|
80
|
+
|
|
81
|
+
Conventional Commits, and no AI co-authorship trailer:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
feat(scope): summary in the imperative
|
|
85
|
+
fix(scope): summary in the imperative
|
|
86
|
+
docs|refactor|test|chore(scope): ...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`pre-commit-check.py` suggests a type from the staged paths. It is a
|
|
90
|
+
suggestion; the scope and the summary are yours.
|
|
91
|
+
|
|
92
|
+
## Related
|
|
93
|
+
|
|
94
|
+
- `sop-release.md` -- the pre-tag gate, including cross-platform CI
|
|
95
|
+
- `sop-post-release-testing.md` -- what to verify after a release ships
|
|
96
|
+
- `sop-release-verification.md` -- end-to-end smoke test of an installed build
|