Files
James Bland befb8fbaeb feat: initial Claude Code configuration scaffold
Comprehensive Claude Code guidance system with:

- 5 agents: tdd-guardian, code-reviewer, security-scanner, refactor-scan, dependency-audit
- 18 skills covering languages (Python, TypeScript, Rust, Go, Java, C#),
  infrastructure (AWS, Azure, GCP, Terraform, Ansible, Docker/K8s, Database, CI/CD),
  testing (TDD, UI, Browser), and patterns (Monorepo, API Design, Observability)
- 3 hooks: secret detection, auto-formatting, TDD git pre-commit
- Strict TDD enforcement with 80%+ coverage requirements
- Multi-model strategy: Opus for planning, Sonnet for execution (opusplan)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 15:47:34 -05:00

9.4 KiB

name, description
name description
monorepo-patterns Monorepo workspace patterns for multi-package projects with shared dependencies, testing strategies, and CI/CD. Use when working in monorepo structures.

Monorepo Patterns Skill

project/
├── apps/
│   ├── backend/                 # Python FastAPI
│   │   ├── src/
│   │   ├── tests/
│   │   └── pyproject.toml
│   └── frontend/                # React TypeScript
│       ├── src/
│       ├── tests/
│       └── package.json
├── packages/
│   ├── shared-types/            # Shared TypeScript types
│   │   ├── src/
│   │   └── package.json
│   └── ui-components/           # Shared React components
│       ├── src/
│       └── package.json
├── infrastructure/
│   ├── terraform/
│   │   ├── environments/
│   │   └── modules/
│   └── ansible/
│       ├── playbooks/
│       └── roles/
├── scripts/                     # Shared scripts
├── docs/                        # Documentation
├── .github/
│   └── workflows/
├── package.json                 # Root (workspaces config)
├── pyproject.toml               # Python workspace config
└── CLAUDE.md                    # Project-level guidance

Workspace Configuration

npm Workspaces (Node.js)

// package.json (root)
{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "dev": "npm run dev --workspaces --if-present",
    "build": "npm run build --workspaces --if-present",
    "test": "npm run test --workspaces --if-present",
    "lint": "npm run lint --workspaces --if-present",
    "typecheck": "npm run typecheck --workspaces --if-present"
  },
  "devDependencies": {
    "typescript": "^5.6.0",
    "vitest": "^3.2.0",
    "@types/node": "^22.0.0"
  }
}

UV Workspace (Python)

# pyproject.toml (root)
[project]
name = "my-monorepo"
version = "0.0.0"
requires-python = ">=3.11"

[tool.uv.workspace]
members = ["apps/*", "packages/*"]

[tool.uv.sources]
shared-utils = { workspace = true }

Package References

TypeScript Internal Packages

// packages/shared-types/package.json
{
  "name": "@myorg/shared-types",
  "version": "0.0.0",
  "private": true,
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js"
    }
  },
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch"
  }
}

// apps/frontend/package.json
{
  "name": "@myorg/frontend",
  "dependencies": {
    "@myorg/shared-types": "workspace:*"
  }
}

Python Internal Packages

# packages/shared-utils/pyproject.toml
[project]
name = "shared-utils"
version = "0.1.0"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

# apps/backend/pyproject.toml
[project]
name = "backend"
dependencies = [
  "shared-utils",  # Resolved via workspace
]

Testing Strategies

Run All Tests

# From root
npm test                          # All Node packages
uv run pytest                     # All Python packages

# Specific workspace
npm test --workspace=@myorg/frontend
uv run pytest apps/backend/

Test Dependencies Between Packages

// packages/shared-types/src/user.ts
export type User = {
  id: string;
  email: string;
  name: string;
};

// apps/frontend/src/features/users/types.ts
// Import from workspace package
import type { User } from '@myorg/shared-types';

export type UserListProps = {
  users: User[];
  onSelect: (user: User) => void;
};

Integration Tests Across Packages

// apps/frontend/tests/integration/api.test.ts
import { User } from '@myorg/shared-types';
import { renderWithProviders } from '../utils/render';

describe('Frontend-Backend Integration', () => {
  it('should display user from API', async () => {
    const mockUser: User = {
      id: 'user-1',
      email: 'test@example.com',
      name: 'Test User',
    };

    // Mock API response with shared type
    server.use(
      http.get('/api/users/user-1', () => HttpResponse.json(mockUser))
    );

    render(<UserProfile userId="user-1" />);

    await expect(screen.findByText('Test User')).resolves.toBeInTheDocument();
  });
});

CI/CD Patterns

Change Detection

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      frontend: ${{ steps.changes.outputs.frontend }}
      backend: ${{ steps.changes.outputs.backend }}
      infrastructure: ${{ steps.changes.outputs.infrastructure }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            frontend:
              - 'apps/frontend/**'
              - 'packages/shared-types/**'
              - 'packages/ui-components/**'
            backend:
              - 'apps/backend/**'
              - 'packages/shared-utils/**'
            infrastructure:
              - 'infrastructure/**'

  frontend:
    needs: detect-changes
    if: needs.detect-changes.outputs.frontend == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - run: npm run typecheck --workspace=@myorg/frontend
      - run: npm run lint --workspace=@myorg/frontend
      - run: npm run test --workspace=@myorg/frontend

  backend:
    needs: detect-changes
    if: needs.detect-changes.outputs.backend == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v4
      - run: uv sync
      - run: uv run ruff check apps/backend/
      - run: uv run mypy apps/backend/
      - run: uv run pytest apps/backend/ --cov --cov-fail-under=80

Jenkinsfile for Monorepo

// Jenkinsfile
pipeline {
    agent any

    stages {
        stage('Detect Changes') {
            steps {
                script {
                    def changes = sh(
                        script: 'git diff --name-only HEAD~1',
                        returnStdout: true
                    ).trim().split('\n')

                    env.FRONTEND_CHANGED = changes.any { it.startsWith('apps/frontend/') || it.startsWith('packages/') }
                    env.BACKEND_CHANGED = changes.any { it.startsWith('apps/backend/') }
                    env.INFRA_CHANGED = changes.any { it.startsWith('infrastructure/') }
                }
            }
        }

        stage('Frontend') {
            when {
                expression { env.FRONTEND_CHANGED == 'true' }
            }
            steps {
                dir('apps/frontend') {
                    sh 'npm ci'
                    sh 'npm run typecheck'
                    sh 'npm run lint'
                    sh 'npm run test'
                }
            }
        }

        stage('Backend') {
            when {
                expression { env.BACKEND_CHANGED == 'true' }
            }
            steps {
                sh 'uv sync'
                sh 'uv run ruff check apps/backend/'
                sh 'uv run pytest apps/backend/ --cov --cov-fail-under=80'
            }
        }

        stage('Infrastructure') {
            when {
                expression { env.INFRA_CHANGED == 'true' }
            }
            steps {
                dir('infrastructure/terraform') {
                    sh 'terraform init'
                    sh 'terraform validate'
                    sh 'terraform fmt -check -recursive'
                }
            }
        }
    }
}

Dependency Management

Shared Dependencies at Root

// package.json (root)
{
  "devDependencies": {
    // Shared dev dependencies
    "typescript": "^5.6.0",
    "vitest": "^3.2.0",
    "eslint": "^9.0.0",
    "@types/node": "^22.0.0"
  }
}

Package-Specific Dependencies

// apps/frontend/package.json
{
  "dependencies": {
    // App-specific dependencies
    "react": "^18.3.0",
    "@tanstack/react-query": "^5.0.0"
  }
}

Commands Quick Reference

# Install all dependencies
npm install                       # Node (from root)
uv sync                           # Python

# Run in specific workspace
npm run dev --workspace=@myorg/frontend
npm run test --workspace=@myorg/shared-types

# Run in all workspaces
npm run build --workspaces
npm run test --workspaces --if-present

# Add dependency to specific package
npm install lodash --workspace=@myorg/frontend
uv add requests --package backend

# Add shared dependency to root
npm install -D prettier

CLAUDE.md Placement

Root CLAUDE.md (Project-Wide)

# Project Standards

[Core standards that apply everywhere]

Package-Specific CLAUDE.md

# apps/frontend/CLAUDE.md

## Frontend-Specific Standards

- Use React Testing Library for component tests
- Prefer Radix UI primitives
- Use TanStack Query for server state
# apps/backend/CLAUDE.md

## Backend-Specific Standards

- Use pytest-asyncio for async tests
- Pydantic v2 for all schemas
- SQLAlchemy 2.0 async patterns

Skills in ~/.claude/skills/ are automatically available across all packages in the monorepo.