start-vibing-stacks 2.3.0 → 2.4.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/README.md +142 -58
- package/dist/detector.js +19 -5
- package/dist/index.js +15 -3
- package/dist/scanner.js +23 -2
- package/dist/setup.js +17 -1
- package/dist/types.d.ts +4 -0
- package/dist/ui.js +6 -5
- package/package.json +1 -1
- package/stacks/_shared/config/security-rules.json +27 -5
- package/stacks/frontend/react/skills/preline-ui/SKILL.md +31 -35
- package/stacks/frontend/react/skills/react-standards/SKILL.md +20 -20
- package/stacks/frontend/react/skills/react-ui-patterns/SKILL.md +78 -42
- package/stacks/frontend/react/skills/tailwind-patterns/SKILL.md +1 -1
- package/stacks/frontend/react/skills/zod-validation/SKILL.md +84 -18
- package/stacks/nodejs/skills/nextjs-app-router/SKILL.md +101 -0
- package/stacks/nodejs/stack.json +43 -121
- package/templates/CLAUDE-nodejs.md +323 -0
- package/templates/CLAUDE-php.md +131 -10
package/templates/CLAUDE-php.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# {{PROJECT_NAME}}
|
|
2
2
|
|
|
3
|
+
> **CHARACTER LIMIT**: Max 40,000 chars. Validate with `wc -m CLAUDE.md` before commit.
|
|
4
|
+
|
|
3
5
|
## Last Change
|
|
4
6
|
|
|
5
7
|
**Branch:** main
|
|
@@ -78,6 +80,24 @@ project/
|
|
|
78
80
|
└── CLAUDE.md # This file
|
|
79
81
|
```
|
|
80
82
|
|
|
83
|
+
## CLAUDE.md Update Rules
|
|
84
|
+
|
|
85
|
+
> After ANY implementation, update this file to reflect the current state.
|
|
86
|
+
|
|
87
|
+
| Change Type | Sections to Update |
|
|
88
|
+
|-------------|-------------------|
|
|
89
|
+
| Any file change | Last Change (branch, date, summary) |
|
|
90
|
+
| API/routes | Critical Rules, Architecture |
|
|
91
|
+
| New feature | 30s Overview, Architecture |
|
|
92
|
+
| New gotcha | FORBIDDEN or NRY |
|
|
93
|
+
| New dependency | Stack |
|
|
94
|
+
| Workflow change | Workflow section |
|
|
95
|
+
|
|
96
|
+
1. **Last Change** documents WHAT was done
|
|
97
|
+
2. **Other sections** document HOW things work NOW
|
|
98
|
+
3. **Both must be current** — updating only Last Change is insufficient
|
|
99
|
+
4. Keep only the LATEST Last Change entry (no stacking)
|
|
100
|
+
|
|
81
101
|
## Critical Rules
|
|
82
102
|
|
|
83
103
|
- **PHP >= 8.3** — readonly, enums, typed constants, match expressions
|
|
@@ -94,18 +114,80 @@ project/
|
|
|
94
114
|
- **Config immutable** — never use `config()` to SET values at runtime
|
|
95
115
|
- **Request object** — use `$request->input()`, never `$_GET`/`$_POST`/`$_SESSION`
|
|
96
116
|
|
|
117
|
+
### Environment Variables & Secrets (MANDATORY)
|
|
118
|
+
|
|
119
|
+
> **NEVER use `env()` outside config files.** After `config:cache`, `env()` returns null everywhere except config files.
|
|
120
|
+
|
|
121
|
+
| Location | Access | Safe for |
|
|
122
|
+
|----------|--------|----------|
|
|
123
|
+
| `.env` | `env()` inside `config/*.php` only | API keys, DB credentials, secrets |
|
|
124
|
+
| `config/*.php` | `config('services.stripe.key')` | Application code access |
|
|
125
|
+
| Frontend (Inertia) | `InertiaShare` or controller props | Public data ONLY |
|
|
126
|
+
|
|
127
|
+
```php
|
|
128
|
+
// config/services.php — Bridge between .env and application
|
|
129
|
+
return [
|
|
130
|
+
'openai' => [
|
|
131
|
+
'key' => env('OPENAI_KEY'),
|
|
132
|
+
],
|
|
133
|
+
'stripe' => [
|
|
134
|
+
'key' => env('STRIPE_KEY'), // Publishable (sent to frontend)
|
|
135
|
+
'secret' => env('STRIPE_SECRET'), // NEVER send to frontend
|
|
136
|
+
'webhook_secret' => env('STRIPE_WEBHOOK_SECRET'),
|
|
137
|
+
],
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
// In code: ALWAYS use config()
|
|
141
|
+
$apiKey = config('services.openai.key');
|
|
142
|
+
|
|
143
|
+
// FORBIDDEN:
|
|
144
|
+
$apiKey = env('OPENAI_KEY'); // Returns null when config is cached!
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Frontend Secret Isolation (MANDATORY)
|
|
148
|
+
|
|
149
|
+
> **NEVER send API keys, secrets, or tokens to the frontend via Inertia props or JavaScript.**
|
|
150
|
+
|
|
151
|
+
```php
|
|
152
|
+
// WRONG — secret exposed in page source / DevTools
|
|
153
|
+
return Inertia::render('Dashboard', [
|
|
154
|
+
'stripeSecret' => config('services.stripe.secret'),
|
|
155
|
+
'openaiKey' => config('services.openai.key'),
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
// CORRECT — only public/publishable data to frontend
|
|
159
|
+
return Inertia::render('Dashboard', [
|
|
160
|
+
'stripePublicKey' => config('services.stripe.key'), // pk_ only
|
|
161
|
+
]);
|
|
162
|
+
|
|
163
|
+
// For operations requiring secrets: use backend API routes
|
|
164
|
+
// Frontend calls /api/payment → backend uses secret server-side
|
|
165
|
+
```
|
|
166
|
+
|
|
97
167
|
## FORBIDDEN
|
|
98
168
|
|
|
99
|
-
###
|
|
169
|
+
### Security (CRITICAL)
|
|
100
170
|
|
|
101
171
|
| Action | Reason |
|
|
102
172
|
|--------|--------|
|
|
173
|
+
| `env()` outside config files | Returns null when config is cached — use `config()` |
|
|
174
|
+
| Send API keys/secrets via Inertia props | Exposed in page source — keep secrets server-side |
|
|
175
|
+
| `$guarded = []` on models | Allows mass assignment of any field — use `$fillable` |
|
|
176
|
+
| `DB::raw()` with user input | SQL injection — use Eloquent or parameterized queries |
|
|
177
|
+
| `{!! $userInput !!}` | XSS — use `{{ }}` (auto-escaped) |
|
|
103
178
|
| Dynamic code execution functions | Remote code execution risk |
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
|
|
|
179
|
+
| `md5()` / `sha1()` for passwords | Weak hashing — use `Hash::make()` |
|
|
180
|
+
| `unserialize()` on user data | Object injection — use JSON with model casts |
|
|
181
|
+
| CORS `allowed_origins: ['*']` | Open API — restrict to your domain |
|
|
182
|
+
| `createToken('x', ['*'])` | Over-privileged — use specific abilities |
|
|
183
|
+
| Trust `X-Forwarded-For` directly | Spoofable — use trusted proxies config |
|
|
184
|
+
| `$_GET` / `$_POST` / `$_SESSION` | Stale in Octane — use `$request->input()` |
|
|
185
|
+
|
|
186
|
+
### Backend
|
|
187
|
+
|
|
188
|
+
| Action | Reason |
|
|
189
|
+
|--------|--------|
|
|
107
190
|
| Business logic in controllers | Move to Service classes |
|
|
108
|
-
| `env()` outside config files | Returns null when config is cached |
|
|
109
191
|
| `static` properties on services | Memory leaks in Octane workers |
|
|
110
192
|
| Global variables / superglobals | Stale state in Octane |
|
|
111
193
|
| `die()` / `exit()` | Kills the Octane worker process |
|
|
@@ -113,11 +195,13 @@ project/
|
|
|
113
195
|
| `migrate:fresh` / `db:wipe` / `db:reset` | Destroys production data |
|
|
114
196
|
| `app()` / `resolve()` in constructors | Use constructor DI instead |
|
|
115
197
|
| `Inertia::render()` after POST/PUT/DELETE | Use `redirect()->route()` instead |
|
|
198
|
+
| `dd()` / `dump()` in production code | Use structured `Log::info()` |
|
|
116
199
|
|
|
117
200
|
### Frontend (React)
|
|
118
201
|
|
|
119
202
|
| Action | Reason |
|
|
120
203
|
|--------|--------|
|
|
204
|
+
| Call external APIs with secrets from JS | Exposes tokens — route through Laravel API |
|
|
121
205
|
| `__()` inside JSX / render | Hook violation — define as CONST before hooks |
|
|
122
206
|
| `fetch()` / `axios` for page data | Bypasses Inertia — use props from controller |
|
|
123
207
|
| `<a href>` for internal links | Full page reload — use `<Link>` |
|
|
@@ -160,8 +244,45 @@ $results = DB::select('SELECT * FROM users WHERE id = ?', [$id]);
|
|
|
160
244
|
|
|
161
245
|
## Workflow
|
|
162
246
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
247
|
+
```
|
|
248
|
+
0. TODO LIST → Create detailed todo list from prompt
|
|
249
|
+
1. BRANCH → Create feature/ | fix/ | refactor/ | test/
|
|
250
|
+
2. RESEARCH → Run research-web agent for NEW features
|
|
251
|
+
3. IMPLEMENT → Types, strict mode, Octane-safe, DI
|
|
252
|
+
4. TEST → Run PHPStan + PHPUnit
|
|
253
|
+
5. DOCUMENT → Run documenter agent for modified files
|
|
254
|
+
6. UPDATE → Update THIS FILE (CLAUDE.md) with changes
|
|
255
|
+
7. QUALITY → PHPStan + PHPUnit + PHP-CS-Fixer
|
|
256
|
+
8. COMMIT → Conventional commits, merge to main
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Domain Documentation
|
|
260
|
+
|
|
261
|
+
> Domain docs prevent Claude from re-exploring the codebase every session.
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
.claude/skills/codebase-knowledge/domains/
|
|
265
|
+
├── authentication.md
|
|
266
|
+
├── api.md
|
|
267
|
+
├── database.md
|
|
268
|
+
├── ui-components.md
|
|
269
|
+
└── [domain-name].md
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Each domain file tracks: Files, Connections, Recent Commits, Attention Points, Problems & Solutions.
|
|
273
|
+
|
|
274
|
+
## Configuration
|
|
275
|
+
|
|
276
|
+
Project settings in `.claude/config/` (generated by start-vibing-stacks):
|
|
277
|
+
|
|
278
|
+
- `active-project.json` — Stack, framework, database, skills
|
|
279
|
+
- `domain-mapping.json` — File-to-domain mapping
|
|
280
|
+
- `quality-gates.json` — Quality check commands
|
|
281
|
+
- `testing-config.json` — Test framework config
|
|
282
|
+
- `security-rules.json` — Security audit rules
|
|
283
|
+
- `standards-review.json` — Imported project standards
|
|
284
|
+
|
|
285
|
+
## Setup by start-vibing-stacks
|
|
286
|
+
|
|
287
|
+
This project was set up with `npx start-vibing-stacks`.
|
|
288
|
+
For updates: `npx start-vibing-stacks --force`
|