- Document ~/.hosts file with IP variables and helper functions - Document SSH aliases from ~/.ssh/config - Show primary SSH key (~/.ssh/homelab) - Create central reference files table Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
18 KiB
[PROJECT_NAME] - Claude Code Guidelines
Template Instructions: Copy this file to new projects and customize the sections marked with
[CUSTOMIZE]. Delete this blockquote after customizing.
Project Overview
[CUSTOMIZE] Brief description of what this project does and its purpose.
Tech Stack: [CUSTOMIZE] e.g., Python/FastAPI, TypeScript/React, etc.
Key Directories:
src/- Main source codetests/- Test filesdocs/- Documentation
Spec-Driven Development (Required)
All features and significant changes MUST follow spec-driven development.
Workflow
1. /speckit.specify → Define requirements (what & why, no tech choices)
2. /speckit.plan → Specify technology and architecture
3. /speckit.tasks → Break plan into ordered, actionable tasks
4. /speckit.implement → Build features according to the plan
5. /speckit.clarify → Resolve ambiguities as they arise
When to Use Spec-Kit
| Scenario | Use Spec-Kit? |
|---|---|
| New feature | Yes |
| Significant refactoring | Yes |
| Bug fixes | No |
| Config changes | No |
| Documentation only | No |
Background Agents MUST Reference Specs
When spawning background agents for implementation work, always include spec context:
# CORRECT: Agent has spec context
Task(
subagent_type="general-purpose",
prompt="""
Implement the user authentication module.
SPEC CONTEXT (from specs/auth.md):
- Use JWT tokens with 24h expiry
- Store refresh tokens in httpOnly cookies
- Rate limit: 5 failed attempts per 15 minutes
PLAN CONTEXT (from plans/auth-plan.md):
- Use FastAPI dependency injection for auth middleware
- Pydantic models for token validation
Implementation requirements:
- Follow the spec exactly
- Run tests after implementation
- Ensure type safety with mypy --strict
""",
run_in_background=True
)
# WRONG: Agent has no context about the plan
Task(
subagent_type="general-purpose",
prompt="Implement user authentication", # Too vague!
run_in_background=True
)
Before spawning agents, always:
- Read the relevant spec file(s)
- Read the current plan
- Include key constraints in the agent prompt
- Specify verification steps (tests, type checks)
Type Safety (Strict Enforcement)
Type safety is non-negotiable. All code must pass strict type checking.
Python
# Required before every commit
mypy --strict src/
- Complete type hints on ALL functions (params + return types)
- No
# type: ignorewithout documented justification - Use
TypedDictfor complex dictionaries - Use
Literalfor string enums - Money/prices: Always
Decimal, neverfloat
TypeScript
# Required before every commit
bun run tsc --noEmit
- Enable
strict: truein tsconfig.json - No
anytypes - useunknownand narrow - Explicit return types on all functions
- Use discriminated unions for complex state
Verification Commands
# [CUSTOMIZE] Add project-specific type check commands
mypy --strict src/ # Python
bun run tsc --noEmit # TypeScript
Required Tool Usage
1. Documentation Lookup (Priority Order)
ALWAYS check documentation before implementing unfamiliar APIs:
1. Ref Tools (private docs) → Check first for internal/uploaded docs
mcp__Ref__ref_search_documentation(query="topic ref_src=private")
2. Ref Tools (public docs) → Framework/library documentation
mcp__Ref__ref_search_documentation(query="FastAPI dependency injection")
3. Exa Tools → Web search (last resort)
mcp__exa__web_search_exa(query="...")
mcp__exa__get_code_context_exa(query="...") # Best for code questions
Never guess at API usage. Look it up.
2. Web Search (Use Exa, Not WebFetch)
| Tool | Use Case |
|---|---|
mcp__exa__web_search_exa |
General web search |
mcp__exa__get_code_context_exa |
Programming docs, APIs, libraries |
mcp__exa__crawling_exa |
Extract content from specific URLs |
mcp__exa__deep_researcher_start |
Complex research (multiple sources) |
3. Code Review
Run after completing significant features:
/code-review:code-review
4. Git Commits
Use for all commits:
/commit-commands:commit
For complete workflow (commit + push + PR):
/commit-commands:commit-push-pr
5. Frontend Design
When building UI components or pages:
/frontend-design:frontend-design
This skill produces high-quality, production-grade frontend interfaces.
6. Background Agents
Use for parallel, independent work:
# Launch multiple agents for independent tasks
Task(subagent_type="general-purpose", prompt="...", run_in_background=True)
Task(subagent_type="general-purpose", prompt="...", run_in_background=True)
When to use background agents:
- Building multiple independent modules
- Running tests across different areas
- Implementing features that don't depend on each other
- Parallel research tasks
Always include in agent prompts:
- Spec/plan context (see above)
- Type safety requirements
- Verification steps
MCP Configuration
Active MCPs for This Project
[CUSTOMIZE] List the MCPs this project actually needs:
# Example - keep only what's needed:
- exa (web search)
- Ref (documentation)
- ticktick (task management) - optional
- claude-in-chrome (browser automation) - only if needed
Disabling Unused MCPs
Disable MCPs that aren't needed for this project to reduce noise and improve performance.
To disable MCPs project-wide, add to .claude/settings.json:
{
"mcpServers": {
"unused-mcp-name": {
"disabled": true
}
}
}
Or use /config → MCP Servers → toggle off unused servers.
MCP Usage Guidelines
| MCP | When to Use | When to Disable |
|---|---|---|
exa |
Web search, research | Never (always useful) |
Ref |
Documentation lookup | Never (always useful) |
ticktick |
Task management | Backend-only projects |
claude-in-chrome |
Browser automation, UI testing | Backend-only projects |
beeper |
Messaging integration | Most projects |
shopping |
E-commerce features | Non-commerce projects |
Pre-Commit Checklist
Before every commit, verify:
# 1. Type safety
mypy --strict src/ # Python
bun run tsc --noEmit # TypeScript
# 2. Linting
ruff check src/ # Python
bun run lint # TypeScript
# 3. Formatting
black src/ # Python
bun run format # TypeScript
# 4. Tests
pytest # Python
bun test # TypeScript
# 5. Code review (for significant changes)
/code-review:code-review
Documentation Requirements
Keep Updated
- README.md: Update when adding features, changing setup, or modifying APIs
- CLAUDE.md: Update when conventions change or new patterns emerge
- Spec files: Update when requirements change mid-implementation
- API docs: Update when endpoints change
When to Update CLAUDE.md
Update this file when:
- Claude makes repeated mistakes → Add specific guidance
- New tools/patterns are adopted → Document them
- Conventions change → Update the rules
- New team members join → Ensure onboarding clarity
Code Quality Standards
General Rules
- No over-engineering: Only implement what's requested
- No premature abstraction: Three similar lines > unnecessary helper
- No unused code: Delete completely, don't comment out
- No backwards-compat hacks: If unused, remove it
Security
- Validate all external inputs
- Never log sensitive data (passwords, tokens, PII)
- Use parameterized queries (no SQL injection)
- Escape output (no XSS)
Error Handling
- Handle errors at system boundaries
- Don't catch generic exceptions without re-raising
- Log errors with context
- Fail fast on invalid state
Project-Specific Patterns
[CUSTOMIZE] Document patterns specific to this project:
API Conventions
# Example: Standard response format
{
"data": {...},
"error": null,
"meta": {"timestamp": "..."}
}
Naming Conventions
- Files:
snake_case.py/kebab-case.ts - Classes:
PascalCase - Functions:
snake_case/camelCase - Constants:
UPPER_SNAKE_CASE
Testing Patterns
# Example: Test file naming
tests/
test_<module_name>.py
conftest.py # Shared fixtures
Quick Reference
Starting a New Feature
/speckit.specify # Define what you're building
/speckit.plan # Plan how to build it
/speckit.tasks # Break into tasks
/speckit.implement # Build it
/code-review:code-review
/commit-commands:commit
Bug Fix (Skip Spec-Kit)
# Direct implementation
# Then:
/code-review:code-review
/commit-commands:commit
Research Before Coding
1. mcp__Ref__ref_search_documentation # Check docs first
2. mcp__exa__get_code_context_exa # Then web search
Homelab Infrastructure (Available Resources)
Reference documentation: ~/Projects/homelab/
Central Reference Files
| File | Purpose | Usage |
|---|---|---|
~/.secrets |
API keys and passwords | source ~/.secrets |
~/.hosts |
IPs, hostnames, URLs | source ~/.hosts |
~/.ssh/config |
SSH aliases and keys | ssh pve, ssh truenas |
SSH Access
Primary key: ~/.ssh/homelab (used for all homelab hosts)
# Use aliases from ~/.ssh/config
ssh pve # Proxmox primary
ssh pve2 # Proxmox secondary
ssh truenas # NAS
ssh saltbox # Media services
ssh docker-host # Docker services
ssh lmdev1 # AI dev with GPU
ssh trading-vm # Trading with A6000
ssh pihole # DNS
ssh traefik # Reverse proxy
Hosts Reference
Source ~/.hosts for IP variables:
source ~/.hosts
curl http://$IP_TRUENAS:8080/api/...
ping $IP_GATEWAY
hosts_list # Show all hosts
hosts_check # Ping critical hosts
API Credentials
Central secrets file: ~/.secrets
# Source credentials
source ~/.secrets
# Use in commands
curl -H "Authorization: token $GITEA_TOKEN" https://git.htsn.io/api/v1/...
curl -H "Authorization: Bearer $HA_TOKEN" $HA_URL/api/...
curl -H "X-API-Key: $SYNCTHING_API_KEY_MACMINI" http://127.0.0.1:8384/rest/...
curl -H "X-N8N-API-KEY: $N8N_API_KEY" $N8N_URL/api/v1/...
Available credentials (see ~/.secrets for values):
| Category | Variables | Purpose |
|---|---|---|
| Git/Dev | GITEA_TOKEN |
Gitea API access |
| Home | HA_TOKEN, SYNCTHING_API_KEY_* |
Home Assistant, file sync |
| Automation | N8N_API_KEY, TELEGRAM_BOT_TOKEN |
Workflows, notifications |
| Productivity | TICKTICK_*, NOTION_*, AIRTABLE_* |
Tasks, notes, databases |
| Trading | ALPACA_*_API_KEY, FINNHUB_API_KEY |
Live/paper trading, market data |
| AI/LLM | GROQ_API_KEY, PORTKEY_API_KEY, WISPRFLOW_API_KEY |
AI services |
| Media | ICONIK_* |
Asset management |
| Infra | CF_API_KEY, OPENWEATHERMAP_API_KEY |
DNS, weather |
Servers
| Server | IP | Specs | GPU | Purpose |
|---|---|---|---|---|
| PVE | 10.10.10.120 | Threadripper PRO 3975WX (32C/64T), 128GB ECC | TITAN RTX (24GB) | Primary Proxmox host |
| PVE2 | 10.10.10.102 | Threadripper PRO 3975WX (32C/64T), 128GB ECC | RTX A6000 (48GB) | Secondary Proxmox host |
Key VMs (for deployment targets)
| VMID | Name | IP | Purpose | Resources |
|---|---|---|---|---|
| 100 | truenas | 10.10.10.200 | Central NAS, NFS/SMB | ZFS vault pool |
| 101 | saltbox | 10.10.10.100 | Media services (Plex, *arr) | TITAN RTX passthrough |
| 111 | lmdev1 | 10.10.10.111 | AI/LLM development | TITAN RTX (shared) |
| 206 | docker-host | 10.10.10.206 | Docker services | General purpose |
| 301 | trading-vm | 10.10.10.221 | AI trading platform | A6000 passthrough |
Services & URLs
| Service | URL | Purpose |
|---|---|---|
| Proxmox | https://pve.htsn.io:8006 | VM management |
| TrueNAS | https://truenas.htsn.io | Storage management |
| Gitea | https://git.htsn.io | Git repositories |
| Plex | https://plex.htsn.io | Media streaming |
| Home Assistant | https://homeassistant.htsn.io | Home automation |
| Traefik | 10.10.10.250:8080 | Reverse proxy dashboard |
Network
- LAN: 10.10.10.0/24 (gateway: 10.10.10.1)
- Internal storage: 10.10.20.0/24 (no external access)
- Tailscale: 100.x.x.x overlay for remote access
- 10Gb: Available between PVE, TrueNAS, Saltbox via vmbr1/vmbr2
Storage Pools
| Pool | Location | Capacity | Purpose |
|---|---|---|---|
| nvme-mirror1 | PVE | 3.6 TB | Fast VM storage |
| nvme-mirror2 | PVE | 1.8 TB | Additional fast storage |
| rpool | PVE | 3.6 TB | Proxmox OS, containers |
| vault | TrueNAS | ~12+ TB | Central file storage |
SSH Access
ssh pve # Primary Proxmox
ssh pve2 # Secondary Proxmox
ssh truenas # TrueNAS storage
ssh saltbox # Media services
ssh docker-host # Docker services
Deployment Considerations
- AI/ML workloads: Use lmdev1 (TITAN RTX) or trading-vm (A6000)
- Docker services: Deploy to docker-host (10.10.10.206)
- Storage-heavy: Use TrueNAS NFS mounts via 10.10.20.x network
- Public services: Route through Traefik at *.htsn.io
Gotchas & Anti-Patterns
[CUSTOMIZE] Document things Claude should avoid or watch out for:
Known Gotchas
- [CUSTOMIZE] e.g., "The
user.emailfield can be null for OAuth users" - [CUSTOMIZE] e.g., "Always use
get_db()dependency, never create sessions directly" - [CUSTOMIZE] e.g., "The legacy
/api/v1/routes are deprecated, use/api/v2/"
Anti-Patterns (Do NOT Do These)
- Don't use
setTimeoutfor polling - use the existinguseIntervalhook - Don't import from
@/lib/deprecated/*- these are scheduled for removal - Don't add new dependencies without checking
package.jsonfor existing alternatives
Known Tech Debt (Don't Copy These Patterns)
[CUSTOMIZE] List files or patterns that exist but shouldn't be replicated:
src/legacy/old_auth.py- Legacy auth, usesrc/auth/insteadcomponents/OldButton.tsx- Use design systemButtoncomponent- Any file in
src/deprecated/- These are migration targets
Permission Boundaries
Claude Should NOT Automatically:
- Delete files or directories without explicit confirmation
- Push to
mainormasterbranches directly - Modify
.envfiles or secrets - Run database migrations in production
- Make breaking API changes without discussion
- Install new major dependencies without asking
Always Ask Before:
- Changing database schemas
- Modifying authentication/authorization logic
- Updating CI/CD configurations
- Changing public API contracts
- Removing features (even if they seem unused)
Environment-Specific Behavior
Development
# [CUSTOMIZE] Dev-specific commands
bun run dev # Start dev server
docker-compose up -d # Local services
Testing
# [CUSTOMIZE] Test commands
pytest --cov=src # With coverage
bun test --watch # Watch mode
Production (Read-Only Context)
- Never run destructive commands against production
- Use read-only database connections for debugging
- Always use staging for testing changes first
Domain Terminology
[CUSTOMIZE] Define project-specific terms Claude should understand:
| Term | Definition |
|---|---|
| [CUSTOMIZE] | e.g., "Workspace" = A collection of projects belonging to one org |
| [CUSTOMIZE] | e.g., "Pipeline" = The CI/CD workflow, not data processing |
| [CUSTOMIZE] | e.g., "Agent" = Background worker process, not AI agent |
Hooks Configuration
[CUSTOMIZE] Document any automated hooks in .claude/settings.json:
Recommended Hooks
{
"hooks": {
"postToolUse": [
{
"tool": "Edit",
"command": "bun run format --write $FILE"
}
],
"preCommit": [
{
"command": "bun run lint && bun run typecheck"
}
]
}
}
Active Hooks in This Project
- [CUSTOMIZE] e.g., "Auto-format on file edit"
- [CUSTOMIZE] e.g., "Run tests on save"
- [CUSTOMIZE] e.g., "Block direct edits to main branch"
Modular Rules (For Large Projects)
For complex projects, break rules into .claude/rules/ directory:
.claude/
rules/
code-style.md # Formatting, naming conventions
testing.md # Test patterns and requirements
security.md # Security requirements
api-design.md # API conventions
frontend/
components.md # Component patterns
state.md # State management rules
backend/
database.md # DB access patterns
services.md # Service layer conventions
All .md files in .claude/rules/ are automatically loaded.
Error Recovery
When Tests Fail
- Read the full error message
- Check if it's a flaky test (run again)
- Check recent changes that might have caused it
- Fix the root cause, don't just make the test pass
When Type Checks Fail
- Don't add
# type: ignorewithout understanding why - Check if types need updating in a shared module
- Ensure third-party type stubs are installed
- Document any legitimate type: ignore with a reason
When Stuck
- Re-read the spec/plan for context
- Check Ref Tools for documentation
- Search with Exa for solutions
- Ask for clarification rather than guessing
Troubleshooting
[CUSTOMIZE] Add project-specific troubleshooting:
Common Issues
Type errors with third-party libraries:
# Install type stubs
pip install types-<package>
# Or add to pyproject.toml py.typed packages
Tests failing in CI but not locally:
# Check for environment differences
# Ensure all deps are in requirements.txt/package.json
MCP tools not working:
# Check MCP server status
/config → MCP Servers → verify connection
# Restart Claude Code if needed