nextjs-hackathon-stack 0.1.38 → 0.1.40
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/dist/index.js +10 -0
- package/package.json +1 -1
- package/template/.cursor/agents/frontend.md +19 -3
- package/template/.cursor/agents/technical-lead.md +2 -8
- package/template/.cursor/mcp.json +4 -0
- package/template/.cursor/rules/coding-standards.mdc +20 -1
- package/template/.cursor/rules/components.mdc +8 -6
- package/template/.cursor/rules/data-fetching.mdc +2 -1
- package/template/.cursor/rules/forms.mdc +3 -2
- package/template/.cursor/rules/migrations.mdc +1 -0
- package/template/.cursor/rules/nextjs.mdc +1 -0
- package/template/.cursor/rules/security.mdc +1 -0
- package/template/.cursor/rules/supabase.mdc +2 -1
- package/template/.cursor/rules/testing.mdc +2 -1
- package/template/.cursor/skills/create-api-route/SKILL.md +1 -1
- package/template/.cursor/skills/review-branch/SKILL.md +2 -0
- package/template/.cursor/skills/review-branch/references/review-checklist.md +2 -2
- package/template/.cursor/skills/security-audit/SKILL.md +2 -0
- package/template/eslint.config.ts +29 -1
package/dist/index.js
CHANGED
|
@@ -308,6 +308,16 @@ async function scaffold(projectName, skipInstall, skipMcp = false, template = "e
|
|
|
308
308
|
spinner2.stop(`Failed to add component: ${component}`);
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
|
+
spinner2.start("Installing shadcn/ui skill");
|
|
312
|
+
try {
|
|
313
|
+
execSync("pnpm dlx skills add shadcn/ui", {
|
|
314
|
+
cwd: targetDir,
|
|
315
|
+
stdio: "pipe"
|
|
316
|
+
});
|
|
317
|
+
spinner2.stop("shadcn/ui skill installed");
|
|
318
|
+
} catch {
|
|
319
|
+
spinner2.stop("shadcn/ui skill install failed \u2014 run manually: pnpm dlx skills add shadcn/ui");
|
|
320
|
+
}
|
|
311
321
|
}
|
|
312
322
|
spinner2.start("Creating initial commit");
|
|
313
323
|
try {
|
package/package.json
CHANGED
|
@@ -23,9 +23,19 @@ readonly: false
|
|
|
23
23
|
Follow `components.mdc` for shadcn/ui, Tailwind v4, and accessibility standards.
|
|
24
24
|
|
|
25
25
|
## Component Discovery
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
|
|
27
|
+
This project has the **shadcn MCP server** configured. Prefer MCP tools over CLI:
|
|
28
|
+
|
|
29
|
+
| Task | MCP tool | CLI fallback |
|
|
30
|
+
|------|----------|--------------|
|
|
31
|
+
| Search for a component | `shadcn_search <query>` | `shadcn search <query>` |
|
|
32
|
+
| Read component docs | `shadcn_docs <component>` | `shadcn docs <component>` |
|
|
33
|
+
| Install a component | `shadcn_install <component>` | `shadcn add <component>` |
|
|
34
|
+
| Check for upstream changes | `shadcn_diff <component>` | `shadcn diff <component>` |
|
|
35
|
+
|
|
36
|
+
**Workflow**: Before building any UI, use `shadcn_search` or `shadcn_docs` to check if a component already exists. Install missing components via MCP or CLI — never manually create files in `@/shared/components/ui/`.
|
|
37
|
+
|
|
38
|
+
The shadcn skill (`pnpm dlx skills add shadcn/ui`) is installed during scaffolding and provides project context automatically via `components.json`.
|
|
29
39
|
|
|
30
40
|
## Component Pattern
|
|
31
41
|
```tsx
|
|
@@ -64,6 +74,12 @@ All user-initiated actions that modify the database must show a toast (success o
|
|
|
64
74
|
- For `useActionState` forms: use a `useEffect` on state changes to trigger toasts
|
|
65
75
|
- Exception: if the action redirects to another page, no success toast is needed
|
|
66
76
|
|
|
77
|
+
## Debugging with next-browser
|
|
78
|
+
|
|
79
|
+
`@vercel/next-browser` — terminal access to a running Next.js app for PPR analysis, component tree inspection, network monitoring, and screenshots.
|
|
80
|
+
|
|
81
|
+
Install: `npx skills add vercel-labs/next-browser`
|
|
82
|
+
|
|
67
83
|
## Guardrails
|
|
68
84
|
- Write RTL tests for every component
|
|
69
85
|
- Verify a11y before marking work done
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
name: technical-lead
|
|
3
3
|
description: Orchestrator and architecture owner. Default entry point for all requests — breaks down tasks, delegates to specialists, and validates architecture. Triggers: new feature planning, architecture questions, task breakdown, multi-agent coordination, refactor planning.
|
|
4
4
|
model: inherit
|
|
5
|
-
# Note: `model: inherit` means this agent uses whatever model the user selected.
|
|
6
|
-
# For security-critical reviews, consider switching to a more capable model explicitly.
|
|
7
5
|
readonly: false
|
|
8
6
|
---
|
|
9
7
|
|
|
8
|
+
<!-- model: inherit means this agent uses whatever model the user selected. For security-critical reviews, consider switching to a more capable model explicitly. -->
|
|
9
|
+
|
|
10
10
|
# Technical Lead Agent
|
|
11
11
|
|
|
12
12
|
## First Step — Load Context via MCP Memory
|
|
@@ -87,12 +87,6 @@ Review against project rules (`coding-standards.mdc`, `architecture.mdc`, `data-
|
|
|
87
87
|
- [ ] TanStack Query is NOT used for mutations (Risk 1)
|
|
88
88
|
- [ ] Every DB mutation shows toast feedback to the user (success or error via `sonner`)
|
|
89
89
|
|
|
90
|
-
## Debugging with next-browser
|
|
91
|
-
|
|
92
|
-
`@vercel/next-browser` — terminal access to a running Next.js app for PPR analysis, component tree inspection, network monitoring, and screenshots.
|
|
93
|
-
|
|
94
|
-
Install: `npx skills add vercel-labs/next-browser`
|
|
95
|
-
|
|
96
90
|
## Guardrails
|
|
97
91
|
- Reject any PR without test coverage
|
|
98
92
|
- Reject any `any` type usage
|
|
@@ -10,10 +10,29 @@ globs: ["src/**/*.ts", "src/**/*.tsx"]
|
|
|
10
10
|
- **Zero `any`** — use `unknown` + type guards or proper generics. `@typescript-eslint/no-explicit-any: error`
|
|
11
11
|
- **Zero comments in production code** — code must be self-documenting through naming. Test AAA labels (`// Arrange`, `// Act`, `// Assert`) are required in tests.
|
|
12
12
|
- **Zero magic numbers/strings** — use typed constants
|
|
13
|
-
- **No `console.log`** in production code — `no-console:
|
|
13
|
+
- **No `console.log`** in production code — `no-console: "error"`
|
|
14
14
|
- **No `!` non-null assertions** — use proper null checks
|
|
15
15
|
- **No `eslint-disable` inline comments** — fix the code instead. If a rule conflict is truly unavoidable (e.g. third-party API with no non-deprecated alternative), add a file-level override in `eslint.config.ts` with a `// TODO` comment explaining why.
|
|
16
16
|
|
|
17
|
+
## AI Agent Lint Pre-Flight
|
|
18
|
+
|
|
19
|
+
Before writing any code, internalize these rules. The project runs `eslint --max-warnings 0` — any violation blocks commits. These are the patterns that most commonly trip AI code generation:
|
|
20
|
+
|
|
21
|
+
- **`no-console: "error"`** — never use `console.*` in production code. Use proper error handling (`throw`) or `ActionResult` error returns.
|
|
22
|
+
- **`strict-boolean-expressions`** — never write `if (value)` for non-boolean types. Use explicit checks:
|
|
23
|
+
- `string`: `if (str !== "")`
|
|
24
|
+
- `number`: `if (n !== 0)`
|
|
25
|
+
- `T | null | undefined`: `if (value !== null && value !== undefined)`
|
|
26
|
+
- `T[]`: `if (array.length > 0)`
|
|
27
|
+
- JSX: `{condition !== null && condition !== undefined && <Component />}`
|
|
28
|
+
- **`naming-convention`** — `camelCase` for variables/functions, `PascalCase` for types/interfaces/React components, `UPPER_CASE` allowed for constants. Never use `snake_case` except in `property` selectors (DB columns, JSON keys).
|
|
29
|
+
- **`no-floating-promises`** — always `await` or prefix with `void` for fire-and-forget.
|
|
30
|
+
- **`restrict-template-expressions`** — never interpolate non-string/number values directly: `` `${someObject}` `` → `` `${someObject.toString()}` ``.
|
|
31
|
+
- **`no-unnecessary-condition`** — never check conditions that the type system proves always truthy/falsy.
|
|
32
|
+
- **`no-unsafe-*`** — never pass `any`-typed values to typed parameters. Narrow with Zod or type guards first.
|
|
33
|
+
|
|
34
|
+
> **Rule of thumb**: If unsure whether a pattern is valid, read `eslint.config.ts` before writing.
|
|
35
|
+
|
|
17
36
|
## TDD
|
|
18
37
|
|
|
19
38
|
Follow the RED → GREEN → REFACTOR cycle. See `testing.mdc` for the full rules and iron rules. Summary: never write implementation without a prior failing test.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: shadcn/ui and Tailwind v4 component standards.
|
|
3
3
|
globs: ["src/**/components/**"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Component Standards
|
|
@@ -11,12 +12,13 @@ globs: ["src/**/components/**"]
|
|
|
11
12
|
- Extend with `className` prop via `cn()` utility
|
|
12
13
|
- New York style, CSS variables for theming
|
|
13
14
|
|
|
14
|
-
## shadcn CLI
|
|
15
|
-
-
|
|
16
|
-
- Before writing component code,
|
|
17
|
-
- Use `
|
|
18
|
-
- Install components with `shadcn add <component>` — never copy-paste component source manually
|
|
19
|
-
- Use `
|
|
15
|
+
## shadcn/ui (MCP + CLI)
|
|
16
|
+
- **MCP tools** (preferred): `shadcn_search`, `shadcn_docs`, `shadcn_install`, `shadcn_diff`
|
|
17
|
+
- Before writing component code, use `shadcn_docs <component>` to get up-to-date API and usage patterns
|
|
18
|
+
- Use `shadcn_search <query>` to discover available components
|
|
19
|
+
- Install components with `shadcn_install` or `shadcn add <component>` — never copy-paste component source manually
|
|
20
|
+
- Use `shadcn_diff <component>` to check for upstream changes to already-installed components
|
|
21
|
+
- The shadcn skill (`pnpm dlx skills add shadcn/ui`) is installed during scaffolding — provides project context automatically
|
|
20
22
|
|
|
21
23
|
## Tailwind v4
|
|
22
24
|
- CSS-native config via `@theme {}` in CSS
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: TanStack Query vs RSC data fetching boundaries.
|
|
2
|
+
description: TanStack Query vs RSC data fetching boundaries. Applied when working on components, pages, queries, hooks, or actions.
|
|
3
3
|
globs: ["src/**/components/**", "src/**/queries/**", "src/**/hooks/**", "src/**/actions/**", "src/app/**"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Data Fetching Rules (Risk 1: TanStack Query + RSC Boundary)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: React Hook Form + Server Actions pattern.
|
|
3
|
-
globs: ["
|
|
2
|
+
description: React Hook Form + Server Actions pattern. Client-side validation via zodResolver + server-side revalidation in the action.
|
|
3
|
+
globs: ["src/**/*form*", "src/**/*.action.ts"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Forms Pattern (Risk 4: RHF + Server Actions)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Security rules (OWASP, auth, RLS, XSS, CSP). Applied to server code, API routes, actions, auth, and config.
|
|
3
3
|
globs: ["src/**/actions/**", "src/**/api/**", "src/**/lib/supabase/**", "src/app/**/route.ts", "src/app/**/proxy.ts", "*.config.*"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Security Rules
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Supabase + Drizzle rules.
|
|
2
|
+
description: Supabase + Drizzle rules. Schema changes require migration — never edit migration files directly.
|
|
3
3
|
globs: ["src/shared/db/**", "src/shared/lib/supabase/**"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Supabase + Drizzle Rules (Risk 2: Zod Schema Drift)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: TDD, Vitest, and Playwright testing standards.
|
|
3
3
|
globs: ["**/*.test.*", "**/e2e/**"]
|
|
4
|
+
alwaysApply: false
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Testing Standards
|
|
@@ -49,7 +50,7 @@ Rules:
|
|
|
49
50
|
- Mock external dependencies only (HTTP calls, Supabase, DB)
|
|
50
51
|
- Test behavior, not implementation details
|
|
51
52
|
- Colocate tests with source: `features/auth/__tests__/`
|
|
52
|
-
-
|
|
53
|
+
- Coverage thresholds are non-negotiable (95% statements/functions/lines, 90% branches — see Iron Rule #3)
|
|
53
54
|
|
|
54
55
|
```typescript
|
|
55
56
|
// ✅ AAA — tests behavior
|
|
@@ -20,6 +20,8 @@ git diff develop...<branch-name>
|
|
|
20
20
|
### 2. Check Each Changed File
|
|
21
21
|
Apply the full checklist from `references/review-checklist.md` — covers code quality, tests, architecture, security, performance, and accessibility.
|
|
22
22
|
|
|
23
|
+
**You MUST check every changed file individually. Do not summarize or skip files. Show your analysis for each file before moving to the next.**
|
|
24
|
+
|
|
23
25
|
### 3. Generate Report
|
|
24
26
|
```
|
|
25
27
|
## Branch Review: <branch-name>
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
## Tests
|
|
12
12
|
- Tests written BEFORE implementation (TDD)
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- ≥95% statement/function/line coverage on new/changed files
|
|
14
|
+
- ≥90% branch coverage (every if/else/ternary/catch)
|
|
15
15
|
- Behavior tested, not implementation
|
|
16
16
|
- AAA pattern with labeled comments on every test
|
|
17
17
|
- Tests NOT weakened (no removed assertions, no loosened matchers, no .skip)
|
|
@@ -8,6 +8,8 @@ disable-model-invocation: true
|
|
|
8
8
|
|
|
9
9
|
## Process
|
|
10
10
|
|
|
11
|
+
**You MUST execute every step below. Do not skip or summarize steps. Show your findings for each step before moving to the next.**
|
|
12
|
+
|
|
11
13
|
Execute all 7 audit steps from `references/audit-steps.md`:
|
|
12
14
|
1. Dependency audit (`pnpm audit`)
|
|
13
15
|
2. Secret scan (hardcoded keys)
|
|
@@ -29,7 +29,31 @@ export default tseslint.config(
|
|
|
29
29
|
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
|
30
30
|
"@typescript-eslint/consistent-type-imports": "error",
|
|
31
31
|
"@typescript-eslint/no-non-null-assertion": "error",
|
|
32
|
-
"no-console": "
|
|
32
|
+
"no-console": "error",
|
|
33
|
+
"@typescript-eslint/strict-boolean-expressions": [
|
|
34
|
+
"error",
|
|
35
|
+
{
|
|
36
|
+
allowString: false,
|
|
37
|
+
allowNumber: false,
|
|
38
|
+
allowNullableObject: false,
|
|
39
|
+
allowNullableBoolean: false,
|
|
40
|
+
allowNullableString: false,
|
|
41
|
+
allowNullableNumber: false,
|
|
42
|
+
allowNullableEnum: false,
|
|
43
|
+
allowAny: false,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
"@typescript-eslint/naming-convention": [
|
|
47
|
+
"error",
|
|
48
|
+
{ selector: "default", format: ["camelCase"], leadingUnderscore: "allow" },
|
|
49
|
+
{ selector: "variable", format: ["camelCase", "UPPER_CASE", "PascalCase"], leadingUnderscore: "allow" },
|
|
50
|
+
{ selector: "function", format: ["camelCase", "PascalCase"] },
|
|
51
|
+
{ selector: "typeLike", format: ["PascalCase"] },
|
|
52
|
+
{ selector: "enumMember", format: ["PascalCase"] },
|
|
53
|
+
{ selector: "import", format: null },
|
|
54
|
+
{ selector: "property", format: null },
|
|
55
|
+
{ selector: "parameter", format: ["camelCase"], leadingUnderscore: "allow" },
|
|
56
|
+
],
|
|
33
57
|
"react/react-in-jsx-scope": "off",
|
|
34
58
|
"react-hooks/rules-of-hooks": "error",
|
|
35
59
|
"react-hooks/exhaustive-deps": "error",
|
|
@@ -51,6 +75,8 @@ export default tseslint.config(
|
|
|
51
75
|
plugins: { vitest: vitestPlugin },
|
|
52
76
|
rules: {
|
|
53
77
|
...vitestPlugin.configs.recommended.rules,
|
|
78
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
79
|
+
"@typescript-eslint/naming-convention": "off",
|
|
54
80
|
},
|
|
55
81
|
},
|
|
56
82
|
{
|
|
@@ -58,6 +84,8 @@ export default tseslint.config(
|
|
|
58
84
|
plugins: { playwright: playwrightPlugin },
|
|
59
85
|
rules: {
|
|
60
86
|
...playwrightPlugin.configs["flat/recommended"].rules,
|
|
87
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
88
|
+
"@typescript-eslint/naming-convention": "off",
|
|
61
89
|
},
|
|
62
90
|
},
|
|
63
91
|
{
|