Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6b09bfe
Fix fingerprint detection gaps: broader token matching, filled embedd…
nahiyankhan Apr 10, 2026
ee0d496
Bulletproof fingerprint detection: color parsing, normalization, sema…
nahiyankhan Apr 13, 2026
9c69b43
Ghost v2: universal AI-native design fingerprinting
nahiyankhan Apr 13, 2026
b1b9738
Add live integration tests for real design systems
nahiyankhan Apr 13, 2026
38dae5c
LLM-first pipeline: drop deterministic parsing, go fully agentic
nahiyankhan Apr 13, 2026
0653e33
Explicit target prefixes: github:, npm:, path:, url:, figma:
nahiyankhan Apr 13, 2026
8dec580
iOS/SwiftUI platform support: cross-platform fingerprinting
nahiyankhan Apr 13, 2026
4feafdd
Architecture refactor: stages, signal extractors, tool use, agent skills
nahiyankhan Apr 13, 2026
400a2a9
Fix signal extraction: registry CSS parsing, sampler budget, pill radii
nahiyankhan Apr 13, 2026
cd9a061
Fix parallel profiling: fresh agent per profile, stable interpret path
nahiyankhan Apr 13, 2026
4ca3e3e
Deterministic oklch, role-based color matching, visual-only distance
nahiyankhan Apr 13, 2026
44b7c97
Remove deterministic signals layer: LLM interprets raw files directly
nahiyankhan Apr 14, 2026
729fc22
Agent SDK fingerprinting: replace prompt-stuffing with filesystem exp…
nahiyankhan Apr 14, 2026
3f9bce3
Add canonical fingerprint for ghost-ui design language
nahiyankhan Apr 14, 2026
41d042a
Increase fingerprint agent max turns to 60 and add package-lock
nahiyankhan Apr 14, 2026
e88c72e
Add CLAUDE.md and update docs to match current architecture
nahiyankhan Apr 14, 2026
e9753cc
Add ghost review: LLM-powered design drift detection on changed files
nahiyankhan Apr 15, 2026
a1a8128
Fix CI: resolve biome platform binaries, lint fixes, remove --deep flag
nahiyankhan Apr 15, 2026
4996adc
Fix all biome lint and format errors across codebase
nahiyankhan Apr 15, 2026
00f5b52
Fix CI: update biome schema, extract review command, add file size ex…
nahiyankhan Apr 15, 2026
4d5bde9
Fix formatting in review-command.ts and check-file-sizes.mjs
nahiyankhan Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ dist
.DS_Store
.claude/settings.local.json
packages/ghost-ui/public/r/
.env
.env.local
packages/ghost-ui/.ghost/
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
shamefully-hoist=false
strict-peer-dependencies=true
@anthropic-ai:registry=https://registry.npmjs.org
112 changes: 112 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Ghost — Agent Context

## Build & Run

```bash
pnpm install # install dependencies (pnpm 10+, Node 18+)
pnpm build # build all packages (tsc --build)
```

Run the CLI after building:

```bash
node packages/ghost-cli/dist/bin.js <command>
# or
pnpm --filter ghost-cli exec ghost <command>
```

## Environment Variables

- `ANTHROPIC_API_KEY` — required for AI-powered profiling (`--ai` flag) and LLM agents
- `OPENAI_API_KEY` — alternative LLM provider
- `GITHUB_TOKEN` — optional, for GitHub target resolution and discovery (avoids rate limits)

The CLI auto-loads `.env` and `.env.local` from the working directory.

## Test & Lint

```bash
pnpm test # vitest run
pnpm test:watch # vitest watch mode
pnpm check # biome check + typecheck + file-size check
pnpm fmt # biome format --write
pnpm lint # biome lint
```

Pre-commit hook (lefthook): `biome format --write`, `biome check --fix`, `just check`.
Pre-push hook: `just check`, `just test`, `just build` (parallel).

## Justfile

Run `just` to list all recipes. Key ones: `setup`, `build`, `check`, `fmt`, `test`, `dev` (ghost-ui catalogue), `build-ui`, `build-registry`, `clean`, `ci`.

## Architecture

**Director** (`packages/ghost-core/src/agents/director.ts`) orchestrates the pipeline:

- **Stages** (`packages/ghost-core/src/stages/`) — deterministic async functions: `extract`, `compare`, `comply`
- **Agents** (`packages/ghost-core/src/agents/`) — LLM-powered steps: `FingerprintAgent`, `DiscoveryAgent`, `ComparisonAgent`, `ComplianceAgent`, `ExtractionAgent`

Typical pipeline: `target → extract (stage) → fingerprint (agent) → compare/comply (stage)`

## Packages

| Package | Description |
|---------|-------------|
| `packages/ghost-core` | Core library: agents, stages, fingerprinting, scanners, extractors, evolution, LLM providers, reporters |
| `packages/ghost-cli` | CLI (citty-based), 12 subcommands |
| `packages/ghost-ui` | Reference design language — 97 shadcn-compatible components, design tokens, live catalogue |
| `packages/ghost-mcp` | MCP server exposing Ghost UI registry to AI assistants (6 tools, 2 resources) |
| `action/` | GitHub Action for automated PR design review |

## CLI Commands

| Command | Description |
|---------|-------------|
| `ghost review [files]` | Review files for visual language drift against a fingerprint (zero-config) |
| `ghost scan` | Scan for design drift (requires `ghost.config.ts`) |
| `ghost profile [target]` | Generate a fingerprint — accepts paths, `github:owner/repo`, `npm:package`, URLs |
| `ghost compare <a.json> <b.json>` | Compare two fingerprint JSON files |
| `ghost diff [component]` | Compare local components against registry |
| `ghost comply [target]` | Check compliance; `--against parent.json` for drift checking |
| `ghost discover [query]` | Find public design systems |
| `ghost fleet <a.json> <b.json> ...` | Ecosystem-level comparison (2+ fingerprint files) |
| `ghost ack` | Acknowledge drift, record stance (aligned/accepted/diverging) |
| `ghost adopt <fingerprint.json>` | Adopt a new parent baseline |
| `ghost diverge <dimension>` | Declare intentional divergence with reasoning |
| `ghost viz <a.json> <b.json> ...` | 3D fingerprint visualization (Three.js) |

## Target Types

The `resolveTarget()` function in `packages/ghost-core/src/config.ts` accepts:

- `github:owner/repo` — GitHub repository
- `npm:package-name` — npm package
- `figma:file-url` — Figma file
- `./path` or `/absolute/path` — local directory
- `https://...` — URL
- `.` — current directory (default for `profile` and `comply`)

Use explicit prefixes when the input is ambiguous.

## Review Pipeline

The `review` module (`packages/ghost-core/src/review/`) provides fingerprint-informed design review:

- **matcher.ts** — deterministic scan: match hardcoded values against fingerprint palette/spacing/typography/surfaces
- **deep-review.ts** — LLM-powered nuanced drift detection (optional, `--deep` flag)
- **file-collector.ts** — git diff parsing to resolve changed files and line numbers
- **pipeline.ts** — orchestrates: resolve fingerprint → collect files → match → (optional) deep review → report

Zero-config: `ghost review` looks for `.ghost-fingerprint.json` in cwd. Generate with `ghost profile . --emit`.

## Key Conventions

- Fingerprints are 64-dimensional vectors stored as JSON (`DesignFingerprint` type)
- `compare`, `fleet`, and `viz` commands take **file paths** to fingerprint JSON, not target strings
- `profile` outputs fingerprints; pipe to `--output <file>` to save for later comparison
- `--against` on `comply` takes a **file path** to a parent fingerprint JSON
- `--ai` enables LLM-powered enrichment on `profile`; `--verbose` shows agent reasoning
- `review` reads `.ghost-fingerprint.json` by default; `--fingerprint <path>` overrides
- `review --deep` requires `ANTHROPIC_API_KEY` for LLM-powered nuanced analysis
- `review --staged` checks only staged changes; `--base main` diffs against a branch
148 changes: 118 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,51 @@ pnpm build

### Quick Start

**Scan for drift:**
**Profile a design system:**

```bash
ghost scan --config ghost.config.ts
```
# Profile the current directory
ghost profile .

**Generate a design fingerprint:**
# Profile a GitHub repo
ghost profile github:shadcn-ui/ui

```bash
ghost profile --config ghost.config.ts
# or from a shadcn registry directly
# Profile with AI enrichment (requires ANTHROPIC_API_KEY or OPENAI_API_KEY)
ghost profile github:shadcn-ui/ui --ai --verbose

# Profile a shadcn registry directly
ghost profile --registry https://ui.shadcn.com/registry.json

# Save fingerprint to a file
ghost profile . --output my-system.json
```

**Compare two fingerprints:**

```bash
ghost compare system-a.json system-b.json
# Profile two systems, then compare
ghost profile github:shadcn-ui/ui --output shadcn.json
ghost profile npm:@chakra-ui/react --output chakra.json
ghost compare shadcn.json chakra.json
```

**Check compliance against a parent:**

```bash
ghost comply . --against parent-fingerprint.json
ghost comply . --against parent-fingerprint.json --format sarif
```

**Visualize a fleet:**
**Scan for drift (config-based):**

```bash
ghost scan --config ghost.config.ts
```

**Fleet observability and visualization:**

```bash
ghost fleet system-a.json system-b.json system-c.json --cluster
ghost viz system-a.json system-b.json system-c.json
```

Expand All @@ -67,46 +89,86 @@ just dev

## CLI Commands

| Command | Description |
| --------------- | ---------------------------------------------------------------------------- |
| `ghost scan` | Detect design drift against a registry |
| `ghost profile` | Generate a design fingerprint from a registry, codebase, or via LLM |
| `ghost compare` | Compare two fingerprints with optional temporal analysis |
| `ghost ack` | Acknowledge current drift and publish a stance (aligned, accepted, diverging) |
| `ghost adopt` | Shift parent baseline to a new fingerprint |
| `ghost diverge` | Mark a fingerprint dimension as intentionally diverging with reasoning |
| `ghost fleet` | Compare N fingerprints for ecosystem-wide observability |
| `ghost viz` | Launch interactive 3D fingerprint visualization |
| Command | Description |
| ---------------- | -------------------------------------------------------------------------------- |
| `ghost scan` | Scan for design drift against a registry |
| `ghost profile` | Generate a fingerprint for any target (directory, URL, npm package, GitHub repo) |
| `ghost compare` | Compare two fingerprint JSON files with optional temporal analysis |
| `ghost diff` | Compare local components against registry with drift analysis |
| `ghost comply` | Check design system compliance against rules and a parent fingerprint |
| `ghost discover` | Find public design systems matching a query |
| `ghost ack` | Acknowledge current drift — record intentional stance toward parent |
| `ghost adopt` | Shift parent baseline to a new fingerprint |
| `ghost diverge` | Declare intentional divergence on a dimension with reasoning |
| `ghost fleet` | Compare N fingerprint files for ecosystem-level observability |
| `ghost viz` | Launch interactive 3D fingerprint visualization |

### Target Types

`ghost profile` and `ghost comply` accept universal targets:

```bash
ghost profile . # current directory
ghost profile ./path/to/project # local path
ghost profile github:shadcn-ui/ui # GitHub repo
ghost profile npm:@chakra-ui/react # npm package
ghost profile https://example.com # URL
ghost profile --registry registry.json # shadcn registry directly
```

Use explicit prefixes (`github:`, `npm:`, `figma:`, `path:`, `url:`) when the input is ambiguous.

## Configuration

Create a `ghost.config.ts` in your project root:
Optionally create a `ghost.config.ts` in your project root to configure scanning targets, rules, and LLM settings.

```typescript
import { defineConfig } from "@ghost/core";

export default defineConfig({
parent: "default",
designSystems: [
{
name: "my-ui",
registry: "https://ui.shadcn.com/registry.json",
componentDir: "components/ui",
styleEntry: "src/styles/main.css",
},
// Parent design system to check drift against
parent: { type: "github", value: "shadcn-ui/ui" },

// Targets to scan
targets: [
{ type: "path", value: "./packages/my-ui" },
],

scan: {
values: true,
structure: true,
visual: false,
analysis: false,
},

rules: {
"hardcoded-color": "error",
"token-override": "warn",
"missing-token": "warn",
"structural-divergence": "warn",
"structural-divergence": "error",
"missing-component": "warn",
"visual-regression": "warn",
},

ignore: [],

// LLM provider for AI-powered profiling (optional)
llm: {
provider: "anthropic",
// model: "claude-sonnet-4-20250514", // optional override
// apiKey: "..." // defaults to ANTHROPIC_API_KEY env var
},

// Embedding provider for semantic comparison (optional)
// embedding: {
// provider: "openai",
// },

// Agent settings (optional)
// agents: {
// maxIterations: 40,
// verbose: true,
// },
});
```

Expand Down Expand Up @@ -187,22 +249,43 @@ just build-ui
just build-registry
```

## Ghost MCP

Ghost MCP (`@ghost/mcp`) is a Model Context Protocol server that exposes the Ghost UI registry to AI assistants.

**Tools:** `search_components`, `get_component`, `get_install_command`, `list_categories`, `get_theme`

**Resources:** `ghost://registry` (full registry JSON), `ghost://skills` (skill docs)

```bash
# Run the MCP server (stdio transport)
node packages/ghost-mcp/dist/bin.js
```

## Project Structure

```
packages/
ghost-core/ Core library
src/
agents/ Director, FingerprintAgent, DiscoveryAgent, ComparisonAgent, ComplianceAgent
stages/ Deterministic pipeline stages (extract, compare, comply)
fingerprint/ Fingerprinting engine (embedding, comparison, extraction)
evolution/ Evolution tracking (sync, temporal, fleet, history)
scanners/ Drift scanners (values, structure, visual)
extractors/ Material extraction (CSS, Tailwind)
resolvers/ Registry and CSS resolution
llm/ LLM providers (Anthropic, OpenAI)
reporters/ Output formatting (CLI, JSON, fingerprint, fleet)
ghost-cli/ CLI interface
ghost-cli/ CLI interface (citty)
src/
bin.ts Command definitions (scan, profile, compare, diff, comply, discover, etc.)
evolution-commands.ts ack, adopt, diverge, fleet commands
viz/ 3D visualization (Three.js, PCA projection)
ghost-mcp/ MCP server for Ghost UI registry
src/
tools.ts 5 MCP tools (search, get, install, categories, theme)
resources.ts 2 MCP resources (registry, skills)
ghost-ui/ Reference design language (@ghost/ui)
src/
components/
Expand All @@ -217,6 +300,11 @@ packages/
styles/ Design tokens and global CSS
fonts/ HK Grotesk woff2 files
registry.json shadcn-compatible component registry
skills/ Claude Code skill definitions
ghost-fingerprint/ Profile any design system
ghost-compare/ Compare two design systems
ghost-drift-check/ Check design compliance
ghost-discover/ Find public design systems
```

## Development
Expand Down
37 changes: 37 additions & 0 deletions action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: "Ghost Design Review"
description: "Review pull requests for visual language drift against a design fingerprint"
author: "Ghost"

inputs:
github-token:
description: "GitHub token for posting review comments"
required: true
default: ${{ github.token }}
fingerprint:
description: "Path to fingerprint JSON file"
required: false
default: ".ghost-fingerprint.json"
anthropic-api-key:
description: "Anthropic API key (or set ANTHROPIC_API_KEY env var)"
required: false
dimensions:
description: "Comma-separated dimensions to check: palette,spacing,typography,surfaces"
required: false
base:
description: "Base ref for diff"
required: false
default: ${{ github.event.pull_request.base.sha }}

outputs:
issues-found:
description: "Number of issues found"
has-errors:
description: "Whether any errors were found (true/false)"

runs:
using: "node20"
main: "dist/index.js"

branding:
icon: "eye"
color: "purple"
Loading
Loading