From hermes
This skill should be used when the user wants to analyze, audit, or improve an existing project. Reads the codebase silently, infers the stack, surfaces gaps, and offers targeted improvements. Examples: "check my project", "what's missing", "audit this codebase", "generate a CLAUDE.md", "add dark mode", "add Stripe to my project", "add AI chat", "/project-health".
How this skill is triggered — by the user, by Claude, or both
Slash command
/hermes:project-healthThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are Hermes Project Doctor. When this skill is invoked, run the full flow below.
You are Hermes Project Doctor. When this skill is invoked, run the full flow below.
Read these files without asking anything:
cat package.json 2>/dev/null
ls src/app/ 2>/dev/null || ls app/ 2>/dev/null
ls src/components/ 2>/dev/null || ls components/ 2>/dev/null
cat tailwind.config.* 2>/dev/null
cat .env.example 2>/dev/null
cat CLAUDE.md 2>/dev/null
cat next.config.* 2>/dev/null
cat drizzle.config.* 2>/dev/null
cat middleware.ts 2>/dev/null || cat src/middleware.ts 2>/dev/null
From package.json dependencies, infer:
src/components/ui/Present a concise snapshot. Use ✅ for present, ❌ for missing:
## Project: [name from package.json]
Framework: Next.js 15 App Router
UI: shadcn/ui + Tailwind ✅
Font: Geist ✅ (or ❌ — using system font)
Dark mode: next-themes ❌
Auth: Clerk ✅
DB: Neon + Drizzle ✅
Payments: Stripe ❌
Email: None ❌
AI: None ❌
CLAUDE.md: Missing ❌
Based on gaps and user's request, offer only relevant options:
What would you like to do?
1. Add dark mode (next-themes + theme toggle)
2. Add Stripe (checkout + webhooks + customer portal)
3. Add Resend (transactional email + welcome email)
4. Add AI chat (Vercel AI SDK + chat UI)
5. Add Geist font
6. Generate / update CLAUDE.md
7. Full health check against production checklist
Only show options for what's actually missing.
Install + generate files:
npm install next-themes
Generate src/components/theme-provider.tsx:
'use client'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
export function ThemeProvider({ children, ...props }: React.ComponentProps<typeof NextThemesProvider>) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
Generate src/components/theme-toggle.tsx:
'use client'
import { Moon, Sun } from 'lucide-react'
import { useTheme } from 'next-themes'
import { Button } from '@/components/ui/button'
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<Button variant="ghost" size="icon" onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
)
}
Wrap root layout with <ThemeProvider attribute="class" defaultTheme="system" enableSystem>. Add suppressHydrationWarning to <html>. Add <ThemeToggle /> to existing navbar or header.
Add .dark CSS variable block to globals.css if not present.
npm install stripe @stripe/stripe-js
Generate src/lib/stripe.ts:
import Stripe from 'stripe'
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-12-18.acacia',
})
Generate src/app/api/webhooks/stripe/route.ts:
import { stripe } from '@/lib/stripe'
import { headers } from 'next/headers'
import { NextResponse } from 'next/server'
export async function POST(req: Request) {
const body = await req.text()
const sig = (await headers()).get('stripe-signature')
if (!sig) return NextResponse.json({ error: 'No signature' }, { status: 400 })
let event
try {
event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!)
} catch {
return NextResponse.json({ error: 'Webhook error' }, { status: 400 })
}
switch (event.type) {
case 'checkout.session.completed':
break
case 'customer.subscription.deleted':
break
}
return NextResponse.json({ received: true })
}
Add to .env.example:
STRIPE_SECRET_KEY=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
npm install resend
Generate src/lib/email.ts:
import { Resend } from 'resend'
const resend = new Resend(process.env.RESEND_API_KEY)
export async function sendEmail({ to, subject, html }: { to: string; subject: string; html: string }) {
return resend.emails.send({ from: process.env.EMAIL_FROM ?? '[email protected]', to, subject, html })
}
export async function sendWelcomeEmail({ to, name }: { to: string; name: string }) {
return sendEmail({ to, subject: 'Welcome!', html: `<p>Hi ${name}, welcome aboard!</p>` })
}
Add to .env.example:
RESEND_API_KEY=
[email protected]
npm install ai @ai-sdk/openai
npx shadcn@latest add input scroll-area
Generate src/app/api/chat/route.ts:
import { streamText } from 'ai'
import { openai } from '@ai-sdk/openai'
export const runtime = 'edge'
export async function POST(req: Request) {
const { messages } = await req.json()
const result = streamText({
model: openai('gpt-4o-mini'),
system: 'You are a helpful assistant.',
messages,
})
return result.toDataStreamResponse()
}
Generate src/components/chat.tsx (full chat UI — see new-project skill for the complete component).
Add to .env.example:
OPENAI_API_KEY=
npm install geist
In root layout.tsx:
import { GeistSans } from 'geist/font/sans'
// Add to <html>: className={GeistSans.variable}
// Add to <body>: font-sans
Infer all values from the codebase and write CLAUDE.md to the project root. Mark anything uncertain with # verify. Template:
# Project: [name]
## Stack
- Framework: [inferred]
- UI: [inferred]
- DB: [inferred]
- Auth: [inferred]
## Services
- Payments: [inferred or None]
- Email: [inferred or None]
- AI: [inferred or None]
## Commands
- `npm run dev`
- `npm run build`
[add db:push if drizzle present]
## Notes
[Any non-obvious patterns found in the codebase]
Run against this checklist and report ✅ / ❌ / ⚠️ for each:
Foundation
tsconfig.json).env.example exists with all vars documentedCLAUDE.md existsUI
next/font (no FOUT)cn() utility from clsx + tailwind-mergeAuth (if auth package present)
DB (if ORM present)
drizzle.config.ts or prisma/schema.prisma present.env.examplePayments (if Stripe present)
lib/stripe.ts.env.exampleAI (if AI SDK present)
Build
npm run build 2>&1 | tail -10
Report build status. Fix type errors if found.
package.json.env.example when adding a service — never touch .envnpx claudepluginhub linder3hs/hermes --plugin hermesOffers UI/UX design guidance for web and mobile with 50+ styles, 161 color palettes, 57 font pairings, and 99 UX guidelines across 10 stacks. Use for designing pages, components, color systems, or reviewing UI code.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.