# Project Detection

The `@xtarterize/core` package provides the `detectProject()` function — the foundation of xtarterize's context-aware behavior. It analyzes your project directory to build a [`ProjectProfile`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts) that drives which conformance tasks are applicable.

`detectProject()` now acts as an orchestration layer in [`packages/core/src/detect.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts), while concrete detection adapters live in [`packages/core/src/detect/`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/core/src/detect) (framework, bundler, router, styling, package manager, and monorepo).

## Overview

Project detection is the first step in every xtarterize command. It analyzes your project directory to build a `ProjectProfile` that drives which conformance tasks are applicable.

### Profile caching

Detection results are cached to avoid redundant I/O on repeated invocations. The cache is stored in `.xtarterize/cache/profile-fingerprint.json` and keyed by a fingerprint of `package.json`, lockfile, and config directories (`.github/`, `.vscode/`, `.changeset/`).

The cache is invalidated when any of these inputs change (mtime or size). Corrupt or missing cache files fall through to full re-computation — the cache is always best-effort. A cache hit typically completes in under 1ms vs 50-150ms for a full detection run.

See the file `docs/ADRs/xtarterize/021-fingerprint-profile-caching.md` for the full design.

## detectProject Function

```typescript
import { detectProject } from '@xtarterize/core'

const profile = await detectProject('/path/to/project')
```

## ProjectProfile Schema

The detection returns a `ProjectProfile` object:

```typescript
interface ProjectProfile {
  // Framework
  framework: 'react' | 'react-native' | 'vue' | 'svelte' | 'solid' | 'node' | null
  frameworkVersion: string | null

  // Bundler
  bundler: 'vite' | 'nextjs' | 'tanstack-start' | 'expo' | 'webpack' | 'rspack' | 'none' | null

  // Router
  router: 'tanstack-router' | 'react-router' | 'next' | 'expo-router' | 'vue-router' | null

  // Styling
  styling: ('tailwind' | 'css-modules' | 'styled-components' | 'vanilla-extract' | 'nativewind' | 'vanilla')[]

  // Language & Runtime
  typescript: boolean
  runtime: 'browser' | 'node' | 'edge' | 'native' | 'universal'

  // Package manager
  packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun'

  // Repo structure
  monorepo: boolean
  monorepoTool: 'turbo' | 'nx' | 'lerna' | null
  workspaceRoot: boolean

  // Git
  hasGitHub: boolean
  hasGit: boolean

  // Existing config presence
  existing: {
    biome: boolean
    tsconfig: boolean
    renovate: boolean
    commitlint: boolean
    knip: boolean
    plop: boolean
    turbo: boolean
    vscodeSettings: boolean
    agentsMd: boolean
    githubWorkflows: string[]
    viteConfig: boolean
    versionrc: boolean
    gitignore: boolean
  }
}
```

## Detection Logic

### Detection modules

- [`framework.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/framework.ts) — framework/runtime/vite-plus detection
- [`bundler.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/bundler.ts) — bundler detection from deps and config files
- [`router.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/router.ts) — router detection from bundler + deps
- [`styling.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/styling.ts) — styling solution detection
- [`package-manager.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/package-manager.ts) — lockfile/nypm package manager detection
- [`monorepo.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/monorepo.ts) — workspace/monorepo detection
- [`types.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/types.ts) + [`utils.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/utils.ts) — shared detection types and guards

```mermaid
flowchart TD
    A[package.json] --> B{Dependencies}
    B --> C[detectFramework]
    B --> D[detectBundler]
    B --> E[detectRouter]
    B --> F[detectStyling]
    B --> G[detectVitePlus]
    
    C --> H{Framework?}
    H -->|"react-native + react"| I["Ambiguous → prompt user"]
    H -->|react| J["Framework: react"]
    H -->|vue| K["Framework: vue"]
    H -->|svelte| L["Framework: svelte"]
    H -->|solid| M["Framework: solid"]
    H -->|node| N["Framework: node"]
    
    D --> O{Bundler?}
    O -->|"@tanstack/start"| P["TanStack Start"]
    O -->|next| Q["Next.js"]
    O -->|expo| R["Expo"]
    O -->|vite| S["Vite"]
    O -->|webpack| T["Webpack"]
    O -->|"@rspack/core"| U["Rspack"]
    O -->|none| V["None"]
    
    E --> W{Router?}
    W -->|"nextjs bundler"| X["Next Router"]
    W -->|"expo bundler"| Y["Expo Router"]
    W -->|"@tanstack/react-router"| Z["TanStack Router"]
    W -->|react-router| AA["React Router"]
    W -->|vue-router| AB["Vue Router"]
    
    style A fill:#6366f1,color:#fff
    style C fill:#22c55e,color:#fff
    style D fill:#22c55e,color:#fff
```

## Detection Sources

| Signal | Source |
    |--------|--------|
    | Framework | [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) dependencies ([`react`](https://react.dev/), [`vue`](https://vuejs.org/), [`react-native`](https://reactnative.dev/), etc.) |
    | Bundler | [`vite`](https://vitejs.dev/), [`next`](https://nextjs.org/), [`expo`](https://expo.dev/), [`webpack`](https://webpack.js.org/), [`@rspack/core`](https://rspack.dev/) in deps |
    | Router | [`@tanstack/react-router`](https://tanstack.com/router/latest), [`react-router-dom`](https://reactrouter.com/), [`vue-router`](https://router.vuejs.org/) in deps |
    | Styling | [`tailwindcss`](https://tailwindcss.com/), [`styled-components`](https://styled-components.com/), [`nativewind`](https://www.nativewind.dev/) in deps |
  | Signal | Source |
    |--------|--------|
    | TypeScript | [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) existence, `typescript` in deps |
    | Package manager | Lockfile presence ([`pnpm-lock.yaml`](https://pnpm.io/), [`yarn.lock`](https://yarnpkg.com/), etc.) |
    | Monorepo | [`pnpm-workspace.yaml`](https://pnpm.io/workspaces), [`turbo.json`](https://turbo.build/repo/docs), `packages/` + `apps/` dirs |
    | GitHub | [`.github/`](https://docs.github.com/en/actions) directory presence |
  ## Ambiguity Handling
**Note:** When both `react` and `react-native` are present in dependencies, `detectProject()` returns `framework: null`. The CLI layer then prompts the user to clarify which describes the project. In `--quiet` mode, it defaults to `react`.

## Example

```typescript
const profile = await detectProject('/path/to/project')

if (profile.bundler === 'vite' && profile.typescript) {
  // Vite plugin tasks will be applicable
}

if (profile.monorepo && profile.monorepoTool === 'turbo') {
  // Turbo task may be skip if already configured
}
```

## References

- [npm package.json Documentation](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) — Package manifest format
- [React](https://react.dev/) — UI library for web and native apps
- [Vue.js](https://vuejs.org/) — Progressive JavaScript framework
- [React Native](https://reactnative.dev/) — Native app development with React
- [Vite](https://vitejs.dev/) — Next-generation frontend build tool
- [Next.js](https://nextjs.org/) — React framework for production
- [TanStack Router](https://tanstack.com/router/latest) — Type-safe routing for React
- [React Router](https://reactrouter.com/) — Declarative routing for React
- [Vue Router](https://router.vuejs.org/) — Official router for Vue.js
- [Expo](https://expo.dev/) — React Native framework
- [Webpack](https://webpack.js.org/) — Module bundler
- [Rspack](https://rspack.dev/) — Fast Rust-based web bundler
- [Tailwind CSS](https://tailwindcss.com/) — Utility-first CSS framework
- [Styled Components](https://styled-components.com/) — CSS-in-JS for React
- [NativeWind](https://www.nativewind.dev/) — Tailwind CSS for React Native
- [pnpm Workspaces](https://pnpm.io/workspaces) — Monorepo workspace support
- [Turborepo](https://turbo.build/repo/docs) — Monorepo task runner
- [TypeScript tsconfig](https://www.typescriptlang.org/tsconfig/) — Compiler configuration