vibesuite 1.0.0 → 1.0.1
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/.agent/skills/nextjs-standards/SKILL.md +193 -0
- package/.agent/skills/nextjs-standards/scripts/vibe-verify.py +150 -0
- package/.agent/skills/nextjs-standards/templates/Coding_Guidelines.md +337 -0
- package/.agent/skills/nextjs-standards/templates/Issue_Template.md +194 -0
- package/.agent/skills/remotion/SKILL.md +45 -0
- package/.agent/skills/remotion/rules/3d.md +86 -0
- package/.agent/skills/remotion/rules/animations.md +29 -0
- package/.agent/skills/remotion/rules/assets/charts-bar-chart.tsx +173 -0
- package/.agent/skills/remotion/rules/assets/text-animations-typewriter.tsx +100 -0
- package/.agent/skills/remotion/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/.agent/skills/remotion/rules/assets.md +78 -0
- package/.agent/skills/remotion/rules/audio.md +172 -0
- package/.agent/skills/remotion/rules/calculate-metadata.md +104 -0
- package/.agent/skills/remotion/rules/can-decode.md +75 -0
- package/.agent/skills/remotion/rules/charts.md +58 -0
- package/.agent/skills/remotion/rules/compositions.md +141 -0
- package/.agent/skills/remotion/rules/display-captions.md +126 -0
- package/.agent/skills/remotion/rules/extract-frames.md +229 -0
- package/.agent/skills/remotion/rules/fonts.md +152 -0
- package/.agent/skills/remotion/rules/get-audio-duration.md +58 -0
- package/.agent/skills/remotion/rules/get-video-dimensions.md +68 -0
- package/.agent/skills/remotion/rules/get-video-duration.md +58 -0
- package/.agent/skills/remotion/rules/gifs.md +138 -0
- package/.agent/skills/remotion/rules/images.md +130 -0
- package/.agent/skills/remotion/rules/import-srt-captions.md +67 -0
- package/.agent/skills/remotion/rules/lottie.md +68 -0
- package/.agent/skills/remotion/rules/maps.md +403 -0
- package/.agent/skills/remotion/rules/measuring-dom-nodes.md +35 -0
- package/.agent/skills/remotion/rules/measuring-text.md +143 -0
- package/.agent/skills/remotion/rules/parameters.md +98 -0
- package/.agent/skills/remotion/rules/sequencing.md +118 -0
- package/.agent/skills/remotion/rules/tailwind.md +11 -0
- package/.agent/skills/remotion/rules/text-animations.md +20 -0
- package/.agent/skills/remotion/rules/timing.md +179 -0
- package/.agent/skills/remotion/rules/transcribe-captions.md +19 -0
- package/.agent/skills/remotion/rules/transitions.md +122 -0
- package/.agent/skills/remotion/rules/trimming.md +53 -0
- package/.agent/skills/remotion/rules/videos.md +171 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +293 -0
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-311.pyc +0 -0
- package/.agent/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-311.pyc +0 -0
- package/.agent/skills/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/skills/vercel-ai-sdk/SKILL.md +1 -0
- package/.agent/workflows/README.md +294 -194
- package/.agent/workflows/agent_reset.md +37 -0
- package/.agent/workflows/build_vibecode_project_v3.md +270 -0
- package/.agent/workflows/continue_build.md +183 -0
- package/.agent/workflows/finalize_build.md +207 -0
- package/.agent/workflows/init_vibecode_genesis_v3.md +190 -0
- package/.agent/workflows/prime_agent.md +70 -171
- package/.agent/workflows/remotion-build.md +323 -0
- package/package.json +2 -2
- package/src/cli.js +45 -27
- package/src/utils.js +376 -4
- package/.agent/skills/prime-agent/SKILL.md +0 -97
- /package/.agent/workflows/{build_vibecode_project_v2.md → LEGACY/build_vibecode_project_v2.md} +0 -0
- /package/.agent/workflows/{init_vibecode_genesis.md → LEGACY/init_vibecode_genesis_v1.md} +0 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nextjs-standards
|
|
3
|
+
description: Comprehensive coding standards, verification protocols, and templates for Next.js App Router projects. Auto-loads on Next.js detection.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Next.js Coding Standards Skill
|
|
7
|
+
|
|
8
|
+
> **Auto-Load Trigger:** Presence of `next.config.*` or `"next"` in `package.json`
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Starting a new Next.js project
|
|
13
|
+
- Before any TypeScript/React file edit
|
|
14
|
+
- When context seems lost mid-session
|
|
15
|
+
- After `/agent_reset` or `/prime_agent`
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🛑 Verification Protocol (MANDATORY)
|
|
20
|
+
|
|
21
|
+
### After Every TypeScript/TSX File Edit
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx tsc --noEmit
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**If this fails:**
|
|
28
|
+
1. DO NOT proceed to next file
|
|
29
|
+
2. Fix the type error immediately
|
|
30
|
+
3. Re-run until it passes
|
|
31
|
+
4. Only then continue
|
|
32
|
+
|
|
33
|
+
### Before Any Handoff
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
python scripts/vibe-verify.py
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
All checks must pass before claiming "done."
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The Blueprint & Build Protocol
|
|
44
|
+
|
|
45
|
+
### Phase 1: Blueprint (Before Coding)
|
|
46
|
+
1. Check `docs/features/` for existing patterns
|
|
47
|
+
2. Create/update `docs/features/FeatureName.md`
|
|
48
|
+
3. Wait for approval before coding
|
|
49
|
+
|
|
50
|
+
### Phase 2: Build (Implementation)
|
|
51
|
+
1. Announce which FR-XXX you're implementing
|
|
52
|
+
2. Reference the corresponding issue in `docs/issues/`
|
|
53
|
+
3. Implement one step at a time
|
|
54
|
+
4. `tsc --noEmit` after every file
|
|
55
|
+
5. Mark acceptance criteria as complete
|
|
56
|
+
|
|
57
|
+
### Phase 3: Finalization
|
|
58
|
+
1. Run full verification (`vibe-verify.py`)
|
|
59
|
+
2. Update issue file with completion status
|
|
60
|
+
3. Generate handoff summary
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Full-Stack Type Safety
|
|
65
|
+
|
|
66
|
+
The AI reliability secret: **TypeScript tells you when you broke something.**
|
|
67
|
+
|
|
68
|
+
### Core Principle
|
|
69
|
+
If you change the backend, the frontend MUST type-check. If type-check fails:
|
|
70
|
+
- The change broke something
|
|
71
|
+
- Fix it before moving on
|
|
72
|
+
- Never ignore type errors
|
|
73
|
+
|
|
74
|
+
### Stack Alignment
|
|
75
|
+
- Server Components fetch data → types flow to client
|
|
76
|
+
- API routes return typed responses → frontend consumes them
|
|
77
|
+
- Prisma schema changes → regenerate client → type-check
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Next.js App Router Rules
|
|
82
|
+
|
|
83
|
+
1. **Server Components Default** — No `'use client'` unless required
|
|
84
|
+
2. **Client Components Sparingly** — Only for interactivity, hooks, browser APIs
|
|
85
|
+
3. **Data Fetching** — In async Server Components, not `useEffect`
|
|
86
|
+
4. **Route Handlers** — All API in `app/api/.../route.ts`
|
|
87
|
+
5. **Caching** — Be explicit: `{ cache: 'no-store' }` or `revalidate = N`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## File Structure (Feature-Sliced)
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
src/
|
|
95
|
+
├── app/ # Next.js App Router pages
|
|
96
|
+
├── features/ # Business domains
|
|
97
|
+
│ └── [FeatureName]/
|
|
98
|
+
│ ├── components/ # Feature-specific components
|
|
99
|
+
│ ├── hooks/ # Feature-specific hooks
|
|
100
|
+
│ └── *.service.ts # Business logic
|
|
101
|
+
├── components/
|
|
102
|
+
│ ├── ui/ # Reusable UI (Button, Card)
|
|
103
|
+
│ └── layout/ # Layout components
|
|
104
|
+
├── lib/ # Utilities, clients
|
|
105
|
+
└── scripts/ # Automation (vibe-verify.py)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Component Rules
|
|
111
|
+
|
|
112
|
+
1. **200-Line Limit** — Refactor if exceeded
|
|
113
|
+
2. **Single Responsibility** — One thing per component
|
|
114
|
+
3. **Props Interface** — Always use TypeScript interfaces
|
|
115
|
+
4. **Custom Hooks** — Extract stateful logic into `use*` hooks
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Styling (Tailwind v4)
|
|
120
|
+
|
|
121
|
+
> **Why Tailwind for AI Reliability:** Tailwind colocates styles with UI in a single file. Unlike separate `.css` files, AI agents see the complete context (logic + styles + structure) without jumping between files. This dramatically reduces hallucinations and context fragmentation.
|
|
122
|
+
|
|
123
|
+
```css
|
|
124
|
+
@import "tailwindcss";
|
|
125
|
+
|
|
126
|
+
@theme {
|
|
127
|
+
--color-background: #ffffff;
|
|
128
|
+
--color-foreground: #0b1221;
|
|
129
|
+
--color-border: #e5e7eb;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@theme .dark {
|
|
133
|
+
--color-background: #0b1221;
|
|
134
|
+
--color-foreground: #e5e7eb;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- Use `@theme` tokens, not `tailwind.config` extensions
|
|
139
|
+
- Utility-first, no custom CSS files
|
|
140
|
+
- Dark mode via `.dark` class on `<html>`
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Backend Rules
|
|
145
|
+
|
|
146
|
+
### Service Layer Pattern
|
|
147
|
+
- **Route Handlers** = Controllers (parse request, return response)
|
|
148
|
+
- **Services** = Business logic (DB queries, calculations)
|
|
149
|
+
|
|
150
|
+
### Validation
|
|
151
|
+
```typescript
|
|
152
|
+
import { z } from 'zod';
|
|
153
|
+
|
|
154
|
+
const schema = z.object({
|
|
155
|
+
email: z.string().email(),
|
|
156
|
+
password: z.string().min(8),
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
All inputs validated with Zod. No exceptions.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Templates Available
|
|
165
|
+
|
|
166
|
+
This skill provides templates in `templates/`:
|
|
167
|
+
|
|
168
|
+
1. **Coding_Guidelines.md** — Copy to `docs/Coding_Guidelines.md`
|
|
169
|
+
2. **Issue_Template.md** — Format for FR issues
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Quick Reference
|
|
174
|
+
|
|
175
|
+
| Command | When |
|
|
176
|
+
|---------|------|
|
|
177
|
+
| `npx tsc --noEmit` | After every TS/TSX edit |
|
|
178
|
+
| `python scripts/vibe-verify.py` | Before handoff |
|
|
179
|
+
| `npm run lint` | Check code style |
|
|
180
|
+
| `npm run build` | Verify production build |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Recovery Protocol
|
|
185
|
+
|
|
186
|
+
If you break something:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
git status # See changed files
|
|
190
|
+
git diff # See what changed
|
|
191
|
+
git checkout -- <file> # Revert specific file
|
|
192
|
+
git stash # Save and revert all
|
|
193
|
+
```
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
VibeCode Verification Script
|
|
4
|
+
============================
|
|
5
|
+
Cross-platform verification for Next.js/TypeScript projects.
|
|
6
|
+
Runs TypeScript check, Lint, and Build to ensure code quality.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python scripts/vibe-verify.py
|
|
10
|
+
python scripts/vibe-verify.py --quick # Skip build, just tsc + lint
|
|
11
|
+
python scripts/vibe-verify.py --strict # Treat warnings as errors
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
import os
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Colors:
|
|
21
|
+
"""ANSI color codes for terminal output."""
|
|
22
|
+
GREEN = '\033[92m'
|
|
23
|
+
RED = '\033[91m'
|
|
24
|
+
YELLOW = '\033[93m'
|
|
25
|
+
BLUE = '\033[94m'
|
|
26
|
+
RESET = '\033[0m'
|
|
27
|
+
BOLD = '\033[1m'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def detect_package_manager() -> str:
|
|
31
|
+
"""Detect which package manager is being used."""
|
|
32
|
+
if Path('pnpm-lock.yaml').exists():
|
|
33
|
+
return 'pnpm'
|
|
34
|
+
elif Path('yarn.lock').exists():
|
|
35
|
+
return 'yarn'
|
|
36
|
+
elif Path('bun.lockb').exists():
|
|
37
|
+
return 'bun'
|
|
38
|
+
else:
|
|
39
|
+
return 'npm'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def run_command(cmd: list[str], description: str) -> tuple[bool, str]:
|
|
43
|
+
"""Run a command and return success status and output."""
|
|
44
|
+
print(f"\n{Colors.BLUE}🔍 {description}...{Colors.RESET}")
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
result = subprocess.run(
|
|
48
|
+
cmd,
|
|
49
|
+
capture_output=True,
|
|
50
|
+
text=True,
|
|
51
|
+
shell=(os.name == 'nt') # Use shell on Windows
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
if result.returncode == 0:
|
|
55
|
+
print(f"{Colors.GREEN}✅ {description}: PASS{Colors.RESET}")
|
|
56
|
+
return True, result.stdout
|
|
57
|
+
else:
|
|
58
|
+
print(f"{Colors.RED}❌ {description}: FAIL{Colors.RESET}")
|
|
59
|
+
# Show error output
|
|
60
|
+
error_output = result.stderr or result.stdout
|
|
61
|
+
if error_output:
|
|
62
|
+
# Limit output to first 20 lines
|
|
63
|
+
lines = error_output.strip().split('\n')[:20]
|
|
64
|
+
for line in lines:
|
|
65
|
+
print(f" {line}")
|
|
66
|
+
if len(error_output.strip().split('\n')) > 20:
|
|
67
|
+
print(f" ... (truncated, {len(error_output.strip().split(chr(10)))} total lines)")
|
|
68
|
+
return False, error_output
|
|
69
|
+
|
|
70
|
+
except FileNotFoundError:
|
|
71
|
+
print(f"{Colors.YELLOW}⚠️ {description}: SKIPPED (command not found){Colors.RESET}")
|
|
72
|
+
return True, "" # Don't fail on missing commands
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print(f"{Colors.RED}❌ {description}: ERROR - {str(e)}{Colors.RESET}")
|
|
75
|
+
return False, str(e)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def main():
|
|
79
|
+
"""Run all verification checks."""
|
|
80
|
+
quick_mode = '--quick' in sys.argv
|
|
81
|
+
strict_mode = '--strict' in sys.argv
|
|
82
|
+
|
|
83
|
+
print(f"\n{Colors.BOLD}{'='*50}")
|
|
84
|
+
print(f"🔍 VibeCode Verification Report")
|
|
85
|
+
print(f"{'='*50}{Colors.RESET}")
|
|
86
|
+
|
|
87
|
+
# Check we're in a Node.js project
|
|
88
|
+
if not Path('package.json').exists():
|
|
89
|
+
print(f"{Colors.RED}❌ No package.json found. Are you in the project root?{Colors.RESET}")
|
|
90
|
+
sys.exit(1)
|
|
91
|
+
|
|
92
|
+
pm = detect_package_manager()
|
|
93
|
+
print(f"\n📦 Package Manager: {Colors.BLUE}{pm}{Colors.RESET}")
|
|
94
|
+
|
|
95
|
+
results = []
|
|
96
|
+
|
|
97
|
+
# 1. TypeScript Check
|
|
98
|
+
tsc_passed, tsc_output = run_command(
|
|
99
|
+
['npx', 'tsc', '--noEmit'],
|
|
100
|
+
"TypeScript Check"
|
|
101
|
+
)
|
|
102
|
+
results.append(('TypeScript', tsc_passed))
|
|
103
|
+
|
|
104
|
+
# 2. Lint Check
|
|
105
|
+
lint_cmd = [pm, 'run', 'lint']
|
|
106
|
+
if pm == 'npm':
|
|
107
|
+
lint_cmd = ['npm', 'run', 'lint', '--', '--quiet'] if not strict_mode else ['npm', 'run', 'lint']
|
|
108
|
+
|
|
109
|
+
lint_passed, lint_output = run_command(
|
|
110
|
+
lint_cmd,
|
|
111
|
+
"Lint Check"
|
|
112
|
+
)
|
|
113
|
+
results.append(('Lint', lint_passed))
|
|
114
|
+
|
|
115
|
+
# 3. Build Check (skip in quick mode)
|
|
116
|
+
if not quick_mode:
|
|
117
|
+
build_cmd = [pm, 'run', 'build']
|
|
118
|
+
if pm == 'npm':
|
|
119
|
+
build_cmd = ['npm', 'run', 'build']
|
|
120
|
+
|
|
121
|
+
build_passed, build_output = run_command(
|
|
122
|
+
build_cmd,
|
|
123
|
+
"Build Check"
|
|
124
|
+
)
|
|
125
|
+
results.append(('Build', build_passed))
|
|
126
|
+
|
|
127
|
+
# Summary
|
|
128
|
+
print(f"\n{Colors.BOLD}{'='*50}")
|
|
129
|
+
print(f"📊 Summary")
|
|
130
|
+
print(f"{'='*50}{Colors.RESET}")
|
|
131
|
+
|
|
132
|
+
all_passed = True
|
|
133
|
+
for name, passed in results:
|
|
134
|
+
status = f"{Colors.GREEN}PASS{Colors.RESET}" if passed else f"{Colors.RED}FAIL{Colors.RESET}"
|
|
135
|
+
print(f" {name}: {status}")
|
|
136
|
+
if not passed:
|
|
137
|
+
all_passed = False
|
|
138
|
+
|
|
139
|
+
print(f"{'='*50}")
|
|
140
|
+
|
|
141
|
+
if all_passed:
|
|
142
|
+
print(f"\n{Colors.GREEN}{Colors.BOLD}✨ All checks passed! Ready for handoff.{Colors.RESET}\n")
|
|
143
|
+
sys.exit(0)
|
|
144
|
+
else:
|
|
145
|
+
print(f"\n{Colors.RED}{Colors.BOLD}🛑 Verification failed. Fix errors before proceeding.{Colors.RESET}\n")
|
|
146
|
+
sys.exit(1)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
if __name__ == '__main__':
|
|
150
|
+
main()
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# Coding Guidelines
|
|
2
|
+
|
|
3
|
+
> **This document is the LAW.** Follow it without exception.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🛑 The Verification Protocol (MANDATORY)
|
|
8
|
+
|
|
9
|
+
### After EVERY TypeScript/TSX File Edit
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx tsc --noEmit
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**If this command fails:**
|
|
16
|
+
1. **STOP.** Do not touch another file.
|
|
17
|
+
2. Read the error message carefully.
|
|
18
|
+
3. Fix the type error.
|
|
19
|
+
4. Re-run the command.
|
|
20
|
+
5. Only proceed when it passes.
|
|
21
|
+
|
|
22
|
+
### Before Any Handoff or "Done" Claim
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python scripts/vibe-verify.py
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
All checks must pass. No exceptions.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## The Blueprint & Build Protocol
|
|
33
|
+
|
|
34
|
+
### Phase 1: Blueprint (Before Writing Code)
|
|
35
|
+
|
|
36
|
+
Before implementing any non-trivial feature:
|
|
37
|
+
|
|
38
|
+
1. **Context Analysis**
|
|
39
|
+
- Check `docs/features/` for existing implementations
|
|
40
|
+
- Check if existing components/hooks can be reused
|
|
41
|
+
- Identify potential impact on other features
|
|
42
|
+
|
|
43
|
+
2. **Create the Plan**
|
|
44
|
+
- Create `docs/features/FeatureName.md` with:
|
|
45
|
+
- High-Level Goal
|
|
46
|
+
- Component Breakdown (label Server/Client)
|
|
47
|
+
- Logic & Data Breakdown
|
|
48
|
+
- Step-by-Step Implementation Plan
|
|
49
|
+
|
|
50
|
+
3. **Get Approval**
|
|
51
|
+
- Present the plan to the user
|
|
52
|
+
- Wait for explicit approval before coding
|
|
53
|
+
|
|
54
|
+
### Phase 2: Build (Implementation)
|
|
55
|
+
|
|
56
|
+
1. **Announce**: "Implementing FR-XXX: [Title]"
|
|
57
|
+
2. **Reference**: Open the corresponding issue in `docs/issues/`
|
|
58
|
+
3. **Implement**: One file at a time
|
|
59
|
+
4. **Verify**: `npx tsc --noEmit` after each file
|
|
60
|
+
5. **Mark Complete**: Check off acceptance criteria as you complete them
|
|
61
|
+
6. **Update Issue**: Edit the issue file to reflect progress
|
|
62
|
+
|
|
63
|
+
### Phase 3: Finalization
|
|
64
|
+
|
|
65
|
+
1. Run `python scripts/vibe-verify.py`
|
|
66
|
+
2. Update all acceptance criteria checkboxes
|
|
67
|
+
3. Generate handoff summary
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Full-Stack Type Safety
|
|
72
|
+
|
|
73
|
+
### The Golden Rule
|
|
74
|
+
|
|
75
|
+
> If you change the backend, the frontend MUST type-check.
|
|
76
|
+
> If type-check fails, THE CHANGE BROKE SOMETHING.
|
|
77
|
+
> Fix it before moving on.
|
|
78
|
+
|
|
79
|
+
### How It Works
|
|
80
|
+
|
|
81
|
+
1. **Prisma/DB Changes** → Regenerate client → Type-check
|
|
82
|
+
2. **API Route Changes** → Frontend consumers must type-check
|
|
83
|
+
3. **Server Component Changes** → Props must align with parent
|
|
84
|
+
|
|
85
|
+
### Tools That Help
|
|
86
|
+
|
|
87
|
+
- **tRPC**: Frontend imports backend types directly
|
|
88
|
+
- **Server Components**: Backend code returns UI with type safety
|
|
89
|
+
- **Zod**: Runtime validation that generates types
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Next.js App Router Architecture
|
|
94
|
+
|
|
95
|
+
### Server vs Client Components
|
|
96
|
+
|
|
97
|
+
| Use Server Components For | Use Client Components For |
|
|
98
|
+
|---------------------------|---------------------------|
|
|
99
|
+
| Data fetching | Event handlers (onClick) |
|
|
100
|
+
| Database access | useState, useEffect |
|
|
101
|
+
| Rendering static content | Browser APIs (localStorage) |
|
|
102
|
+
| Accessing backend services | Interactivity |
|
|
103
|
+
|
|
104
|
+
**Default**: Server Component (no directive)
|
|
105
|
+
**Client**: Add `'use client'` at top of file
|
|
106
|
+
|
|
107
|
+
### Data Fetching
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// ✅ GOOD: Fetch in Server Component
|
|
111
|
+
async function ProductList() {
|
|
112
|
+
const products = await db.product.findMany();
|
|
113
|
+
return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ❌ BAD: useEffect fetching
|
|
117
|
+
function ProductList() {
|
|
118
|
+
const [products, setProducts] = useState([]);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
fetch('/api/products').then(...); // Avoid this
|
|
121
|
+
}, []);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Route Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
app/
|
|
129
|
+
├── page.tsx # Home page
|
|
130
|
+
├── layout.tsx # Root layout
|
|
131
|
+
├── api/
|
|
132
|
+
│ └── [resource]/
|
|
133
|
+
│ └── route.ts # API endpoints
|
|
134
|
+
├── (auth)/ # Route group
|
|
135
|
+
│ ├── login/page.tsx
|
|
136
|
+
│ └── register/page.tsx
|
|
137
|
+
└── dashboard/
|
|
138
|
+
├── page.tsx
|
|
139
|
+
└── settings/page.tsx
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## File Structure (Feature-Sliced)
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
src/
|
|
148
|
+
├── app/ # Next.js App Router
|
|
149
|
+
├── features/ # Business domains
|
|
150
|
+
│ └── [FeatureName]/
|
|
151
|
+
│ ├── components/ # Feature UI
|
|
152
|
+
│ ├── hooks/ # Feature hooks
|
|
153
|
+
│ ├── [name].service.ts
|
|
154
|
+
│ └── types.ts
|
|
155
|
+
├── components/
|
|
156
|
+
│ ├── ui/ # Reusable: Button, Card, Input
|
|
157
|
+
│ └── layout/ # Navbar, Sidebar, Footer
|
|
158
|
+
├── lib/ # Utilities
|
|
159
|
+
│ ├── db.ts # Prisma client
|
|
160
|
+
│ └── utils.ts
|
|
161
|
+
└── scripts/
|
|
162
|
+
└── vibe-verify.py
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Component Rules
|
|
168
|
+
|
|
169
|
+
### The 200-Line Rule
|
|
170
|
+
|
|
171
|
+
A component file exceeding **200 lines** is a code smell.
|
|
172
|
+
|
|
173
|
+
**When you hit the limit:**
|
|
174
|
+
1. Extract logic into a custom hook
|
|
175
|
+
2. Extract sub-components into separate files
|
|
176
|
+
3. Move business logic to a service file
|
|
177
|
+
|
|
178
|
+
### Props & Types
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
// ✅ GOOD: Interface for props
|
|
182
|
+
interface UserCardProps {
|
|
183
|
+
user: User;
|
|
184
|
+
onEdit?: (id: string) => void;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function UserCard({ user, onEdit }: UserCardProps) {
|
|
188
|
+
// ...
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ❌ BAD: No types
|
|
192
|
+
function UserCard(props) {
|
|
193
|
+
const user = props.user; // No type safety
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Custom Hooks
|
|
198
|
+
|
|
199
|
+
Extract stateful logic into hooks:
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
// hooks/useUser.ts
|
|
203
|
+
export function useUser(userId: string) {
|
|
204
|
+
const [user, setUser] = useState<User | null>(null);
|
|
205
|
+
const [loading, setLoading] = useState(true);
|
|
206
|
+
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
fetchUser(userId).then(setUser).finally(() => setLoading(false));
|
|
209
|
+
}, [userId]);
|
|
210
|
+
|
|
211
|
+
return { user, loading };
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Styling (Tailwind CSS v4)
|
|
218
|
+
|
|
219
|
+
### Setup
|
|
220
|
+
|
|
221
|
+
```css
|
|
222
|
+
/* globals.css */
|
|
223
|
+
@import "tailwindcss";
|
|
224
|
+
|
|
225
|
+
@theme {
|
|
226
|
+
--color-background: #ffffff;
|
|
227
|
+
--color-foreground: #0b1221;
|
|
228
|
+
--color-border: #e5e7eb;
|
|
229
|
+
--color-ring: #3b82f6;
|
|
230
|
+
|
|
231
|
+
/* Brand colors */
|
|
232
|
+
--color-primary: #2563eb;
|
|
233
|
+
--color-secondary: #7c3aed;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@theme .dark {
|
|
237
|
+
--color-background: #0b1221;
|
|
238
|
+
--color-foreground: #f3f4f6;
|
|
239
|
+
--color-border: #374151;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@layer base {
|
|
243
|
+
* { @apply border-border; }
|
|
244
|
+
body { @apply bg-background text-foreground; }
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Rules
|
|
249
|
+
|
|
250
|
+
1. **Utility-first**: Apply Tailwind classes in JSX
|
|
251
|
+
2. **No custom CSS**: Unless absolutely necessary
|
|
252
|
+
3. **Dark mode**: Use `dark:` prefix, controlled by `.dark` class
|
|
253
|
+
4. **Tokens**: Define in `@theme`, not `tailwind.config`
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Backend / API Design
|
|
258
|
+
|
|
259
|
+
### Service Layer Pattern
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Route Handler (route.ts) → Controller (parse, respond)
|
|
263
|
+
↓
|
|
264
|
+
Service (*.service.ts) → Business logic
|
|
265
|
+
↓
|
|
266
|
+
Database (Prisma) → Data access
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Example
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
// app/api/users/route.ts (Controller)
|
|
273
|
+
export async function POST(request: Request) {
|
|
274
|
+
const body = await request.json();
|
|
275
|
+
const validated = createUserSchema.parse(body); // Zod validation
|
|
276
|
+
const user = await userService.createUser(validated);
|
|
277
|
+
return NextResponse.json({ data: user }, { status: 201 });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// features/users/user.service.ts (Service)
|
|
281
|
+
export const userService = {
|
|
282
|
+
async createUser(data: CreateUserInput) {
|
|
283
|
+
return db.user.create({ data });
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Validation with Zod
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
import { z } from 'zod';
|
|
292
|
+
|
|
293
|
+
export const createUserSchema = z.object({
|
|
294
|
+
email: z.string().email(),
|
|
295
|
+
name: z.string().min(2),
|
|
296
|
+
role: z.enum(['USER', 'ADMIN']).default('USER'),
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
export type CreateUserInput = z.infer<typeof createUserSchema>;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**All inputs must be validated. No exceptions.**
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Recovery Protocol
|
|
307
|
+
|
|
308
|
+
If you break something:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
# See what changed
|
|
312
|
+
git status
|
|
313
|
+
git diff
|
|
314
|
+
|
|
315
|
+
# Revert a specific file
|
|
316
|
+
git checkout -- path/to/file.tsx
|
|
317
|
+
|
|
318
|
+
# Save changes and revert
|
|
319
|
+
git stash
|
|
320
|
+
|
|
321
|
+
# Restore saved changes
|
|
322
|
+
git stash pop
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Quick Reference
|
|
328
|
+
|
|
329
|
+
| Command | When to Run |
|
|
330
|
+
|---------|-------------|
|
|
331
|
+
| `npx tsc --noEmit` | After every TS/TSX edit |
|
|
332
|
+
| `python scripts/vibe-verify.py` | Before handoff |
|
|
333
|
+
| `python scripts/vibe-verify.py --quick` | Quick check (no build) |
|
|
334
|
+
| `npm run lint` | Check code style |
|
|
335
|
+
| `npm run build` | Full production build |
|
|
336
|
+
| `npx prisma generate` | After schema changes |
|
|
337
|
+
| `npx prisma migrate dev` | Apply DB migrations |
|