# @codelifter/cli

> Surface 3/8 — automation lane. Hosts the MCP server, handles batch/diff/watch.

The CLI is the automation surface for [Codelifter](https://codelifter.vercel.app). It runs the same DOM → React/Vue/Svelte extraction engine as the [Browser Extension](https://chromewebstore.google.com/), but from your terminal — so it can run in CI, cron, headless servers, or as a host process for an MCP server that AI editors talk to. `batch`/`diff`/`watch` ship in v1.0.3 for production-page regression detection.

---

## Why CLI?

The Codelifter browser extension is a one-click GUI — perfect for click users. But there are workflows that the extension cannot reach:

- **CI / GitHub Actions** — your runner is headless, has no clicks, no profile.
- **Cron / scheduled scrapes** — you want a daily snapshot of `stripe.com/payments`, not a manual click.
- **Shell pipelines** — you want `codelifter extract <url> | jq '.extractionResult.detectedLibraries[].name'` in a one-liner.
- **MCP host process** — Claude Code, Cursor, Zed, and Neovim talk to local stdio MCP servers; the extension can't be one. The CLI hosts `codelifter mcp-stdio` for them.
- **Behind-auth pages** — `--use-my-chrome` reuses your authenticated Chrome session via CDP 9222, something the extension can't expose to a script.

Same engine, same Tier 2 component-library detection (shadcn/ui, Radix, MUI, …), same pairing token — just a different entry point.

---

## Install

```bash
npm install -g @codelifter/cli
# 또는 일회성
npx @codelifter/cli <command>
```

설치 시 Playwright Chromium (~150MB)이 자동으로 다운로드됩니다.

---

## Quickstart

### Authentication

```bash
codelifter login --api-key <your-key>
```

### Extract UI

```bash
# 기본 (확장 브리지 자동 감지 → headless fallback)
codelifter extract https://example.com

# 파일로 저장
codelifter extract https://example.com -o result.json

# 특정 요소만 추출
codelifter extract https://example.com -s ".hero-section"

# 내 Chrome 으로 추출 (behind-auth 사이트)
codelifter extract https://app.example.com --use-my-chrome
```

### Pipeline modes

| 모드 | 트리거 | Tier 2 보존율 |
|------|--------|-------------|
| `extension` | Codelifter 확장 MCP 서버 감지 | 100% |
| `headless-bundled` | 기본 headless + 확장 번들 | ~95% |
| `headless-remote` | `--use-my-chrome` | 100% (세션 포함) |

### Framework 옵션

```bash
codelifter extract <url> -f react        # default
codelifter extract <url> -f vue
codelifter extract <url> -f svelte
codelifter extract <url> -f react-native # SDK adapter 사용 권장 (CLI 는 react JSON 만 반환)
codelifter extract <url> -f flutter      # SDK adapter 사용 권장 (CLI 는 react JSON 만 반환)
```

| Framework | 백엔드 처리 | 클라이언트 변환 |
|-----------|-----------|---------------|
| `react` / `vue` / `svelte` | 직접 변환 | 없음 |
| `react-native` / `flutter` | `react` 로 추출 | SDK adapter 가 후처리 (`@codelifter/sdk` 사용) |

CLI 안에서는 RN/Flutter 시 raw JSON 만 출력합니다. `.tsx`/`.dart` 변환을 원하면 SDK 의 `extract()` 를 직접 호출:

```ts
import { extract } from '@codelifter/sdk';
const r = await extract(url, { framework: 'react-native' });
console.log(r.generatedFiles?.[0]?.content); // RN .tsx
```

### MCP server (Claude Code / Cursor / Zed / Neovim)

```bash
# Claude Code 에 MCP 서버 등록 (stdio transport — 권장)
claude mcp add codelifter --transport stdio -- codelifter mcp-stdio

# Zed, Neovim 등 stdio-only 클라이언트는 직접 실행
codelifter mcp-stdio
```

Codelifter 확장을 열면 자동으로 내장 WebSocket 서버에 연결됩니다. 확장이 연결되면 `extension` 파이프라인(100% Tier 2 보존)으로 동작하고, 연결되지 않으면 `headless-bundled`로 fallback 합니다.

### Commands

```bash
codelifter login              # API 키 저장
codelifter extract <url>      # UI 추출
codelifter batch <urls.txt>   # 줄 단위 URL 병렬 추출 (CI 회귀 검증용)
codelifter diff <a> <b>       # 두 추출 결과 JSON 비교 (DOM/Tier2/style)
codelifter watch <url>        # interval 마다 재추출하여 변화 감지 (stub)
codelifter install-browser    # Chromium 수동 설치
codelifter connect-my-chrome  # Chrome 원격 디버깅 모드로 실행
codelifter mcp-stdio          # stdio MCP 서버 (Claude Code / Zed / Neovim 등)
```

### batch — CI 회귀 검증

```bash
# urls.txt: 줄당 URL 1 개. # 으로 시작하는 줄은 주석.
echo "https://stripe.com/payments" >> urls.txt
echo "https://stripe.com/pricing"  >> urls.txt

codelifter batch ./urls.txt --concurrency 4 -o ./results/
# 결과: ./results/<hostname>-<pathHash>.json + ./results/errors.txt
# 실패 1 건 이상이면 exit 1 (CI gate 친화).
```

### diff — DOM/Tier 2/style 변화 리포트

```bash
codelifter diff ./results/baseline.json ./results/current.json
# 또는 JSON
codelifter diff ./baseline.json ./current.json --format json
# Tier 2 라이브러리가 제거되면 exit 1 (regression gate).
```

### watch — 변화 감지 (stub, v1.0.5 webhook 백로그)

```bash
codelifter watch https://stripe.com/payments --interval 1d --state ./.codelifter/state.json
# cron 친화: --once 로 한 번만 실행 후 종료
codelifter watch https://stripe.com/payments --once --state ./state.json
```

---

## How to get the pairing token

CLI/SDK/Skill/MCP 모든 접점이 **하나의 페어링 토큰**을 공유합니다. 토큰은 Browser Extension 안에서만 발급되며, CLI/SDK 등은 환경변수 또는 config 파일로 받습니다.

1. **Browser Extension 열기** — 툴바의 Codelifter 아이콘 클릭, 사이드 패널의 Settings 탭으로 이동.
2. **Developer integrations 섹션 펼치기** — "MCP server" 카드.
3. **"Enable MCP server" 토글 ON** — 토큰이 자동 생성됩니다.
4. **64자 토큰 표시** — "Show pairing token" 버튼으로 마스킹 해제. 옆의 복사 버튼으로 클립보드에 복사.
5. **CLI 에 전달** — 다음 두 방법 중 하나:

   ```bash
   # 방법 1: 환경변수 (단발성)
   export CODELIFTER_MCP_TOKEN=<pasted-64-char-token>
   codelifter mcp-stdio

   # 방법 2: config 파일 (영구)
   mkdir -p ~/.config/codelifter
   echo "<pasted-64-char-token>" > ~/.config/codelifter/pairing.token
   chmod 600 ~/.config/codelifter/pairing.token
   ```

> **Token regeneration**: Extension 설정에서 "Regenerate" 누르면 즉시 새 토큰이 생성되고 기존 연결이 모두 끊깁니다. CLI 측 환경변수/config 도 다시 갱신해야 합니다.

> **Security**: 토큰은 Codelifter 서버에 절대 전송되지 않습니다. 로컬 WebSocket 핸드쉐이크에만 사용되며, MCP 서버는 `127.0.0.1` 만 listen 합니다.

---

## Environment variables

| Variable | Purpose | Default |
|---|---|---|
| `CODELIFTER_MCP_TOKEN` | Browser Extension 과 페어링하는 64자 토큰 (위의 "How to get the pairing token" 참고) | `~/.config/codelifter/pairing.token` 파일 fallback |
| `CODELIFTER_API_KEY` | Codelifter 서버 API 키 (`codelifter login` 의 환경변수 대체) | — (login 명령 또는 `~/.config/codelifter/config.json`) |
| `CODELIFTER_API_URL` | Codelifter 서버 base URL (자체 호스팅 또는 staging 용) | `https://codelifter.vercel.app` |
| `CODELIFTER_EXTENSION_PATH` | Playwright 가 로드할 확장 번들 경로 오버라이드 (테스트용) | bundled extension |
| `CODELIFTER_MCP_WS_URL` | MCP WebSocket 엔드포인트 (테스트용) | `ws://127.0.0.1:12307` |
| `CODELIFTER_ALLOW_ORIGINS` | MCP 서버 가 허용하는 Origin allowlist (콤마 구분) | `chrome-extension://{ext-id}` |
| `CODELIFTER_SKIP_BROWSER_INSTALL` | `1` 설정 시 postinstall Chromium 다운로드 건너뜀 | `0` (다운로드함) |

---

## Related surfaces (8개 모두 Live)

- **Browser Extension** (Surface 1/8) — 클릭 사용자 진입점. CLI 가 제공하는 100% Tier 2 보존의 원천.
- **MCP Server** (Surface 2/8) — `codelifter mcp-stdio` 가 그 자체로 호스팅하는 stdio MCP 서버.
- **SDK** (`@codelifter/sdk`, Surface 4/8) — 빌더가 자기 도구에 박는 high-level API. CLI lib 을 internal 의존으로 wrap.
- **Claude Code Skill** (Surface 5/8) — `/codelifter` 슬래시. 클립보드 또는 MCP 결과를 `.tsx` 로 변환.
- **VSCode / Cursor Extension** (Surface 6/8) — Command Palette 의 `Codelifter: Extract from URL`. SDK 위에 박혀 동일 엔진 사용.
- **Figma Plugin** (Surface 7/8) — 라이브 URL 을 Figma frame 으로 lift. 동일 페어링 토큰 공유.
- **Raycast Extension** (Surface 8/8) — Cmd+Space → `lift <url>` → 클립보드 React. SDK backbone.
