Organize Grey Haven projects following standard structures for TanStack Start (frontend) and FastAPI (backend). Use when creating new projects, organizing files, or refactoring project layout.
/plugin marketplace add greyhaven-ai/claude-code-config/plugin install developer-experience@grey-haven-pluginsThis skill is limited to using the following tools:
checklists/project-setup-checklist.mdexamples/INDEX.mdreference/INDEX.mdFollow Grey Haven Studio's standardized project structures for TypeScript/React (TanStack Start) and Python/FastAPI projects.
Based on cvi-template - TanStack Start, React 19, Drizzle, Better-auth.
project-root/
├── .claude/ # Claude Code configuration
├── .github/workflows/ # GitHub Actions (CI/CD)
├── public/ # Static assets
├── src/
│ ├── routes/ # TanStack Router file-based routes
│ │ ├── __root.tsx # Root layout
│ │ ├── index.tsx # Homepage
│ │ ├── _authenticated/ # Protected routes group
│ │ │ ├── _layout.tsx # Auth layout wrapper
│ │ │ ├── dashboard.tsx # /dashboard
│ │ │ └── profile.tsx # /profile
│ │ └── auth/ # Auth routes
│ │ ├── login.tsx # /auth/login
│ │ └── signup.tsx # /auth/signup
│ ├── lib/
│ │ ├── components/ # React components
│ │ │ ├── ui/ # Shadcn UI (PascalCase)
│ │ │ ├── auth/ # Auth components
│ │ │ ├── layout/ # Layout components
│ │ │ └── shared/ # Shared components
│ │ ├── server/ # Server-side code
│ │ │ ├── schema/ # Drizzle schema (snake_case)
│ │ │ ├── functions/ # Server functions
│ │ │ ├── auth.ts # Better-auth config
│ │ │ └── db.ts # Database connections
│ │ ├── config/ # Configuration
│ │ │ ├── env.ts # Environment validation
│ │ │ └── auth.ts # Auth configuration
│ │ ├── middleware/ # Route middleware
│ │ ├── hooks/ # Custom React hooks (use-*)
│ │ ├── utils/ # Utility functions
│ │ └── types/ # TypeScript types
│ └── tests/
│ ├── unit/ # Vitest unit tests
│ ├── integration/ # Vitest integration tests
│ └── e2e/ # Playwright E2E tests
├── migrations/ # Drizzle migrations
├── .env.example # Example environment variables
├── .prettierrc # Prettier (90 chars, double quotes)
├── .eslintrc # ESLint (any allowed, strict off)
├── tsconfig.json # TypeScript (~/* path alias)
├── commitlint.config.cjs # Commitlint (100 char header)
├── drizzle.config.ts # Drizzle ORM config
├── vite.config.ts # Vite configuration
├── vitest.config.ts # Vitest test configuration
├── package.json # Dependencies (use bun!)
└── README.md # Project documentation
// ✅ Correct - Use ~/* path alias
import { Button } from "~/lib/components/ui/button";
import { getUserById } from "~/lib/server/functions/users";
import { env } from "~/lib/config/env";
import { useAuth } from "~/lib/hooks/use-auth";
// ❌ Wrong - Relative paths
import { Button } from "../../lib/components/ui/button";
UserProfile.tsx, LoginForm.tsx)user-profile.tsx, auth/login.tsx)formatDate.ts, use-auth.ts)auth.ts, users.ts)users.ts, organizations.ts)import { useState } from "react"; // 1. External imports
import { useQuery } from "@tanstack/react-query";
import { Button } from "~/lib/components/ui/button"; // 2. Internal imports
import { getUserById } from "~/lib/server/functions/users";
interface UserProfileProps { // 3. Types/Interfaces
userId: string;
}
export default function UserProfile({ userId }: UserProfileProps) { // 4. Component
const [editing, setEditing] = useState(false); // 5. State hooks
const { data: user } = useQuery({ // 6. Queries/Mutations
queryKey: ["user", userId],
queryFn: () => getUserById(userId),
staleTime: 60000,
});
const handleSave = () => { // 7. Event handlers
// ...
};
return ( // 8. JSX
<div>
<h1>{user?.full_name}</h1>
<Button onClick={handleSave}>Save</Button>
</div>
);
}
Based on cvi-backend-template - FastAPI, SQLModel, Alembic.
project-root/
├── .github/workflows/ # GitHub Actions
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app entry point
│ ├── routers/ # API routers (endpoints)
│ │ ├── __init__.py
│ │ ├── auth.py # /auth routes
│ │ ├── users.py # /users routes
│ │ └── health.py # /health routes
│ ├── services/ # Business logic layer
│ │ ├── __init__.py
│ │ ├── user_service.py
│ │ ├── auth_service.py
│ │ └── billing_service.py
│ ├── db/ # Database layer
│ │ ├── __init__.py
│ │ ├── models/ # SQLModel models (snake_case)
│ │ │ ├── __init__.py
│ │ │ ├── user.py
│ │ │ ├── tenant.py
│ │ │ └── organization.py
│ │ ├── repositories/ # Data access layer
│ │ │ ├── __init__.py
│ │ │ ├── base.py # Base repository
│ │ │ └── user_repository.py
│ │ └── session.py # Database sessions
│ ├── schemas/ # Pydantic schemas
│ │ ├── __init__.py
│ │ ├── user.py # UserCreate, UserResponse
│ │ ├── auth.py # AuthRequest, AuthResponse
│ │ └── common.py # Shared schemas
│ ├── middleware/ # FastAPI middleware
│ │ ├── __init__.py
│ │ ├── auth.py # JWT verification
│ │ └── tenant.py # Tenant context
│ ├── core/ # Core configuration
│ │ ├── __init__.py
│ │ ├── config.py # Settings (Doppler)
│ │ ├── security.py # Password hashing, JWT
│ │ └── deps.py # FastAPI dependencies
│ └── utils/ # Utility functions
│ ├── __init__.py
│ └── format.py
├── tests/ # Pytest tests
│ ├── __init__.py
│ ├── unit/ # @pytest.mark.unit
│ ├── integration/ # @pytest.mark.integration
│ └── e2e/ # @pytest.mark.e2e
├── alembic/ # Alembic migrations
│ ├── versions/
│ └── env.py
├── .env.example # Example environment variables
├── .env # Local environment (gitignored)
├── pyproject.toml # Ruff, mypy, pytest config
├── alembic.ini # Alembic configuration
├── Taskfile.yml # Task runner commands
├── requirements.txt # Production dependencies
├── requirements-dev.txt # Development dependencies
└── README.md # Project documentation
"""Module docstring describing purpose."""
# 1. Standard library imports
import os
from datetime import datetime
from typing import Optional
from uuid import UUID
# 2. Third-party imports
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import select
# 3. Local imports
from app.db.models.user import User
from app.db.repositories.user_repository import UserRepository
from app.schemas.user import UserCreate, UserResponse
user_service.py, auth_middleware.py)User in user.py)test_ prefix (test_user_service.py)# app/db/repositories/base.py
from typing import Generic, TypeVar, Optional
from uuid import UUID
from sqlmodel import select
from sqlalchemy.ext.asyncio import AsyncSession
T = TypeVar("T")
class BaseRepository(Generic[T]):
"""Base repository with CRUD and tenant isolation."""
def __init__(self, session: AsyncSession, model: type[T]):
self.session = session
self.model = model
async def get_by_id(self, id: UUID, tenant_id: UUID) -> Optional[T]:
"""Get by ID with automatic tenant filtering."""
result = await self.session.execute(
select(self.model)
.where(self.model.id == id)
.where(self.model.tenant_id == tenant_id)
)
return result.scalar_one_or_none()
# app/services/user_service.py
from uuid import UUID
from app.db.repositories.user_repository import UserRepository
from app.schemas.user import UserCreate, UserResponse
class UserService:
"""User business logic."""
def __init__(self, user_repo: UserRepository):
self.user_repo = user_repo
async def create_user(self, data: UserCreate, tenant_id: UUID) -> UserResponse:
"""Create new user with validation."""
existing = await self.user_repo.get_by_email(data.email_address, tenant_id)
if existing:
raise ValueError("Email already registered")
user = await self.user_repo.create(data, tenant_id)
return UserResponse.model_validate(user)
All supporting files are under 500 lines per Anthropic best practices:
examples/ - Complete project examples
reference/ - Structure references
templates/ - Copy-paste ready templates
checklists/ - Structure checklists
Use this skill when:
These patterns are from Grey Haven's production templates:
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.