LT CLI 참조
주의사항
lt fullstack init에--noConfirm을 붙이지 않으면 Claude Code가 영원히 멈춥니다 — 대화형 프롬프트(프로젝트 이름, git init, 템플릿 선택)가 stdin 입력을 기다립니다. Claude Code는 응답할 수 없으며, 세션이 "Unfurling..." 상태에서 멈추고 토큰이 소모되지 않습니다. Claude Code에서 lt CLI를 호출할 때는--noConfirm과 모든 필수 플래그(--name X --frontend nuxt --git false)를 함께 전달하세요.--api-link와--frontend-link는 복사본이 아닌 심볼릭 링크를 생성합니다 — 이 머신 어디에 있든 템플릿 체크아웃(nest-server-starter,nuxt-base-starter)의 변경 사항이 연결된 프로젝트에 즉시 영향을 미칩니다. 이는 프레임워크 개발에 유용한 기능이지만, 복사본을 예상하는 개발자에게는 놀라움을 줄 수 있습니다.--api-link를 사용할 때는 프로젝트 README에 이를 문서화하세요.lt git reset은 파괴적이며 되돌릴 수 없습니다 — CLI 메뉴에서 안전한lt git get옆에 있습니다.reset은git reset --hard를 수행한 후 강제 풀을 실행하여 확인 없이 모든 로컬 변경 사항을 삭제합니다. 푸시되지 않은 작업이 있는 브랜치에서는 절대 실행하지 마세요.git stash+lt git get을 선호합니다.lt server object X --controller는 REST를 생성하며 GraphQL이 아닙니다 — 기본값은 REST입니다. GraphQL 프로젝트에서는--resolver를 사용하세요. CLI는 기존 프로젝트 패턴에서 자동 감지하지 않습니다. 명시적으로 지정해야 합니다.lt fullstack convert-mode는 소스 트리를 다시 작성합니다 —npm과vendor모드 간 전환은 프레임워크 코드를src/core/(API) 또는app/core/(앱) 안팎으로 이동합니다. 이 작업은 되돌릴 수 있지만 실행 중간에는 멱등적이지 않습니다. 항상 시작 전에 커밋하여 실패한 변환을git reset으로 롤백할 수 있도록 하세요.--next는 실험적이며lt server module/object/addProp/test/permissions와 호환되지 않습니다 —lt server create --next또는lt fullstack init --next가 사용되면 API가nest-server-starter대신nest-base(Bun + Prisma 7 + Postgres + Better-Auth)에서 복제됩니다. 다운스트림 생성기는 클래식 nest-server 레이아웃(Mongoose 모델, src/server/modules/ 등)을 대상으로 하며 nest-base 프로젝트에서는 작동하지 않습니다. 새로운 프로토타이핑에만 사용하고, 프로덕션 작업에는 기본 템플릿을 선호합니다.- macOS: 긴
$TMPDIR은lt dev up에서 Nuxt SSR을 중단시킵니다 — macOS에서$TMPDIR은 긴 사용자별 경로(/var/folders/…, 종종 ~49자 이상)입니다. Nuxt 4.4.7의 vite-node는 그 아래에 Unix 도메인 소켓 경로를 구축하는데, 이는 OS 104자 제한을 초과합니다 → SSR이 500 오류로 충돌합니다. 해결 방법: 짧은 tmp 디렉토리로 시작하세요.TMPDIR=/tmp lt dev up. (Linux$TMPDIR=/tmp는 짧으므로 macOS에서만 발생합니다.) - macOS: HMR WebSocket 포트 24678이 병렬
lt dev프로젝트 간에 충돌합니다 — 동시에 실행되는 두 개의lt dev프로젝트가 모두 Vite의 HMR WS 포트 24678에 바인딩하려고 시도합니다.vite.server.hmr.port는 Nuxt 4.4.7에서 무시되므로 구성에서 다시 할당할 수 없습니다. 이는 치명적이지 않습니다 — SSR 재컴파일은 여전히 작동합니다. 두 번째 프로젝트의 라이브 HMR 푸시만 영향을 받습니다. 변경 사항을 적용하려면 페이지를 새로고침하세요.
스킬 경계
| 사용자 의도 | 올바른 스킬 |
|---|---|
| "lt fullstack init" | 이 스킬 |
| "lt git get feature-branch" | 이 스킬 |
| "lt server create my-project" | 이 스킬 |
| "lt server module / object / addProp" | generating-nest-servers |
| "lt server permissions" | generating-nest-servers |
| "Create a NestJS module" | generating-nest-servers |
| "Build a Vue component" | developing-lt-frontend |
| "lt deployment create" | 이 스킬 (lt deployment create 명령어 참조) |
| "TurboOps에 배포 / 라이브 전환 / turbo 배포 / 배포 단계" | deploying-to-turboops |
lt fullstack init 이후:
- 백엔드 작업 (projects/api/) →
generating-nest-servers - 프론트엔드 작업 (projects/app/) →
developing-lt-frontend
명령어
lt git get — 브랜치 체크아웃/생성
lt git get <branch-name> # 별칭: lt git g
- 브랜치가 로컬에 존재함 → 해당 브랜치로 전환
- 브랜치가 원격에 존재함 → 체크아웃하고 추적
- 둘 다 존재하지 않음 → 현재 브랜치에서 새 브랜치 생성
lt git reset — 원격으로 재설정
lt git reset
원격에서 최신 상태를 가져오고, 현재 브랜치를 origin/<branch>로 재설정합니다. 파괴적 — 모든 로컬 변경 사항이 손실됩니다.
lt fullstack init — 전체 스택 워크스페이스 생성
# 비대화형
lt fullstack init --name <Name> --frontend <angular|nuxt> --git <true|false> --noConfirm \
[--git-link <URL>] [--api-link <path>] [--frontend-link <path>] [--next]
| 매개변수 | 필수 | 설명 |
|---|---|---|
--name | 예 | 워크스페이스 이름 (PascalCase) |
--frontend | 예 | angular 또는 nuxt |
--git | 예 | git 초기화: true / false |
--noConfirm | 아니요 | 확인 프롬프트 건너뛰기 |
--git-link | 아니요 | Git 저장소 URL |
--api-branch | 아니요 | nest-server-starter의 브랜치 |
--frontend-branch | 아니요 | 프론트엔드 스타터의 브랜치 |
--api-copy / --api-link | 아니요 | 로컬 API 템플릿 (복사 / 심볼릭 링크) |
--frontend-copy / --frontend-link | 아니요 | 로컬 프론트엔드 템플릿 (복사 / 심볼릭 링크) |
--next | 아니요 | 실험적 — API용 nest-base(Bun + Prisma 7 + Postgres + Better-Auth)를 복제합니다. apiMode = Rest, frameworkMode = npm을 강제하고 워크스페이스 설치를 건너<0xEB><0x8A><0xB0>니다(앱은 pnpm install, api는 bun install을 수동으로 실행). 다운스트림 lt server module/object/addProp/test는 결과 레이아웃과 호환되지 않습니다. |
우선순위: --*-link > --*-copy > --*-branch > 기본값 (GitHub 클론)
생성된 구조:
<workspace>/
├── projects/
│ ├── api/ ← nest-server-starter (또는 --next 사용 시 nest-base)
│ └── app/ ← nuxt-base-starter (또는 ng-base-starter)
├── package.json
└── .gitignore
생성 후:
cd <workspace> && pnpm install
lt dev init # 멱등적: ENV 패치 + 등록; 머신이 아직 설정되지 않은 경우 먼저 `lt dev install`을 자동 실행합니다
lt dev up # Caddy 뒤에서 https://<slug>.localhost 아래에 API + 앱 시작
# --next 사용 시: 서브프로젝트별 설치, 워크스페이스 설치 없음
cd <workspace>/projects/app && pnpm install
cd <workspace>/projects/api && bun install
(lt dev를 사용하지 않는 경우 기본 포트 3000/3001에서 pnpm -r --parallel run start로 대체합니다.)
lt dev — 병렬 프로젝트 오케스트레이션 (Caddy + HTTPS)
모든 lt 프로젝트를 Caddy를 통해 안정적인 HTTPS URL(<slug>.localhost, api.<slug>.localhost)로 제공하여 여러 프로젝트가 3000/3001에서 충돌하지 않고 인증 교차 연결 없이 나란히 실행될 수 있도록 합니다. 모든 lt-모노레포 또는 독립형 API/앱 프로젝트에서 사용하세요.
lt dev install # 머신당 한 번: 전용 LaunchAgent/systemd 유닛 + Caddyfile 스텁 + CA 알림 부트스트랩
lt dev uninstall [--purge] # lt-dev 서비스 제거 (--purge는 Caddyfile + 로그도 삭제)
lt dev init # 프로젝트당 한 번 (멱등적): ENV 패치 + 등록
lt dev up # Caddy 뒤에 API + 앱 시작
lt dev down # 프로세스 중지 + Caddy 블록 제거 (격리된 테스트 스택도 해체)
lt dev test # 격리된 Playwright E2E: 병렬 스택 + 전용 `<slug>-test` DB, 자동 해체
lt dev test --shard # 2개의 격리된 스택에 분할 (기본값 — 안정적인 최적 지점)
lt dev test --shard 3 # N개의 격리된 스택에 분할 (각각 자체 포트/Caddy/DB `<slug>-test-<i>`)
lt dev test --shard auto # 이 머신의 CPU + RAM에서 N 크기 산정 (보수적)
lt dev test down # 격리된 테스트 스택 해체 (잔여물 없음)
lt dev status # 이 프로젝트의 URL + PID + 라이브 업스트림 상태 표시 (테스트 스택 포함)
lt dev status --all # 등록된 모든 프로젝트 + 실행 상태 나열
lt dev doctor # Caddy / CA / DNS / 포트 문제 진단
lt dev tunnel [--api] # 포그라운드 Cloudflare Quick Tunnel: 공개 *.trycloudflare.com URL
각 하위 명령어가 하는 일:
install— 머신당 한 번.caddy가 PATH에 있는지 확인(없으면brew install caddy제안),~/.lenneTech/Caddyfile스텁 생성, 전용 LaunchAgent(macOS,~/Library/LaunchAgents/tech.lenne.lt-dev-caddy.plist) 또는 systemd-user 유닛(Linux) 작성 + 부트스트랩. Caddy 관리 엔드포인트(:2019)가 응답할 때까지 최대 8초 대기, 파일 유효성 검사,sudo -E HOME="$HOME" caddy trust실행을 알림(-E HOME="$HOME"는 필수 — 없으면 sudo가 HOME을/var/root로 전환하고 CA 설치가 조용히 실패합니다).brew services start caddy를 사용하지 않습니다 — 해당 plist는--config /opt/homebrew/etc/Caddyfile을 하드코딩하고 우리 Caddyfile 위치와 충돌하여 크래시 루프에 빠집니다. 자동 체인: 초기화되지 않은 lt-dev 프로젝트 내에서 실행되면 이후init을 실행합니다(--skip-init으로 옵트아웃).uninstall—install의 대칭 대응. LaunchAgent / systemd 유닛을 제거하고 유닛 파일을 삭제합니다.--purge를 사용하면~/.lenneTech/Caddyfile과 caddy 로그도 삭제합니다. caddy 바이너리 자체는 제거하지 않습니다(원하면brew uninstall caddy사용).init(별칭migrate) — 멱등적. 프로젝트 ID를 구축합니다(slug =package.json"name", 모노레포 레이아웃의 서브도메인), 레거시 하드코딩된port: 3000/port: 3001/ Vite-프록시 대상 / Playwright URL을 환경 인식 변형으로 패치(기본값 유지),~/.lenneTech/projects.json에 저장, 모든CLAUDE.md파일에 "Local Development (lt dev)" URL 블록 주입,.lt-dev/를.gitignore에 추가합니다. 자동 체인: 머신이 아직 준비되지 않은 경우 먼저install을 실행합니다(--skip-install로 옵트아웃).up— 내부 업스트림 포트를 할당(4000+, 절대 3000/3001 아님), **reverse_proxy 127.0.0.1:<port>**와 함께 Caddy 블록을 업서트 + 리로드,PORT,HOST=127.0.0.1/NITRO_HOST=127.0.0.1(개발 서버를 IPv4에 고정하여 업스트림이 명확하도록 함),BASE_URL,APP_URL,NUXT_API_URL,NUXT_PUBLIC_API_URL,NUXT_PUBLIC_SITE_URL,NUXT_PUBLIC_STORAGE_PREFIX,NUXT_PUBLIC_API_PROXY=false, API 데이터베이스(MongoDB:NSC__MONGOOSE__URI; PostgreSQL / MySQL / MariaDB, lt CLI 1.54.0부터:NSC__DATABASE__URL및NSC__DATABASE__OWNER_URL- API 전용, 스택 자체의 데이터베이스에서 첫 번째 시작 시 소유자 역할로 생성, PostgreSQL에서는CREATEDB, MySQL/MariaDB에서는CREATE+GRANT OPTION필요;~/.lenneTech/projects.json의dbUrls아래에 자격 증명 없이 기록됨),NODE_EXTRA_CA_CERTS(Caddy 루트 CA로 Nuxt SSR이 HTTPS를 신뢰하도록 함), 그리고NUXT_*규칙보다 먼저 나온 프로젝트를 위한 레거시 별칭API_URL/SITE_URL을 내보냅니다. 그런 다음pnpm start(api) +pnpm dev(앱)을 분리하여 실행합니다. 사전 점검은 Caddy가 없거나, Caddy 데몬이 중단되었거나, 기존 세션이 활성 상태이거나, 내부 포트가 이미 바인딩된 경우 시작을 거부합니다. 로그는<root>/.lt-dev/{api,app}.log에 있습니다.down— 저장된 프로세스 그룹(음수 PID)에 SIGTERM을 보내어 자식 프로세스(Vite, Nest watcher 등)도 수신하도록 합니다. 프로젝트의 Caddy 블록을 제거하고 리로드합니다. 또한 이 프로젝트의 모든 격리된 테스트 스택(lt dev test)을 해체합니다.test— 격리된 E2E. 두 번째 병렬 스택(<slug>-test.localhost/api.<slug>-test.localhost, 자체 포트 + Caddy 블록 +.lt-dev/.env.test브리지)을 전용 DB<slug>-test(개발<slug>-local및 API-test<slug>-e2e와 분리)에서 가동하고, Playwright 스위트를 실행(global-setup이 첫 번째 테스트 전에 해당 DB를 한 번 재설정)한 다음 잔여물 없이 자동 해체합니다. 개발 세션과 함께 실행되며 절대 건드리지 않습니다.--keep는 유지하고, **lt dev test down**이 중지하며,--api는 (이미 격리된) API 테스트를 대신 실행하고,--debug= PWDEBUG+headed,-- <args>는 Playwright로 전달됩니다. **--shard N**은 스위트를 N개의 완전히 격리된 병렬 스택(각각 자체 포트 + Caddy 블록 + DB<slug>-test-<i>) + N개의--shard=i/NPlaywright 프로세스로 분할하여 실행합니다 — 로컬 CI-패리티 매트릭스.--shard만 사용하면 기본값 2(안정적인 최적 지점: N≥3은 일반 개발 머신에서 성능 코어를 초과 구독하여 불안정함),--shard auto는 CPU+RAM에서 N 크기를 산정(보수적). 로컬 샤드는 하나의 머신을 공유합니다(CI의 샤드별 컨테이너와 달리), 따라서 CLI는 프로젝트의 playwright.config가 해당 부하에서만 타임아웃을 완화할 수 있도록LT_DEV_TEST_SHARDS를 내보냅니다(CI는 빠르게 유지).lt dev test down은 모든 샤드를 회수합니다. 이 격리된 세션을 제공하는 lt CLI 버전이 필요합니다.status/status --all— 현재 프로젝트: 서브도메인 → 업스트림 포트, DB URI, 세션 PID(활성/중지), 라이브lsof업스트림 상태.--all:●/○표시기가 있는 모든 등록된 프로젝트.doctor— Caddy on PATH, lt-dev LaunchAgent / systemd 유닛 로드됨, 데몬 실행 중, Caddyfile 유효, 포트 80/443이 사용 가능하거나 Caddy가 점유,*.localhost가 리졸브됨(IPv4 또는 IPv6 루프백), 레지스트리 상태.tunnel— 포그라운드 Cloudflare Quick Tunnel:cloudflared tunnel --url https://<slug>.localhost --http-host-header <slug>.localhost --no-tls-verify. 공개*.trycloudflare.comURL(5-10초)을 출력하고 Ctrl-C까지 실행됩니다. 기본값은 앱을 노출하고,--api는 대상을 전환합니다. localhost 도메인의 인증 쿠키는 터널 URL에서 유효하지 않습니다. 로그인 흐름이 성공하려면 터널 URL을 Better-Auth의trustedOrigins에 추가하세요. 외부에서 완전히 사용하려면 두 번째lt dev tunnel --api를 병렬로 시작하세요.
스폰 바이너리 재정의: LT_PNPM_BIN을 통해(예: 래퍼 스크립트를 사용한 bun 기반 프로젝트의 경우).
lt ticket — 병렬 티켓 개발 환경
하나의 프로젝트에서 여러 티켓/기능을 동시에 작업합니다. 각각 자체 git worktree + 자체 격리된 lt dev 스택(자체 URL, 포트, Caddy 블록, 빈 DB)을 사용하여 여러 티켓을 상호 영향 없이 병렬로 브라우저 테스트와 E2E 테스트를 모두 수행할 수 있습니다.
lt ticket start DEV-2200 # worktree (origin/dev에서 feat/DEV-2200 브랜치) + pnpm install + lt dev up