mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-04 19:21:51 +00:00
chore(skills): update Next.js guidance to version 16 (#11143)
This commit is contained in:
@@ -15,7 +15,7 @@ Use these skills for detailed patterns on-demand:
|
|||||||
|-------|-------------|-----|
|
|-------|-------------|-----|
|
||||||
| `typescript` | Const types, flat interfaces, utility types | [SKILL.md](skills/typescript/SKILL.md) |
|
| `typescript` | Const types, flat interfaces, utility types | [SKILL.md](skills/typescript/SKILL.md) |
|
||||||
| `react-19` | No useMemo/useCallback, React Compiler | [SKILL.md](skills/react-19/SKILL.md) |
|
| `react-19` | No useMemo/useCallback, React Compiler | [SKILL.md](skills/react-19/SKILL.md) |
|
||||||
| `nextjs-15` | App Router, Server Actions, streaming | [SKILL.md](skills/nextjs-15/SKILL.md) |
|
| `nextjs-16` | App Router, Server Actions, proxy.ts, streaming | [SKILL.md](skills/nextjs-16/SKILL.md) |
|
||||||
| `tailwind-4` | cn() utility, no var() in className | [SKILL.md](skills/tailwind-4/SKILL.md) |
|
| `tailwind-4` | cn() utility, no var() in className | [SKILL.md](skills/tailwind-4/SKILL.md) |
|
||||||
| `playwright` | Page Object Model, MCP workflow, selectors | [SKILL.md](skills/playwright/SKILL.md) |
|
| `playwright` | Page Object Model, MCP workflow, selectors | [SKILL.md](skills/playwright/SKILL.md) |
|
||||||
| `pytest` | Fixtures, mocking, markers, parametrize | [SKILL.md](skills/pytest/SKILL.md) |
|
| `pytest` | Fixtures, mocking, markers, parametrize | [SKILL.md](skills/pytest/SKILL.md) |
|
||||||
@@ -60,11 +60,14 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
|--------|-------|
|
|--------|-------|
|
||||||
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
||||||
| Adding DRF pagination or permissions | `django-drf` |
|
| Adding DRF pagination or permissions | `django-drf` |
|
||||||
|
| Adding a compliance output formatter (per-provider class + table dispatcher) | `prowler-compliance` |
|
||||||
|
| Adding indexes or constraints to database tables | `django-migration-psql` |
|
||||||
| Adding new providers | `prowler-provider` |
|
| Adding new providers | `prowler-provider` |
|
||||||
| Adding privilege escalation detection queries | `prowler-attack-paths-query` |
|
| Adding privilege escalation detection queries | `prowler-attack-paths-query` |
|
||||||
| Adding services to existing providers | `prowler-provider` |
|
| Adding services to existing providers | `prowler-provider` |
|
||||||
| After creating/modifying a skill | `skill-sync` |
|
| After creating/modifying a skill | `skill-sync` |
|
||||||
| App Router / Server Actions | `nextjs-15` |
|
| App Router / Server Actions | `nextjs-16` |
|
||||||
|
| Auditing check-to-requirement mappings as a cloud auditor | `prowler-compliance` |
|
||||||
| Building AI chat features | `ai-sdk-5` |
|
| Building AI chat features | `ai-sdk-5` |
|
||||||
| Committing changes | `prowler-commit` |
|
| Committing changes | `prowler-commit` |
|
||||||
| Configuring MCP servers in agentic workflows | `gh-aw` |
|
| Configuring MCP servers in agentic workflows | `gh-aw` |
|
||||||
@@ -78,6 +81,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Creating a git commit | `prowler-commit` |
|
| Creating a git commit | `prowler-commit` |
|
||||||
| Creating new checks | `prowler-sdk-check` |
|
| Creating new checks | `prowler-sdk-check` |
|
||||||
| Creating new skills | `skill-creator` |
|
| Creating new skills | `skill-creator` |
|
||||||
|
| Creating or reviewing Django migrations | `django-migration-psql` |
|
||||||
| Creating/modifying Prowler UI components | `prowler-ui` |
|
| Creating/modifying Prowler UI components | `prowler-ui` |
|
||||||
| Creating/modifying models, views, serializers | `prowler-api` |
|
| Creating/modifying models, views, serializers | `prowler-api` |
|
||||||
| Creating/updating compliance frameworks | `prowler-compliance` |
|
| Creating/updating compliance frameworks | `prowler-compliance` |
|
||||||
@@ -85,6 +89,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Debugging gh-aw compilation errors | `gh-aw` |
|
| Debugging gh-aw compilation errors | `gh-aw` |
|
||||||
| Fill .github/pull_request_template.md (Context/Description/Steps to review/Checklist) | `prowler-pr` |
|
| Fill .github/pull_request_template.md (Context/Description/Steps to review/Checklist) | `prowler-pr` |
|
||||||
| Fixing bug | `tdd` |
|
| Fixing bug | `tdd` |
|
||||||
|
| Fixing compliance JSON bugs (duplicate IDs, empty Section, stale refs) | `prowler-compliance` |
|
||||||
| General Prowler development questions | `prowler` |
|
| General Prowler development questions | `prowler` |
|
||||||
| Implementing JSON:API endpoints | `django-drf` |
|
| Implementing JSON:API endpoints | `django-drf` |
|
||||||
| Implementing feature | `tdd` |
|
| Implementing feature | `tdd` |
|
||||||
@@ -102,6 +107,8 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Review changelog format and conventions | `prowler-changelog` |
|
| Review changelog format and conventions | `prowler-changelog` |
|
||||||
| Reviewing JSON:API compliance | `jsonapi` |
|
| Reviewing JSON:API compliance | `jsonapi` |
|
||||||
| Reviewing compliance framework PRs | `prowler-compliance-review` |
|
| Reviewing compliance framework PRs | `prowler-compliance-review` |
|
||||||
|
| Running makemigrations or pgmakemigrations | `django-migration-psql` |
|
||||||
|
| Syncing compliance framework with upstream catalog | `prowler-compliance` |
|
||||||
| Testing RLS tenant isolation | `prowler-test-api` |
|
| Testing RLS tenant isolation | `prowler-test-api` |
|
||||||
| Testing hooks or utilities | `vitest` |
|
| Testing hooks or utilities | `vitest` |
|
||||||
| Troubleshoot why a skill is missing from AGENTS.md auto-invoke | `skill-sync` |
|
| Troubleshoot why a skill is missing from AGENTS.md auto-invoke | `skill-sync` |
|
||||||
@@ -129,6 +136,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Writing React components | `react-19` |
|
| Writing React components | `react-19` |
|
||||||
| Writing TypeScript types/interfaces | `typescript` |
|
| Writing TypeScript types/interfaces | `typescript` |
|
||||||
| Writing Vitest tests | `vitest` |
|
| Writing Vitest tests | `vitest` |
|
||||||
|
| Writing data backfill or data migration | `django-migration-psql` |
|
||||||
| Writing documentation | `prowler-docs` |
|
| Writing documentation | `prowler-docs` |
|
||||||
| Writing unit tests for UI | `vitest` |
|
| Writing unit tests for UI | `vitest` |
|
||||||
|
|
||||||
@@ -142,7 +150,7 @@ Prowler is an open-source cloud security assessment tool supporting AWS, Azure,
|
|||||||
|-----------|----------|------------|
|
|-----------|----------|------------|
|
||||||
| SDK | `prowler/` | Python 3.10+, Poetry 2.3+ |
|
| SDK | `prowler/` | Python 3.10+, Poetry 2.3+ |
|
||||||
| API | `api/` | Django 5.1, DRF, Celery |
|
| API | `api/` | Django 5.1, DRF, Celery |
|
||||||
| UI | `ui/` | Next.js 15, React 19, Tailwind 4 |
|
| UI | `ui/` | Next.js 16, React 19, Tailwind 4 |
|
||||||
| MCP Server | `mcp_server/` | FastMCP, Python 3.12+ |
|
| MCP Server | `mcp_server/` | FastMCP, Python 3.12+ |
|
||||||
| Dashboard | `dashboard/` | Dash, Plotly |
|
| Dashboard | `dashboard/` | Dash, Plotly |
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,19 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Action | Skill |
|
| Action | Skill |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
||||||
|
| Adding a compliance output formatter (per-provider class + table dispatcher) | `prowler-compliance` |
|
||||||
| Adding new providers | `prowler-provider` |
|
| Adding new providers | `prowler-provider` |
|
||||||
| Adding services to existing providers | `prowler-provider` |
|
| Adding services to existing providers | `prowler-provider` |
|
||||||
|
| Auditing check-to-requirement mappings as a cloud auditor | `prowler-compliance` |
|
||||||
| Create PR that requires changelog entry | `prowler-changelog` |
|
| Create PR that requires changelog entry | `prowler-changelog` |
|
||||||
| Creating new checks | `prowler-sdk-check` |
|
| Creating new checks | `prowler-sdk-check` |
|
||||||
| Creating/updating compliance frameworks | `prowler-compliance` |
|
| Creating/updating compliance frameworks | `prowler-compliance` |
|
||||||
|
| Fixing compliance JSON bugs (duplicate IDs, empty Section, stale refs) | `prowler-compliance` |
|
||||||
| Mapping checks to compliance controls | `prowler-compliance` |
|
| Mapping checks to compliance controls | `prowler-compliance` |
|
||||||
| Mocking AWS with moto in tests | `prowler-test-sdk` |
|
| Mocking AWS with moto in tests | `prowler-test-sdk` |
|
||||||
| Review changelog format and conventions | `prowler-changelog` |
|
| Review changelog format and conventions | `prowler-changelog` |
|
||||||
| Reviewing compliance framework PRs | `prowler-compliance-review` |
|
| Reviewing compliance framework PRs | `prowler-compliance-review` |
|
||||||
|
| Syncing compliance framework with upstream catalog | `prowler-compliance` |
|
||||||
| Update CHANGELOG.md in any component | `prowler-changelog` |
|
| Update CHANGELOG.md in any component | `prowler-changelog` |
|
||||||
| Updating existing checks and metadata | `prowler-sdk-check` |
|
| Updating existing checks and metadata | `prowler-sdk-check` |
|
||||||
| Writing Prowler SDK tests | `prowler-test-sdk` |
|
| Writing Prowler SDK tests | `prowler-test-sdk` |
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ Reusable patterns for common technologies:
|
|||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
| `typescript` | Const types, flat interfaces, utility types |
|
| `typescript` | Const types, flat interfaces, utility types |
|
||||||
| `react-19` | React 19 patterns, React Compiler |
|
| `react-19` | React 19 patterns, React Compiler |
|
||||||
| `nextjs-15` | App Router, Server Actions, streaming |
|
| `nextjs-16` | App Router, Server Actions, proxy.ts, streaming |
|
||||||
| `tailwind-4` | cn() utility, Tailwind 4 patterns |
|
| `tailwind-4` | cn() utility, Tailwind 4 patterns |
|
||||||
| `playwright` | Page Object Model, selectors |
|
| `playwright` | Page Object Model, selectors |
|
||||||
| `vitest` | Unit testing, React Testing Library |
|
| `vitest` | Unit testing, React Testing Library |
|
||||||
|
|||||||
@@ -1,150 +0,0 @@
|
|||||||
---
|
|
||||||
name: nextjs-15
|
|
||||||
description: >
|
|
||||||
Next.js 15 App Router patterns.
|
|
||||||
Trigger: When working in Next.js App Router (app/), Server Components vs Client Components, Server Actions, Route Handlers, caching/revalidation, and streaming/Suspense.
|
|
||||||
license: Apache-2.0
|
|
||||||
metadata:
|
|
||||||
author: prowler-cloud
|
|
||||||
version: "1.0"
|
|
||||||
scope: [root, ui]
|
|
||||||
auto_invoke: "App Router / Server Actions"
|
|
||||||
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
|
|
||||||
---
|
|
||||||
|
|
||||||
## App Router File Conventions
|
|
||||||
|
|
||||||
```
|
|
||||||
app/
|
|
||||||
├── layout.tsx # Root layout (required)
|
|
||||||
├── page.tsx # Home page (/)
|
|
||||||
├── loading.tsx # Loading UI (Suspense)
|
|
||||||
├── error.tsx # Error boundary
|
|
||||||
├── not-found.tsx # 404 page
|
|
||||||
├── (auth)/ # Route group (no URL impact)
|
|
||||||
│ ├── login/page.tsx # /login
|
|
||||||
│ └── signup/page.tsx # /signup
|
|
||||||
├── api/
|
|
||||||
│ └── route.ts # API handler
|
|
||||||
└── _components/ # Private folder (not routed)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Server Components (Default)
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// No directive needed - async by default
|
|
||||||
export default async function Page() {
|
|
||||||
const data = await db.query();
|
|
||||||
return <Component data={data} />;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Server Actions
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// app/actions.ts
|
|
||||||
"use server";
|
|
||||||
|
|
||||||
import { revalidatePath } from "next/cache";
|
|
||||||
import { redirect } from "next/navigation";
|
|
||||||
|
|
||||||
export async function createUser(formData: FormData) {
|
|
||||||
const name = formData.get("name") as string;
|
|
||||||
|
|
||||||
await db.users.create({ data: { name } });
|
|
||||||
|
|
||||||
revalidatePath("/users");
|
|
||||||
redirect("/users");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Usage
|
|
||||||
<form action={createUser}>
|
|
||||||
<input name="name" required />
|
|
||||||
<button type="submit">Create</button>
|
|
||||||
</form>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Data Fetching
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Parallel
|
|
||||||
async function Page() {
|
|
||||||
const [users, posts] = await Promise.all([
|
|
||||||
getUsers(),
|
|
||||||
getPosts(),
|
|
||||||
]);
|
|
||||||
return <Dashboard users={users} posts={posts} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Streaming with Suspense
|
|
||||||
<Suspense fallback={<Loading />}>
|
|
||||||
<SlowComponent />
|
|
||||||
</Suspense>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Route Handlers (API)
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// app/api/users/route.ts
|
|
||||||
import { NextRequest, NextResponse } from "next/server";
|
|
||||||
|
|
||||||
export async function GET(request: NextRequest) {
|
|
||||||
const users = await db.users.findMany();
|
|
||||||
return NextResponse.json(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
|
||||||
const body = await request.json();
|
|
||||||
const user = await db.users.create({ data: body });
|
|
||||||
return NextResponse.json(user, { status: 201 });
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Middleware
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// middleware.ts (root level)
|
|
||||||
import { NextResponse } from "next/server";
|
|
||||||
import type { NextRequest } from "next/server";
|
|
||||||
|
|
||||||
export function middleware(request: NextRequest) {
|
|
||||||
const token = request.cookies.get("token");
|
|
||||||
|
|
||||||
if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
|
|
||||||
return NextResponse.redirect(new URL("/login", request.url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NextResponse.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const config = {
|
|
||||||
matcher: ["/dashboard/:path*"],
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Metadata
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Static
|
|
||||||
export const metadata = {
|
|
||||||
title: "My App",
|
|
||||||
description: "Description",
|
|
||||||
};
|
|
||||||
|
|
||||||
// Dynamic
|
|
||||||
export async function generateMetadata({ params }) {
|
|
||||||
const product = await getProduct(params.id);
|
|
||||||
return { title: product.name };
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## server-only Package
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import "server-only";
|
|
||||||
|
|
||||||
// This will error if imported in client component
|
|
||||||
export async function getSecretData() {
|
|
||||||
return db.secrets.findMany();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
---
|
||||||
|
name: nextjs-16
|
||||||
|
description: >
|
||||||
|
Next.js 16 App Router patterns.
|
||||||
|
Trigger: When working in Next.js App Router (app/), Server Components vs Client Components, Server Actions, Route Handlers, proxy.ts, caching/revalidation, Cache Components, and streaming/Suspense.
|
||||||
|
license: Apache-2.0
|
||||||
|
metadata:
|
||||||
|
author: prowler-cloud
|
||||||
|
version: "1.0"
|
||||||
|
scope: [root, ui]
|
||||||
|
auto_invoke: "App Router / Server Actions"
|
||||||
|
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
|
||||||
|
---
|
||||||
|
|
||||||
|
## App Router File Conventions
|
||||||
|
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── layout.tsx # Root layout (required)
|
||||||
|
├── page.tsx # Home page (/)
|
||||||
|
├── loading.tsx # Loading UI (Suspense)
|
||||||
|
├── error.tsx # Error boundary
|
||||||
|
├── not-found.tsx # 404 page
|
||||||
|
├── (auth)/ # Route group (no URL impact)
|
||||||
|
│ ├── login/page.tsx # /login
|
||||||
|
│ └── signup/page.tsx # /signup
|
||||||
|
├── api/
|
||||||
|
│ └── route.ts # API handler
|
||||||
|
└── _components/ # Private folder (not routed)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next.js 16 Notes
|
||||||
|
|
||||||
|
- Use `proxy.ts` for request-boundary logic. `middleware.ts` is deprecated in Next.js 16.
|
||||||
|
- `proxy.ts` runs on the Node.js runtime and cannot be configured for Edge.
|
||||||
|
- Keep `proxy.ts` matchers narrow. Exclude `api`, static files, and image assets unless the route explicitly needs proxy logic.
|
||||||
|
- Route Handlers in `app/api/**/route.ts` are the right fit for health checks, webhooks, backend-for-frontend endpoints, and server-only proxy calls.
|
||||||
|
|
||||||
|
## Server Components (Default)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// No directive needed - async by default
|
||||||
|
export default async function Page() {
|
||||||
|
const data = await db.query();
|
||||||
|
return <Component data={data} />;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Server Actions
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
"use server";
|
||||||
|
|
||||||
|
import { revalidatePath } from "next/cache";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
export async function createUser(formData: FormData) {
|
||||||
|
const name = formData.get("name") as string;
|
||||||
|
|
||||||
|
await db.users.create({ data: { name } });
|
||||||
|
|
||||||
|
revalidatePath("/users");
|
||||||
|
redirect("/users");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Fetching
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async function Page() {
|
||||||
|
const [users, posts] = await Promise.all([getUsers(), getPosts()]);
|
||||||
|
|
||||||
|
return <Dashboard users={users} posts={posts} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
<Suspense fallback={<Loading />}>
|
||||||
|
<SlowComponent />
|
||||||
|
</Suspense>;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Caching and Revalidation
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { revalidatePath, revalidateTag } from "next/cache";
|
||||||
|
|
||||||
|
export async function refreshDashboard() {
|
||||||
|
"use server";
|
||||||
|
|
||||||
|
revalidatePath("/");
|
||||||
|
revalidateTag("dashboard");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Use `revalidatePath` for route-level invalidation after mutations.
|
||||||
|
- Use `revalidateTag` when data fetches share a cache tag across routes.
|
||||||
|
- With Cache Components enabled, put `"use cache"` only in pure server-side cached functions. Do not cache auth, tenant-scoped, or per-user responses unless the cache key explicitly isolates them.
|
||||||
|
|
||||||
|
## Route Handlers (API)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// app/api/users/route.ts
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const users = await db.users.findMany();
|
||||||
|
return NextResponse.json(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request: Request) {
|
||||||
|
const body = await request.json();
|
||||||
|
const user = await db.users.create({ data: body });
|
||||||
|
return NextResponse.json(user, { status: 201 });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Proxy
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// proxy.ts (root level)
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import type { NextRequest } from "next/server";
|
||||||
|
|
||||||
|
export function proxy(request: NextRequest) {
|
||||||
|
const token = request.cookies.get("token");
|
||||||
|
|
||||||
|
if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
|
||||||
|
return NextResponse.redirect(new URL("/login", request.url));
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: ["/dashboard/:path*"],
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export const metadata = {
|
||||||
|
title: "My App",
|
||||||
|
description: "Description",
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function generateMetadata() {
|
||||||
|
const product = await getProduct();
|
||||||
|
return { title: product.name };
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## server-only Package
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import "server-only";
|
||||||
|
|
||||||
|
export async function getSecretData() {
|
||||||
|
return db.secrets.findMany();
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: prowler-ui
|
name: prowler-ui
|
||||||
description: >
|
description: >
|
||||||
Prowler UI-specific patterns. For generic patterns, see: typescript, react-19, nextjs-15, tailwind-4.
|
Prowler UI-specific patterns. For generic patterns, see: typescript, react-19, nextjs-16, tailwind-4.
|
||||||
Trigger: When working inside ui/ on Prowler-specific conventions (shadcn vs HeroUI legacy, folder placement, actions/adapters, shared types/hooks/lib).
|
Trigger: When working inside ui/ on Prowler-specific conventions (shadcn vs HeroUI legacy, folder placement, actions/adapters, shared types/hooks/lib).
|
||||||
license: Apache-2.0
|
license: Apache-2.0
|
||||||
metadata:
|
metadata:
|
||||||
@@ -18,7 +18,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
|
|||||||
|
|
||||||
- `typescript` - Const types, flat interfaces
|
- `typescript` - Const types, flat interfaces
|
||||||
- `react-19` - No useMemo/useCallback, compiler
|
- `react-19` - No useMemo/useCallback, compiler
|
||||||
- `nextjs-15` - App Router, Server Actions
|
- `nextjs-16` - App Router, Server Actions
|
||||||
- `tailwind-4` - cn() utility, styling rules
|
- `tailwind-4` - cn() utility, styling rules
|
||||||
- `zod-4` - Schema validation
|
- `zod-4` - Schema validation
|
||||||
- `zustand-5` - State management
|
- `zustand-5` - State management
|
||||||
@@ -28,7 +28,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
|
|||||||
## Tech Stack (Versions)
|
## Tech Stack (Versions)
|
||||||
|
|
||||||
```
|
```
|
||||||
Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | shadcn/ui
|
Next.js 16.2.3 | React 19.2.5 | Tailwind 4.1.18 | shadcn/ui
|
||||||
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
|
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
|
||||||
NextAuth 5.0.0-beta.30 | Recharts 2.15.4
|
NextAuth 5.0.0-beta.30 | Recharts 2.15.4
|
||||||
HeroUI 2.8.4 (LEGACY - do not add new components)
|
HeroUI 2.8.4 (LEGACY - do not add new components)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
|
|||||||
|-----------|-------|----------|
|
|-----------|-------|----------|
|
||||||
| SDK | Python 3.10+, Poetry | `prowler/` |
|
| SDK | Python 3.10+, Poetry | `prowler/` |
|
||||||
| API | Django 5.1, DRF, Celery | `api/` |
|
| API | Django 5.1, DRF, Celery | `api/` |
|
||||||
| UI | Next.js 15, React 19, Tailwind 4 | `ui/` |
|
| UI | Next.js 16, React 19, Tailwind 4 | `ui/` |
|
||||||
| MCP | FastMCP 2.13.1 | `mcp_server/` |
|
| MCP | FastMCP 2.13.1 | `mcp_server/` |
|
||||||
|
|
||||||
## Quick Commands
|
## Quick Commands
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: react-19
|
name: react-19
|
||||||
description: >
|
description: >
|
||||||
React 19 patterns with React Compiler.
|
React 19 patterns with React Compiler.
|
||||||
Trigger: When writing React 19 components/hooks in .tsx (React Compiler rules, hook patterns, refs as props). If using Next.js App Router/Server Actions, also use nextjs-15.
|
Trigger: When writing React 19 components/hooks in .tsx (React Compiler rules, hook patterns, refs as props). If using Next.js App Router/Server Actions, also use nextjs-16.
|
||||||
license: Apache-2.0
|
license: Apache-2.0
|
||||||
metadata:
|
metadata:
|
||||||
author: prowler-cloud
|
author: prowler-cloud
|
||||||
|
|||||||
+3
-3
@@ -5,7 +5,7 @@
|
|||||||
> - [`prowler-test-ui`](../skills/prowler-test-ui/SKILL.md) - Playwright E2E testing (comprehensive)
|
> - [`prowler-test-ui`](../skills/prowler-test-ui/SKILL.md) - Playwright E2E testing (comprehensive)
|
||||||
> - [`typescript`](../skills/typescript/SKILL.md) - Const types, flat interfaces
|
> - [`typescript`](../skills/typescript/SKILL.md) - Const types, flat interfaces
|
||||||
> - [`react-19`](../skills/react-19/SKILL.md) - No useMemo/useCallback, compiler
|
> - [`react-19`](../skills/react-19/SKILL.md) - No useMemo/useCallback, compiler
|
||||||
> - [`nextjs-15`](../skills/nextjs-15/SKILL.md) - App Router, Server Actions
|
> - [`nextjs-16`](../skills/nextjs-16/SKILL.md) - App Router, Server Actions
|
||||||
> - [`tailwind-4`](../skills/tailwind-4/SKILL.md) - cn() utility, no var() in className
|
> - [`tailwind-4`](../skills/tailwind-4/SKILL.md) - cn() utility, no var() in className
|
||||||
> - [`zod-4`](../skills/zod-4/SKILL.md) - New API (z.email(), z.uuid())
|
> - [`zod-4`](../skills/zod-4/SKILL.md) - New API (z.email(), z.uuid())
|
||||||
> - [`zustand-5`](../skills/zustand-5/SKILL.md) - Selectors, persist middleware
|
> - [`zustand-5`](../skills/zustand-5/SKILL.md) - Selectors, persist middleware
|
||||||
@@ -21,7 +21,7 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
|
|||||||
| Action | Skill |
|
| Action | Skill |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
| Add changelog entry for a PR or feature | `prowler-changelog` |
|
||||||
| App Router / Server Actions | `nextjs-15` |
|
| App Router / Server Actions | `nextjs-16` |
|
||||||
| Building AI chat features | `ai-sdk-5` |
|
| Building AI chat features | `ai-sdk-5` |
|
||||||
| Committing changes | `prowler-commit` |
|
| Committing changes | `prowler-commit` |
|
||||||
| Create PR that requires changelog entry | `prowler-changelog` |
|
| Create PR that requires changelog entry | `prowler-changelog` |
|
||||||
@@ -179,7 +179,7 @@ test("action works", { tag: ["@critical", "@feature"] }, async ({ page }) => {
|
|||||||
|
|
||||||
## TECH STACK
|
## TECH STACK
|
||||||
|
|
||||||
Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | shadcn/ui
|
Next.js 16.2.3 | React 19.2.5 | Tailwind 4.1.18 | shadcn/ui
|
||||||
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8 | NextAuth 5.0.0-beta.30 | Recharts 2.15.4
|
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8 | NextAuth 5.0.0-beta.30 | Recharts 2.15.4
|
||||||
|
|
||||||
> **Note**: HeroUI exists in `components/ui/` as legacy code. Do NOT add new components there.
|
> **Note**: HeroUI exists in `components/ui/` as legacy code. Do NOT add new components there.
|
||||||
|
|||||||
Reference in New Issue
Block a user