start-vibing-stacks 2.1.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/detector.js +4 -6
- package/dist/index.js +63 -2
- package/dist/scanner.d.ts +12 -0
- package/dist/scanner.js +480 -0
- package/dist/setup.js +29 -0
- package/dist/types.d.ts +20 -0
- package/dist/ui.js +1 -1
- package/package.json +1 -1
- package/stacks/_shared/hooks/user-prompt-submit.ts +26 -2
- package/stacks/frontend/react-inertia/skills/inertia-react/SKILL.md +342 -0
- package/stacks/frontend/react-inertia/skills/react-standards/SKILL.md +267 -0
- package/stacks/php/skills/api-security/SKILL.md +431 -0
- package/stacks/php/skills/laravel-octane/SKILL.md +155 -53
- package/stacks/php/skills/laravel-patterns/SKILL.md +244 -39
- package/stacks/php/skills/php-patterns/SKILL.md +113 -53
- package/stacks/php/skills/security-scan-php/SKILL.md +161 -43
- package/stacks/php/stack.json +19 -6
- package/templates/CLAUDE-php.md +108 -29
package/templates/CLAUDE-php.md
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
|-----------|------------|
|
|
17
17
|
| Language | PHP >= 8.3 |
|
|
18
18
|
| Framework | {{FRAMEWORK}} |
|
|
19
|
+
| Server | Octane + RoadRunner |
|
|
20
|
+
| Frontend | ReactJS 19+ / Inertia.js / TailwindCSS 4+ |
|
|
19
21
|
| Database | {{DATABASE}} |
|
|
20
22
|
| Package Manager | Composer |
|
|
21
23
|
| Static Analysis | PHPStan (level 6) |
|
|
@@ -26,41 +28,104 @@
|
|
|
26
28
|
|
|
27
29
|
```
|
|
28
30
|
project/
|
|
29
|
-
├──
|
|
30
|
-
├──
|
|
31
|
-
├──
|
|
31
|
+
├── app/
|
|
32
|
+
│ ├── Console/ # Artisan commands
|
|
33
|
+
│ ├── Exceptions/ # Exception handlers
|
|
34
|
+
│ ├── Http/
|
|
35
|
+
│ │ ├── Controllers/ # Thin controllers (Inertia::render + Services)
|
|
36
|
+
│ │ ├── Middleware/ # HTTP middleware (HandleInertiaRequests)
|
|
37
|
+
│ │ └── Requests/ # Form request validation
|
|
38
|
+
│ ├── Models/ # Eloquent models (UUIDs, $fillable)
|
|
39
|
+
│ ├── Providers/ # Service providers
|
|
40
|
+
│ ├── Services/ # Business logic (single responsibility)
|
|
41
|
+
│ │ └── Helpers/ # Extracted logic for complex services
|
|
42
|
+
│ ├── Support/ # Helper classes (InertiaShare)
|
|
43
|
+
│ ├── Traits/ # Shared traits (Loggable, FormatsDatesForApi)
|
|
44
|
+
│ └── Jobs/ # Queue jobs (idempotent, chunked)
|
|
45
|
+
├── bootstrap/ # Framework bootstrap
|
|
46
|
+
├── config/ # Configuration (immutable at runtime)
|
|
47
|
+
│ └── translations_inertia.php # Per-page translation mapping
|
|
48
|
+
├── database/
|
|
49
|
+
│ ├── factories/ # Model factories
|
|
50
|
+
│ ├── migrations/ # Incremental migrations ONLY
|
|
51
|
+
│ └── seeders/ # Database seeders
|
|
52
|
+
├── lang/
|
|
53
|
+
│ ├── en/ # English translations
|
|
54
|
+
│ └── pt/ # Portuguese translations
|
|
55
|
+
├── public/ # Web root (index.php)
|
|
56
|
+
├── resources/
|
|
57
|
+
│ ├── views/ # Blade root template (app.blade.php)
|
|
58
|
+
│ ├── css/ # Stylesheets (TailwindCSS)
|
|
59
|
+
│ └── js/
|
|
60
|
+
│ ├── Pages/ # React page components (mapped by Inertia)
|
|
61
|
+
│ ├── Components/ # Reusable React components
|
|
62
|
+
│ ├── Layouts/ # Page layouts (Authenticated, Guest)
|
|
63
|
+
│ ├── Icons/ # SVG icons (import with ?react)
|
|
64
|
+
│ └── Utils/
|
|
65
|
+
│ └── translate.js # __() translation helper
|
|
66
|
+
├── routes/
|
|
67
|
+
│ ├── api.php # API routes (RESTful + action endpoints)
|
|
68
|
+
│ └── web.php # Web routes (Inertia pages)
|
|
69
|
+
├── storage/ # Logs, cache, uploads
|
|
32
70
|
├── tests/
|
|
33
|
-
│ ├── Unit/
|
|
34
|
-
│ └── Feature/
|
|
35
|
-
├──
|
|
36
|
-
├──
|
|
37
|
-
├──
|
|
38
|
-
├──
|
|
39
|
-
|
|
71
|
+
│ ├── Unit/ # PHPUnit unit tests
|
|
72
|
+
│ └── Feature/ # Feature/integration tests
|
|
73
|
+
├── .claude/ # AI agent configuration
|
|
74
|
+
├── artisan # CLI entry point
|
|
75
|
+
├── rr.yaml # RoadRunner config (Octane)
|
|
76
|
+
├── composer.json # Dependencies
|
|
77
|
+
├── phpstan.neon # Static analysis config
|
|
78
|
+
└── CLAUDE.md # This file
|
|
40
79
|
```
|
|
41
80
|
|
|
42
81
|
## Critical Rules
|
|
43
82
|
|
|
44
|
-
- **PHP >= 8.3** —
|
|
83
|
+
- **PHP >= 8.3** — readonly, enums, typed constants, match expressions
|
|
45
84
|
- **`declare(strict_types=1)`** in EVERY PHP file
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
85
|
+
- **Octane-safe code** — no static state, no globals, no `die()`/`exit()`
|
|
86
|
+
- **Dependency Injection** — use DI over `app()` or `resolve()`
|
|
87
|
+
- **Thin controllers** — delegate business logic to Service classes
|
|
88
|
+
- **Form Requests** — validate input in dedicated request classes
|
|
89
|
+
- **Type everything** — properties, params, returns (no `mixed` without justification)
|
|
90
|
+
- **UUIDs** — all new models use `HasUuids` trait as primary key
|
|
91
|
+
- **Mass assignment** — always define `$fillable` on models
|
|
92
|
+
- **Auditing** — critical models use `Loggable` trait
|
|
93
|
+
- **Eloquent only** — no raw SQL unless strictly justified with parameter binding
|
|
94
|
+
- **Config immutable** — never use `config()` to SET values at runtime
|
|
95
|
+
- **Request object** — use `$request->input()`, never `$_GET`/`$_POST`/`$_SESSION`
|
|
51
96
|
|
|
52
97
|
## FORBIDDEN
|
|
53
98
|
|
|
99
|
+
### Backend
|
|
100
|
+
|
|
101
|
+
| Action | Reason |
|
|
102
|
+
|--------|--------|
|
|
103
|
+
| Dynamic code execution functions | Remote code execution risk |
|
|
104
|
+
| `DB::raw()` with user input | SQL injection risk |
|
|
105
|
+
| `{!! $userInput !!}` | XSS — use `{{ }}` instead |
|
|
106
|
+
| Mass assignment without `$fillable` | Uncontrolled field injection |
|
|
107
|
+
| Business logic in controllers | Move to Service classes |
|
|
108
|
+
| `env()` outside config files | Returns null when config is cached |
|
|
109
|
+
| `static` properties on services | Memory leaks in Octane workers |
|
|
110
|
+
| Global variables / superglobals | Stale state in Octane |
|
|
111
|
+
| `die()` / `exit()` | Kills the Octane worker process |
|
|
112
|
+
| `config(['key' => 'val'])` at runtime | Affects all concurrent requests |
|
|
113
|
+
| `migrate:fresh` / `db:wipe` / `db:reset` | Destroys production data |
|
|
114
|
+
| `app()` / `resolve()` in constructors | Use constructor DI instead |
|
|
115
|
+
| `Inertia::render()` after POST/PUT/DELETE | Use `redirect()->route()` instead |
|
|
116
|
+
|
|
117
|
+
### Frontend (React)
|
|
118
|
+
|
|
54
119
|
| Action | Reason |
|
|
55
120
|
|--------|--------|
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
|
|
|
59
|
-
| `
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
121
|
+
| `__()` inside JSX / render | Hook violation — define as CONST before hooks |
|
|
122
|
+
| `fetch()` / `axios` for page data | Bypasses Inertia — use props from controller |
|
|
123
|
+
| `<a href>` for internal links | Full page reload — use `<Link>` |
|
|
124
|
+
| `window.location` for navigation | Full reload — use `router.visit()` |
|
|
125
|
+
| Inline SVGs in JSX | Bloats components — use SVG files with `?react` |
|
|
126
|
+
| Raw `console.log` | Uncontrolled — use debug constant pattern |
|
|
127
|
+
| Inline Tailwind class soup | Unreadable — use STYLES const object |
|
|
128
|
+
| `axios.post()` for forms | No CSRF/errors — use `useForm().post()` |
|
|
64
129
|
|
|
65
130
|
## Quality Gates
|
|
66
131
|
|
|
@@ -68,21 +133,35 @@ project/
|
|
|
68
133
|
vendor/bin/phpstan analyse --level=6 # Static analysis
|
|
69
134
|
vendor/bin/phpunit # Tests
|
|
70
135
|
vendor/bin/php-cs-fixer fix --dry-run # Code style
|
|
136
|
+
php artisan test # Laravel test runner
|
|
71
137
|
```
|
|
72
138
|
|
|
73
|
-
##
|
|
139
|
+
## Database
|
|
74
140
|
|
|
75
|
-
|
|
141
|
+
Use Eloquent ORM and Query Builder. Raw queries only when strictly necessary with parameter binding:
|
|
76
142
|
|
|
77
143
|
```php
|
|
78
|
-
|
|
79
|
-
$
|
|
144
|
+
// Eloquent (preferred)
|
|
145
|
+
$user = User::findOrFail($id);
|
|
146
|
+
|
|
147
|
+
// Query Builder
|
|
148
|
+
$users = DB::table('users')->where('active', true)->get();
|
|
149
|
+
|
|
150
|
+
// Raw query (last resort — always bind parameters)
|
|
151
|
+
$results = DB::select('SELECT * FROM users WHERE id = ?', [$id]);
|
|
80
152
|
```
|
|
81
153
|
|
|
154
|
+
## Migration Safety
|
|
155
|
+
|
|
156
|
+
- **ALWAYS** use incremental migrations (`make:migration`)
|
|
157
|
+
- **NEVER** execute `migrate:fresh`, `migrate:refresh`, `db:wipe`, `db:reset`
|
|
158
|
+
- If a migration fails, fix the file or create a new one
|
|
159
|
+
- Assume all environments contain critical data
|
|
160
|
+
|
|
82
161
|
## Workflow
|
|
83
162
|
|
|
84
163
|
1. Create feature branch
|
|
85
|
-
2. Implement with types, strict mode
|
|
164
|
+
2. Implement with types, strict mode, Octane-safe patterns
|
|
86
165
|
3. Run PHPStan + PHPUnit
|
|
87
166
|
4. Update domains & CLAUDE.md
|
|
88
167
|
5. Commit → merge to main
|