Security
prowler-ui - Claude MCP Skill
Prowler UI-specific patterns. For generic patterns, see: typescript, react-19, nextjs-15, tailwind-4. Trigger: When working inside ui/ on Prowler-specific conventions (shadcn vs HeroUI legacy, folder placement, actions/adapters, shared types/hooks/lib).
SEO Guide: Enhance your AI agent with the prowler-ui tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to prowler ui-specific patterns. for generic patterns, see: typescript, react-19, nextjs-15, tailwind-4... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.md## Related Generic Skills
- `typescript` - Const types, flat interfaces
- `react-19` - No useMemo/useCallback, compiler
- `nextjs-15` - App Router, Server Actions
- `tailwind-4` - cn() utility, styling rules
- `zod-4` - Schema validation
- `zustand-5` - State management
- `ai-sdk-5` - Chat/AI features
- `playwright` - E2E testing (see also `prowler-test-ui`)
## Tech Stack (Versions)
```
Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | 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
HeroUI 2.8.4 (LEGACY - do not add new components)
```
## CRITICAL: Component Library Rule
- **ALWAYS**: Use `shadcn/ui` + Tailwind (`components/shadcn/`)
- **NEVER**: Add new HeroUI components (`components/ui/` is legacy only)
## DECISION TREES
### Component Placement
```
New feature UI? ā shadcn/ui + Tailwind
Existing HeroUI feature? ā Keep HeroUI (don't mix)
Used 1 feature? ā features/{feature}/components/
Used 2+ features? ā components/shared/
Needs state/hooks? ā "use client"
Server component? ā No directive needed
```
### Code Location
```
Server action ā actions/{feature}/{feature}.ts
Data transform ā actions/{feature}/{feature}.adapter.ts
Types (shared 2+) ā types/{domain}.ts
Types (local 1) ā {feature}/types.ts
Utils (shared 2+) ā lib/
Utils (local 1) ā {feature}/utils/
Hooks (shared 2+) ā hooks/
Hooks (local 1) ā {feature}/hooks.ts
shadcn components ā components/shadcn/
HeroUI components ā components/ui/ (LEGACY)
```
### Styling Decision
```
Tailwind class exists? ā className
Dynamic value? ā style prop
Conditional styles? ā cn()
Static only? ā className (no cn())
Recharts/library? ā CHART_COLORS constant + var()
```
### Scope Rule (ABSOLUTE)
- Used 2+ places ā `lib/` or `types/` or `hooks/` (components go in `components/{domain}/`)
- Used 1 place ā keep local in feature directory
- **This determines ALL folder structure decisions**
## Project Structure
```
ui/
āāā app/
ā āāā (auth)/ # Auth pages (login, signup)
ā āāā (prowler)/ # Main app
ā āāā compliance/
ā āāā findings/
ā āāā providers/
ā āāā scans/
ā āāā services/
ā āāā integrations/
āāā components/
ā āāā shadcn/ # shadcn/ui (USE THIS)
ā āāā ui/ # HeroUI (LEGACY)
ā āāā {domain}/ # Domain-specific (compliance, findings, providers, etc.)
ā āāā filters/ # Filter components
ā āāā graphs/ # Chart components
ā āāā icons/ # Icon components
āāā actions/ # Server actions
āāā types/ # Shared types
āāā hooks/ # Shared hooks
āāā lib/ # Utilities
āāā store/ # Zustand state
āāā tests/ # Playwright E2E
āāā styles/ # Global CSS
```
## Recharts (Special Case)
For Recharts props that don't accept className:
```typescript
const CHART_COLORS = {
primary: "var(--color-primary)",
secondary: "var(--color-secondary)",
text: "var(--color-text)",
gridLine: "var(--color-border)",
};
// Only use var() for library props, NEVER in className
<XAxis tick={{ fill: CHART_COLORS.text }} />
<CartesianGrid stroke={CHART_COLORS.gridLine} />
```
## Form + Validation Pattern
```typescript
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
email: z.email(), // Zod 4 syntax
name: z.string().min(1),
});
type FormData = z.infer<typeof schema>;
export function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = async (data: FormData) => {
await serverAction(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
<button type="submit">Submit</button>
</form>
);
}
```
## Commands
```bash
# Development
cd ui && pnpm install
cd ui && pnpm run dev
# Code Quality
cd ui && pnpm run typecheck
cd ui && pnpm run lint:fix
cd ui && pnpm run format:write
cd ui && pnpm run healthcheck # typecheck + lint
# Testing
cd ui && pnpm run test:e2e
cd ui && pnpm run test:e2e:ui
cd ui && pnpm run test:e2e:debug
# Build
cd ui && pnpm run build
cd ui && pnpm start
```
## QA Checklist Before Commit
- [ ] `pnpm run typecheck` passes
- [ ] `pnpm run lint:fix` passes
- [ ] `pnpm run format:write` passes
- [ ] Relevant E2E tests pass
- [ ] All UI states handled (loading, error, empty)
- [ ] No secrets in code (use `.env.local`)
- [ ] Error messages sanitized (no stack traces to users)
- [ ] Server-side validation present (don't trust client)
- [ ] Accessibility: keyboard navigation, ARIA labels
- [ ] Mobile responsive (if applicable)
## Migrations Reference
| From | To | Key Changes |
|------|-----|-------------|
| React 18 | 19.1 | Async components, React Compiler (no useMemo/useCallback) |
| Next.js 14 | 15.5 | Improved App Router, better streaming |
| NextUI | HeroUI 2.8.4 | Package rename only, same API |
| Zod 3 | 4 | `z.email()` not `z.string().email()`, `error` not `message` |
| AI SDK 4 | 5 | `@ai-sdk/react`, `sendMessage` not `handleSubmit`, `parts` not `content` |
## Resources
- **Documentation**: See [references/](references/) for links to local developer guideSignals
Information
- Repository
- prowler-cloud/prowler
- Author
- prowler-cloud
- Last Sync
- 3/12/2026
- Repo Updated
- 3/12/2026
- Created
- 1/12/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
pr-status
PR Status
upgrade-nodejs
Upgrading Bun's Self-Reported Node.js Version
cursorrules
CrewAI Development Rules
cn-check
Install and run the Continue CLI (`cn`) to execute AI agent checks on local code changes. Use when asked to "run checks", "lint with AI", "review my changes with cn", or set up Continue CI locally.
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.