> For the complete documentation index, see [llms.txt](https://gotts.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gotts.gitbook.io/docs/monorepo-infrastructure/monorepo/10-appendix.md).

# Appendix

> **Part of**: [Monorepo Infrastructure PRD](/docs/monorepo-infrastructure/monorepo.md) | **Last Updated**: 2026-02-19
>
> Every config file in the monorepo, complete and copy-pasteable. Files are grouped by location in the directory tree.

***

## Root Directory

### `package.json`

```jsonc
{
  "name": "gotts-monorepo",
  "private": true,
  "packageManager": "pnpm@9.15.9",
  "engines": {
    "node": ">=20.0.0",
  },
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "test": "turbo run test",
    "test:integration": "turbo run test:integration",
    "lint": "turbo run lint",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "check-types": "turbo run check-types",
    "clean": "turbo run clean && rm -rf node_modules .turbo",
    "clean:turbo": "rm -rf .turbo **/node_modules/.cache/turbo",
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "turbo run build --filter='./packages/*' && changeset publish",
    "knip": "knip",
    "syncpack:check": "syncpack lint",
    "syncpack:fix": "syncpack fix-mismatches",
    "prepare": "husky",
  },
  "devDependencies": {
    "@changesets/cli": "^2.27.0",
    "@commitlint/cli": "^19.0.0",
    "@commitlint/config-conventional": "^19.0.0",
    "eslint": "^10.0.0",
    "husky": "^9.0.0",
    "knip": "^5.0.0",
    "lint-staged": "^16.0.0",
    "prettier": "^3.5.0",
    "prettier-plugin-tailwindcss": "^0.6.0",
    "syncpack": "^13.0.0",
    "tsdown": "^0.8.0",
    "tsx": "^4.0.0",
    "turbo": "^2.8.0",
    "typescript": "^5.8.0",
    "vitest": "^4.0.0",
  },
}
```

### `pnpm-workspace.yaml`

```yaml
packages:
  - "packages/*"
  - "apps/*"
```

### `.npmrc`

```ini
# Hoist only peer dependencies needed by tools that don't support pnpm's strict layout
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*

# Strict mode: fail on missing peer dependencies
strict-peer-dependencies=true

# Use the fastest resolution strategy
resolution-mode=highest
```

### `turbo.json`

```jsonc
{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": ["**/.env.*local"],
  "ui": "tui",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["src/**", "tsconfig.json", "tsdown.config.ts", "package.json"],
      "outputs": ["dist/**"],
    },
    "check-types": {
      "dependsOn": ["^check-types"],
      "inputs": ["src/**", "test/**", "tsconfig.json"],
      "outputs": [],
    },
    "dev": {
      "cache": false,
      "persistent": true,
    },
    "lint": {
      "dependsOn": ["^build"],
      "inputs": [
        "src/**",
        "test/**",
        "eslint.config.ts",
        "../../eslint.config.ts",
      ],
      "outputs": [],
    },
    "test": {
      "dependsOn": ["^build"],
      "inputs": ["src/**", "test/**", "vitest.config.ts"],
      "outputs": [],
    },
    "test:integration": {
      "dependsOn": ["^build"],
      "inputs": ["src/**", "test/**"],
      "outputs": [],
      "cache": false,
    },
    "clean": {
      "cache": false,
    },
  },
}
```

### `tsconfig.json`

```jsonc
{
  "extends": "@gotts.ai/typescript-config/base.json",
  "compilerOptions": {
    "noEmit": true,
  },
  "include": [],
  "references": [
    { "path": "packages/safe" },
    { "path": "packages/vault" },
    { "path": "packages/agent-proxy" },
    { "path": "packages/ui" },
    { "path": "apps/web" },
  ],
}
```

### `vitest.config.ts`

```typescript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    projects: ["packages/*/vitest.config.ts", "apps/*/vitest.config.ts"],
  },
});
```

### `eslint.config.ts`

```typescript
import { base } from "@gotts.ai/eslint-config";

export default [
  ...base,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  {
    ignores: [
      "dist/",
      "node_modules/",
      ".turbo/",
      ".next/",
      "coverage/",
      "**/*.config.{ts,js,mjs}",
    ],
  },
];
```

### `.prettierrc`

```jsonc
{
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "bracketSpacing": true,
  "arrowParens": "always",
  "endOfLine": "lf",
  "plugins": ["prettier-plugin-tailwindcss"],
}
```

### `.prettierignore`

```
dist
node_modules
.turbo
.next
pnpm-lock.yaml
coverage
*.sol
```

### `commitlint.config.ts`

```typescript
import type { UserConfig } from "@commitlint/types";

const config: UserConfig = {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "scope-enum": [
      2,
      "always",
      [
        "safe",
        "vault",
        "agent-proxy",
        "ui",
        "eslint-config",
        "typescript-config",
        "web",
        "ci",
        "deps",
        "monorepo",
      ],
    ],
    "body-max-line-length": [0, "always", Infinity],
  },
};

export default config;
```

### `lint-staged.config.mjs`

```javascript
export default {
  "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
  "*.{json,md,yml,yaml}": ["prettier --write"],
  "*.sol": ["forge fmt"],
};
```

### `knip.config.ts`

```typescript
import type { KnipConfig } from "knip";

const config: KnipConfig = {
  workspaces: {
    ".": {
      entry: ["scripts/*.ts"],
      ignoreDependencies: ["husky", "lint-staged"],
    },
    "packages/safe": {
      entry: ["src/index.ts"],
      ignoreDependencies: [],
    },
    "packages/vault": {
      entry: ["src/index.ts", "sdk/src/index.ts"],
      ignoreDependencies: [],
    },
    "packages/agent-proxy": {
      entry: ["src/index.ts", "sdk/src/index.ts"],
      ignoreDependencies: [],
    },
    "packages/ui": {
      entry: ["src/index.ts"],
      ignoreDependencies: [],
    },
    "apps/web": {
      entry: ["src/app/**/*.{ts,tsx}"],
      ignoreDependencies: [],
    },
  },
  ignore: ["**/*.d.ts", "**/*.config.{ts,js,mjs}"],
};

export default config;
```

### `syncpack.config.ts`

```typescript
import type { RcFile } from "syncpack";

const config: RcFile = {
  sortFirst: [
    "name",
    "version",
    "private",
    "type",
    "description",
    "license",
    "repository",
    "exports",
    "main",
    "types",
    "files",
    "scripts",
    "dependencies",
    "devDependencies",
    "peerDependencies",
    "engines",
    "publishConfig",
  ],
  versionGroups: [
    {
      label: "Use workspace protocol for internal packages",
      dependencies: ["@gotts.ai/*"],
      dependencyTypes: ["dev", "prod"],
      pinVersion: "workspace:*",
    },
  ],
  semverGroups: [
    {
      label: "All dependencies use caret ranges",
      range: "^",
      dependencies: ["**"],
      packages: ["**"],
    },
  ],
};

export default config;
```

***

## `.husky/`

### `.husky/pre-commit`

```bash
pnpm exec lint-staged
```

### `.husky/commit-msg`

```bash
pnpm exec commitlint --edit $1
```

***

## `.vscode/`

### `.vscode/extensions.json`

```jsonc
{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "bradlc.vscode-tailwindcss",
    "ms-vscode.vscode-typescript-next",
    "vitest.explorer",
    "juanblanco.solidity",
    "vercel.turbo-vscode",
  ],
}
```

### `.vscode/settings.json`

```jsonc
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "eslint.useFlatConfig": true,
  "eslint.workingDirectories": [
    { "pattern": "packages/*" },
    { "pattern": "apps/*" },
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
  },
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "tailwindCSS.experimental.configFile": "apps/web/tailwind.css",
  "files.associations": {
    "*.css": "tailwindcss",
  },
  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/.turbo": true,
    "**/.next": true,
    "**/coverage": true,
    "pnpm-lock.yaml": true,
  },
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.patterns": {
    "package.json": "pnpm-lock.yaml, .npmrc, pnpm-workspace.yaml, turbo.json",
    "tsconfig.json": "tsconfig.*.json",
    ".gitignore": ".gitattributes, .prettierignore, .eslintignore",
  },
}
```

***

## `.changeset/`

### `.changeset/config.json`

```jsonc
{
  "$schema": "https://unpkg.com/@changesets/config@3/schema.json",
  "changelog": "@changesets/cli/changelog",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": [],
  "privatePackages": {
    "version": false,
    "tag": false,
  },
}
```

***

## `.github/`

### `.github/workflows/ci.yml`

```yaml
name: CI

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

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  ci:
    name: Build & Test
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Check formatting
        run: pnpm format:check

      - name: Lint
        run: pnpm lint

      - name: Type check
        run: pnpm check-types

      - name: Build
        run: pnpm build

      - name: Test
        run: pnpm test

      - name: publint
        run: |
          for pkg in packages/safe packages/vault packages/agent-proxy; do
            pnpm dlx publint "$pkg"
          done

  foundry:
    name: Solidity Tests
    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Foundry
        uses: foundry-rs/foundry-toolchain@v1

      - name: Forge build (vault)
        working-directory: packages/vault
        run: forge build

      - name: Forge test (vault)
        working-directory: packages/vault
        run: forge test -vvv

      - name: Forge build (agent-proxy)
        working-directory: packages/agent-proxy
        run: forge build

      - name: Forge test (agent-proxy)
        working-directory: packages/agent-proxy
        run: forge test -vvv
```

### `.github/workflows/release.yml`

```yaml
name: Release

on:
  push:
    branches: [main]

concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: false

permissions:
  contents: write
  pull-requests: write
  id-token: write

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
          registry-url: "https://registry.npmjs.org"

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Create Release Pull Request or Publish
        id: changesets
        uses: changesets/action@v1
        with:
          publish: pnpm release
          version: pnpm version-packages
          title: "chore(release): version packages"
          commit: "chore(release): version packages"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
```

### `.github/renovate.json5`

```json5
{
  $schema: "https://docs.renovatebot.com/renovate-schema.json",
  extends: [
    "config:recommended",
    ":semanticCommits",
    ":automergeMinor",
    "group:monorepos",
    "group:recommended",
  ],
  labels: ["dependencies"],
  rangeStrategy: "bump",
  packageRules: [
    {
      description: "Group all non-major updates together",
      matchUpdateTypes: ["minor", "patch"],
      groupName: "all non-major dependencies",
      groupSlug: "all-minor-patch",
      schedule: ["before 6am on Monday"],
    },
    {
      description: "Auto-merge dev dependencies",
      matchDepTypes: ["devDependencies"],
      matchUpdateTypes: ["minor", "patch"],
      automerge: true,
    },
    {
      description: "Group Foundry updates",
      matchPackageNames: ["foundry-rs/**"],
      groupName: "foundry",
    },
  ],
  ignoreDeps: [],
}
```

***

## `packages/typescript-config/`

### `package.json`

```jsonc
{
  "name": "@gotts.ai/typescript-config",
  "version": "0.0.0",
  "private": true,
  "license": "MIT",
  "exports": {
    "./base.json": "./base.json",
    "./library.json": "./library.json",
    "./nextjs.json": "./nextjs.json",
  },
}
```

### `base.json`

```jsonc
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noEmit": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "target": "es2022",
    "lib": ["es2022"],
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "verbatimModuleSyntax": true,
    "erasableSyntaxOnly": true,
  },
  "exclude": ["node_modules", "dist"],
}
```

### `library.json`

```jsonc
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./base.json",
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "bundler",
    "declaration": true,
    "declarationMap": true,
    "outDir": "dist",
  },
}
```

### `nextjs.json`

```jsonc
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "./base.json",
  "compilerOptions": {
    "target": "es2022",
    "lib": ["dom", "dom.iterable", "es2022"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "jsx": "preserve",
    "plugins": [{ "name": "next" }],
    "allowJs": true,
  },
}
```

***

## `packages/eslint-config/`

### `package.json`

```jsonc
{
  "name": "@gotts.ai/eslint-config",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "default": "./src/index.ts",
    },
    "./base": {
      "types": "./src/base.ts",
      "default": "./src/base.ts",
    },
    "./library": {
      "types": "./src/library.ts",
      "default": "./src/library.ts",
    },
    "./nextjs": {
      "types": "./src/nextjs.ts",
      "default": "./src/nextjs.ts",
    },
  },
  "dependencies": {
    "@eslint/js": "^10.0.0",
    "eslint-plugin-perfectionist": "^4.0.0",
    "eslint-plugin-turbo": "^2.0.0",
    "typescript-eslint": "^8.0.0",
  },
  "peerDependencies": {
    "eslint": "^10.0.0",
    "typescript": "^5.8.0",
  },
}
```

### `tsconfig.json`

```jsonc
{
  "extends": "@gotts.ai/typescript-config/base.json",
  "include": ["src"],
  "exclude": ["node_modules"],
}
```

### `src/base.ts`

```typescript
import eslint from "@eslint/js";
import perfectionist from "eslint-plugin-perfectionist";
import turboPlugin from "eslint-plugin-turbo";
import tseslint from "typescript-eslint";
import type { Linter } from "eslint";

export const base: Linter.Config[] = [
  eslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  ...tseslint.configs.stylisticTypeChecked,
  {
    plugins: {
      perfectionist,
      turbo: turboPlugin,
    },
    rules: {
      "perfectionist/sort-imports": [
        "error",
        {
          type: "natural",
          groups: [
            "builtin",
            "external",
            "internal",
            "parent",
            "sibling",
            "index",
            "type",
          ],
          newlinesBetween: "always",
        },
      ],
      "perfectionist/sort-named-exports": ["error", { type: "natural" }],
      "perfectionist/sort-named-imports": ["error", { type: "natural" }],
      "turbo/no-undeclared-env-vars": "warn",
      "@typescript-eslint/no-explicit-any": "error",
      "@typescript-eslint/no-unused-vars": [
        "error",
        { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
      ],
      "@typescript-eslint/consistent-type-imports": [
        "error",
        { prefer: "type-imports", fixStyle: "separate-type-imports" },
      ],
      "prefer-const": "error",
      "no-var": "error",
    },
  },
];
```

### `src/library.ts`

```typescript
import { base } from "./base";
import type { Linter } from "eslint";

export const library: Linter.Config[] = [
  ...base,
  {
    rules: {
      "@typescript-eslint/explicit-function-return-type": [
        "warn",
        { allowExpressions: true },
      ],
    },
  },
];
```

### `src/nextjs.ts`

```typescript
import { base } from "./base";
import type { Linter } from "eslint";

export const nextjs: Linter.Config[] = [
  ...base,
  {
    settings: {
      react: {
        version: "detect",
      },
    },
    rules: {
      "@typescript-eslint/no-misused-promises": [
        "error",
        { checksVoidReturn: { attributes: false } },
      ],
    },
  },
];
```

### `src/index.ts`

```typescript
export { base } from "./base";
export { library } from "./library";
export { nextjs } from "./nextjs";
```

***

## `packages/ui/`

### `package.json`

```jsonc
{
  "name": "@gotts.ai/ui",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "default": "./src/index.ts",
    },
    "./*": {
      "types": "./src/*.tsx",
      "default": "./src/*.tsx",
    },
    "./styles": "./src/styles.css",
  },
  "dependencies": {
    "react": "^19.0.0",
  },
  "devDependencies": {
    "@gotts.ai/typescript-config": "workspace:*",
    "@types/react": "^19.0.0",
    "typescript": "^5.8.0",
  },
}
```

### `tsconfig.json`

```jsonc
{
  "extends": "@gotts.ai/typescript-config/base.json",
  "compilerOptions": {
    "jsx": "react-jsx",
  },
  "include": ["src"],
  "exclude": ["node_modules"],
}
```

***

## Published Package Template

Template for `packages/safe/`, `packages/vault/`, `packages/agent-proxy/`:

### `package.json`

```jsonc
{
  "name": "@gotts.ai/safe",
  "version": "0.1.0",
  "type": "module",
  "description": "Gotts Safe — Unified MCP server for Uniswap",
  "license": "MIT",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js",
      },
      "require": {
        "types": "./dist/index.d.cts",
        "default": "./dist/index.cjs",
      },
    },
  },
  "files": ["dist", "README.md", "LICENSE"],
  "scripts": {
    "build": "tsdown",
    "dev": "tsdown --watch",
    "check-types": "tsc --noEmit",
    "clean": "rm -rf dist .turbo",
    "lint": "eslint .",
    "test": "vitest run",
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "viem": "^2.30.0",
    "zod": "^3.23.0",
  },
  "devDependencies": {
    "@gotts.ai/eslint-config": "workspace:*",
    "@gotts.ai/typescript-config": "workspace:*",
    "tsdown": "^0.8.0",
    "typescript": "^5.8.0",
    "vitest": "^4.0.0",
  },
  "engines": {
    "node": ">=20.0.0",
  },
  "publishConfig": {
    "access": "public",
    "provenance": true,
  },
}
```

### `tsconfig.json`

```jsonc
{
  "extends": "@gotts.ai/typescript-config/library.json",
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist", "test"],
}
```

### `tsdown.config.ts`

```typescript
import { defineConfig } from "tsdown";

export default defineConfig({
  entry: ["src/index.ts"],
  format: ["esm", "cjs"],
  dts: true,
  clean: true,
  sourcemap: true,
  outDir: "dist",
});
```

### `vitest.config.ts`

```typescript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    name: "safe",
    environment: "node",
    include: ["test/**/*.test.ts"],
    globals: false,
    coverage: {
      provider: "v8",
      include: ["src/**/*.ts"],
      exclude: ["src/**/*.d.ts", "src/**/index.ts"],
      thresholds: {
        statements: 80,
        branches: 80,
        functions: 80,
        lines: 80,
      },
    },
  },
});
```

### `eslint.config.ts`

```typescript
import { library } from "@gotts.ai/eslint-config";

export default [
  ...library,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
];
```

***

## `apps/web/`

### `package.json`

```jsonc
{
  "name": "web",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "eslint .",
    "check-types": "tsc --noEmit",
  },
  "dependencies": {
    "@gotts.ai/ui": "workspace:*",
    "next": "^15.5.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
  },
  "devDependencies": {
    "@gotts.ai/eslint-config": "workspace:*",
    "@gotts.ai/typescript-config": "workspace:*",
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0",
    "typescript": "^5.8.0",
  },
}
```

### `next.config.ts`

```typescript
import type { NextConfig } from "next";

const config: NextConfig = {
  reactStrictMode: true,
  transpilePackages: ["@gotts.ai/ui"],
};

export default config;
```

### `tsconfig.json`

```jsonc
{
  "extends": "@gotts.ai/typescript-config/nextjs.json",
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
    },
  },
  "include": ["src", "next-env.d.ts", ".next/types/**/*.ts"],
  "exclude": ["node_modules"],
}
```

### `tailwind.css`

```css
@import "tailwindcss";
@import "@gotts.ai/ui/styles";

@theme {
  --color-brand-50: #fef2f8;
  --color-brand-100: #fce7f3;
  --color-brand-500: #ec4899;
  --color-brand-600: #db2777;
  --color-brand-700: #be185d;
  --color-brand-900: #831843;

  --color-background: var(--color-white);
  --color-foreground: var(--color-gray-950);
  --color-muted: var(--color-gray-100);
  --color-muted-foreground: var(--color-gray-500);
  --color-border: var(--color-gray-200);
  --color-ring: var(--color-brand-500);

  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  --radius-sm: 0.25rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
}

@media (prefers-color-scheme: dark) {
  @theme {
    --color-background: var(--color-gray-950);
    --color-foreground: var(--color-gray-50);
    --color-muted: var(--color-gray-900);
    --color-muted-foreground: var(--color-gray-400);
    --color-border: var(--color-gray-800);
  }
}
```

### `eslint.config.ts`

```typescript
import { nextjs } from "@gotts.ai/eslint-config";

export default [
  ...nextjs,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
];
```

### `components.json`

```jsonc
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "tailwind.css",
    "baseColor": "gray",
    "cssVariables": true,
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks",
  },
}
```
