prowler-ui
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).
- License 许可
- Apache-2.0
- 最近更新
- 2026-08-03
- Stars
- ★ 1
- Forks
- 0
01 前言 Front Matter
- name
- prowler-ui
- license
- Apache-2.0
- metadata
- { "scope": [ "root", "ui" ], "author": "prowler-cloud", "version": "1.0", "auto_invoke": [ "Creating/modifying Prowler UI components", "Working on Prowler UI structure (actions/adapters/types/hooks)" ] }
- description
- 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).
- allowed-tools
- Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
02 资源文件 3
- 参考文档references/ui-docs.md294 B
- 参考文档SOURCE.md185 B
- 参考文档TRUST.auto.yaml2.2 KB
03 SKILL.md 正文
Related Generic Skills
typescript- Const types, flat interfacesreact-19- No useMemo/useCallback, compilernextjs-15- App Router, Server Actionstailwind-4- cn() utility, styling ruleszod-4- Schema validationzustand-5- State managementai-sdk-5- Chat/AI featuresplaywright- E2E testing (see alsoprowler-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/ortypes/orhooks/(components go incomponents/{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:
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
"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
# 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 typecheckpasses - [ ]
pnpm run lint:fixpasses - [ ]
pnpm run format:writepasses - [ ] 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/ for links to local developer guide
04 同仓库更多 Skills
next-workflow-step
Use this skill when the user wants to transition to the next workflow step, wrap up a session cleanly, prepare a handoff, or says things like "next step", "continue the workflow", "wrap up", "hand off", "move to the next phase", "what's next in embrace", or "prepare for /clear". Also triggers when the current octo:embrace phase appears complete and no explicit next action is set.
source-discovery
This skill should be used when the user asks to "find sources", "discover URLs", "catalog a source", "classify a URL", "search for libraries", "check what exists", or mentions source discovery, URL cataloging, source classification, or research source management.
review-synthesis
This skill should be used when the user asks to "summarize review findings", "prioritize fixes", "rank review issues", "combine reviewer feedback", "create action items from review", or mentions review synthesis, finding prioritization, severity ranking, or review result summarization.
research-scoring
This skill should be used when the user asks to "score research", "check research quality", "evaluate coverage", "measure improvement", "assess research completeness", or mentions research scoring, quality metrics, coverage gaps, improvement baseline, or research pipeline status.
notebooklm-integration
This skill should be used when the user asks to "ingest into NotebookLM", "query NotebookLM", "add sources to notebook", "cross-source synthesis", "check stale sources", or mentions NotebookLM, notebook integration, source ingestion, or knowledge consolidation.
evidence-synthesis
This skill should be used when the user asks to "synthesize findings", "combine research", "cross-reference sources", "summarize evidence", "write a deep review", or mentions evidence synthesis, finding consolidation, cross-source analysis, or research summarization.