UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

1,480 lines (1,069 loc) 62.8 kB
# Command Reference for lt This document provides a comprehensive reference for all `lt` CLI commands. For configuration file options, see [lt.config.md](./lt.config.md). ## Related Documentation - **[LT-ECOSYSTEM-GUIDE](./LT-ECOSYSTEM-GUIDE.md)** — Complete reference for `lt` CLI **and** the `lt-dev` Claude-Code Plugin including architecture, vendor-mode workflows, agents, and skills - **[VENDOR-MODE-WORKFLOW](./VENDOR-MODE-WORKFLOW.md)** — Step-by-step guide for converting a project from npm mode to vendor mode, updating it, and optional rollback - **[lt.config.md](./lt.config.md)** — Configuration file reference ## Table of Contents - [CLI Commands](#cli-commands) - [Server Commands](#server-commands) - [Local Development Commands](#local-development-commands) - [Ports Commands](#ports-commands) - [Git Commands](#git-commands) - [Fullstack Commands](#fullstack-commands) - [Deployment Commands](#deployment-commands) - [NPM Commands](#npm-commands) - [Frontend Commands](#frontend-commands) - [Config Commands](#config-commands) - [Utility Commands](#utility-commands) - [Database Commands](#database-commands) - [Directus Commands](#directus-commands) - [TypeScript Commands](#typescript-commands) - [Starter Commands](#starter-commands) - [Claude Commands](#claude-commands) - [Blocks & Components](#blocks--components) - [Template Commands](#template-commands) - [Other Commands](#other-commands) --- ## CLI Commands ### `lt cli create` Creates a new CLI project based on the lenne.Tech CLI starter. **Usage:** ```bash lt cli create [name] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--author <name>` | Author name for the CLI | | `--link` | Link CLI globally after creation | | `--nolink` | Skip linking | **Configuration:** `commands.cli.create.author`, `defaults.author` --- ### `lt cli rename` Renames the current CLI project. **Usage:** ```bash lt cli rename <new-name> ``` --- ## Server Commands ### `lt server create` Creates a new standalone NestJS server project in a sibling directory. For an in-workspace API, prefer [`lt fullstack add-api`](#lt-fullstack-add-api). **Usage:** ```bash lt server create [name] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Server name (preferred over the positional argument) | | `--description <text>` | Project description | | `--author <name>` | Author name | | `--api-mode <Rest\|GraphQL\|Both>` | API mode (ignored with `--next`) | | `--framework-mode <npm\|vendor>` | Framework consumption mode (ignored with `--next`) | | `--framework-upstream-branch <ref>` | Upstream `nest-server` branch/tag/commit to vendor (only with `--framework-mode vendor`) | | `--branch <branch>` / `-b` | Branch of nest-server-starter to use as template | | `--copy <path>` / `-c` | Copy from local template directory instead of cloning | | `--link <path>` | Symlink to local template directory (fastest, changes affect original) | | `--git` | Initialize git repository | | `--next` | **Experimental:** clone [`nest-base`](https://github.com/lenneTech/nest-base) (Bun + Prisma 7 + Postgres + Better-Auth) instead of `nest-server-starter`. Skips API-mode / vendor-mode / install / lt.config.json processing. | | `--dry-run` | Print the resolved plan and exit without making any changes | | `--force` | Override the workspace-detection abort under `--noConfirm` | | `--noConfirm` | Skip confirmation prompts | **Workspace-awareness:** When run inside a directory that already looks like a fullstack workspace (contains `pnpm-workspace.yaml` or `projects/`), the command behaves differently per mode: - **interactive** → asks for confirmation before creating a stray standalone clone - **`--noConfirm` without `--force`** → **refuses** with exit code 1 and points the caller to `lt fullstack add-api`. This is the default behaviour for AI agents and CI scripts: fail loud rather than produce a stray clone that pnpm-workspace.yaml does not pick up. - **`--noConfirm --force`** → proceeds and logs a hint so the override is visible in CI logs. **CLAUDE.md Patching:** If the project contains a `CLAUDE.md`, the generic API mode description is replaced with the selected mode. In single-mode projects (`Rest` or `GraphQL`), the "API Mode System" documentation section is condensed to a brief note. Skipped when `--next` is used. **Configuration:** `commands.server.create.*`, `defaults.author`, `defaults.noConfirm` --- ### `lt server module` Creates a new server module with model, service, controller/resolver. **Usage:** ```bash lt server module [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Module name | | `--controller <type>` | Controller type: `Rest`, `GraphQL`, `Both`, `auto` | | `--noConfirm` | Skip confirmation prompts | | `--skipLint` | Skip lint fix after creation | **Configuration:** `commands.server.module.*`, `defaults.controller`, `defaults.skipLint`, `defaults.noConfirm` --- ### `lt server object` Creates a new embedded object (sub-document). **Usage:** ```bash lt server object [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Object name | | `--skipLint` | Skip lint fix after creation | **Configuration:** `commands.server.object.skipLint`, `defaults.skipLint` --- ### `lt server permissions` Scans all server modules and generates a permissions report showing roles, restrictions, and security gaps. **Usage:** ```bash lt server permissions [options] ``` **Options:** | Option | Description | |--------|-------------| | `--path <dir>` | Path to NestJS project (default: auto-detect) | | `--output <file>` | Output file (default: `permissions.<format>`) | | `--format <md\|json\|html>` | Output format (default: `html` for TTY, `json` for CI) | | `--open` / `--no-open` | Open report in browser (default: `true` for TTY) | | `--console` | Print summary to console | | `--fail-on-warnings` | Exit code 1 on warnings (for CI/CD) | | `--noConfirm` | Skip confirmation prompts | **Configuration:** `commands.server.permissions.*`, `defaults.noConfirm` --- ### `lt server addProp` Adds a property to an existing module or object. **Usage:** ```bash lt server addProp [options] ``` **Options:** | Option | Description | |--------|-------------| | `--type <type>` | Target type: `Module` or `Object` | | `--element <name>` | Target element name | | `--skipLint` | Skip lint fix after creation | **Configuration:** `commands.server.addProp.skipLint`, `defaults.skipLint` --- ### `lt server create-secret` Creates a random secret key. **Usage:** ```bash lt server create-secret ``` --- ### `lt server set-secrets` Sets secrets in environment files. **Usage:** ```bash lt server set-secrets [options] ``` --- ### `lt server test` Runs server tests. **Usage:** ```bash lt server test ``` --- ### `lt server convert-mode` Convert an existing API (NestJS) project between npm mode and vendor mode for `@lenne.tech/nest-server`. **Usage:** ```bash lt server convert-mode --to <vendor|npm> [options] ``` **Options:** | Option | Description | |--------|-------------| | `--to <mode>` | Target mode: `vendor` or `npm` (required) | | `--upstream-branch <ref>` | Upstream branch/tag to vendor from (only with `--to vendor`) | | `--version <version>` | nest-server version to install (only with `--to npm`, default: from VENDOR.md baseline) | | `--dry-run` | Show the resolved plan without making any changes | | `--noConfirm` | Skip confirmation prompt | **Behavior:** - **npm → vendor:** - Clones `@lenne.tech/nest-server` from GitHub at the specified tag (default: currently installed version) - Copies `src/core/`, `src/index.ts`, `src/core.module.ts`, `src/test/`, `src/types/`, and `LICENSE` to `<api-root>/src/core/`; places upstream `src/templates/` at `<api-root>/src/templates/` (outside `core/` so the runtime E-Mail template resolver works) - Applies flatten-fix on `index.ts`, `core.module.ts`, `test.helper.ts`, `core-persistence-model.interface.ts` - Rewrites all consumer imports from `'@lenne.tech/nest-server'` to relative paths - Merges upstream dependencies dynamically into `package.json` - Rewrites `migrate:*` scripts to use local `bin/migrate.js` with `ts-compiler.js` bootstrap - Adds `check:vendor-freshness` script - Creates `src/core/VENDOR.md` with baseline version + commit SHA - Prepends a vendor-mode notice block to `CLAUDE.md` - **vendor → npm:** - Extracts baseline version from `src/core/VENDOR.md` (warns if local patches exist) - Rewrites consumer imports back to `@lenne.tech/nest-server` - Deletes `src/core/` - Restores `@lenne.tech/nest-server` dependency in `package.json` - Restores `migrate:*` scripts to `node_modules/.bin/` paths - Removes vendor artifacts (`bin/`, `migrations-utils/ts-compiler.js`, `migration-guides/`) and `CLAUDE.md` marker **Examples:** ```bash # Convert existing npm project to vendor mode at a specific version cd projects/api lt server convert-mode --to vendor --upstream-branch 11.24.3 --noConfirm # Preview what the conversion would do lt server convert-mode --to vendor --dry-run # Convert vendored project back to npm with a specific version lt server convert-mode --to npm --version 11.24.3 --noConfirm ``` **Note:** nest-server tags have **no** `v` prefix — use e.g. `11.24.3`, not `v11.24.3`. For mode-aware update workflows after conversion, use: - `/lt-dev:backend:update-nest-server-core` (vendor mode) - `/lt-dev:backend:update-nest-server` (npm mode) - `/lt-dev:fullstack:update-all` (coordinated backend + frontend) --- ## Local Development Commands Run multiple lt projects in parallel without port collisions or cross-wiring. **URL-first**: every project gets stable HTTPS URLs (`<slug>.localhost`, `api.<slug>.localhost`) served by Caddy. Internal ports are opaque and auto-allocated. Cross-project state (database, storage, cookies) is namespaced by slug so projects cannot accidentally interfere. ### `lt dev` Open the local-orchestration submenu. **Usage:** ```bash lt dev ``` **Alias:** `lt d` --- ### `lt dev install` One-time per-machine setup. Idempotent — re-run anytime to diagnose what's missing. Owns the full Caddy lifecycle via a dedicated LaunchAgent (macOS) / systemd-user unit (Linux) — **does not** use `brew services caddy`, whose hardcoded `/opt/homebrew/etc/Caddyfile` path would crash-loop against our `~/.lenneTech/Caddyfile`. **Usage:** ```bash lt dev install lt dev install --skip-init # do NOT auto-run `lt dev init` afterwards ``` **Alias:** `lt d i` **Auto-chaining:** when run from inside an lt-dev-capable project that is not yet initialized, `lt dev install` runs `lt dev init` for that project **afterwards**. Pass `--skip-init` to opt out. This is one hop deep and never recurses — `install` calls the init *helper*, not the init command. **What it does:** 1. Verifies `caddy` is on PATH (suggests `brew install caddy` if missing). 2. Creates `~/.lenneTech/Caddyfile` stub if absent. 3. Detects a conflicting `brew services caddy` registration and asks you to stop it. 4. Writes + bootstraps a dedicated service: - **macOS:** `~/Library/LaunchAgents/tech.lenne.lt-dev-caddy.plist` via `launchctl bootstrap gui/<uid>`. - **Linux:** `~/.config/systemd/user/lt-dev-caddy.service` via `systemctl --user enable --now`. 5. Waits up to 8s for Caddy's admin endpoint (`http://127.0.0.1:2019/config/`) to respond. 6. Validates the Caddyfile. 7. Reminds you to run the CA trust command **with HOME preserved**: ```bash sudo -E HOME="$HOME" caddy trust ``` Without `-E HOME="$HOME"`, sudo switches HOME to `/var/root` and caddy cannot find its user-scoped CA — this was the bug that blocked the very first install attempt. **Logs:** `~/.lenneTech/caddy.log`, `~/.lenneTech/caddy.err.log`. --- ### `lt dev uninstall` Symmetric counterpart to `lt dev install`. Removes the LaunchAgent / systemd-user unit and stops the Caddy daemon. Does **not** remove the caddy binary itself. **Usage:** ```bash lt dev uninstall # interactive: asks whether to purge Caddyfile + logs lt dev uninstall --purge # also remove ~/.lenneTech/Caddyfile + caddy logs lt dev uninstall --noConfirm # skip the purge prompt (keep files) ``` **Alias:** `lt d un` **What it does NOT touch:** - the `caddy` binary (use `brew uninstall caddy` if you want to remove the tool too) - per-project state under `<project>/.lt-dev/` (use `lt dev down`) - the trusted CA in the system keychain (use `sudo -E HOME="$HOME" caddy untrust` if desired) --- ### `lt dev init` Initialize an existing project for `lt dev` and apply idempotent env-aware patches. Safe to run multiple times; safe to run after `lt fullstack init`. **Usage:** ```bash lt dev init lt dev init --skip-install # do NOT auto-run `lt dev install` first ``` **Alias:** `lt d init`, `lt d migrate`, `lt d m` (`migrate` is the former name, kept for backwards compatibility) **Auto-chaining:** if the machine has not been prepared yet (no `lt dev install` has run), `lt dev init` runs the install step **first**, then initializes the project. Pass `--skip-install` to opt out. This is one hop deep and never recurses — `init` calls the install *helper*, not the install command. **What it does:** 1. Detects the workspace layout (monorepo `projects/api`+`projects/app`, or standalone). 2. Builds the project identity (slug from `package.json` "name", subdomains). 3. Patches legacy hardcoded ports in `config.env.ts` (`port: 3000`), `nuxt.config.ts` (`port: 3001`, vite proxy target), `playwright.config.ts` (`baseURL`/`host`/`url`) to env-overridable form. Defaults preserved, idempotent. 4. Persists the entry to `~/.lenneTech/projects.json` (override path via `LT_DEV_REGISTRY_PATH`). 5. Adds `.lt-dev/` to the project's `.gitignore`. 6. Injects (or refreshes) a "Local Development (lt dev)" URL block into `CLAUDE.md` files at the workspace root and inside each subproject — bracketed by HTML comment markers. --- ### `lt dev up` Start API + App behind Caddy. Allocates internal ports (4000+), spawns processes detached, persists PIDs to `<root>/.lt-dev/state.json`. **Usage:** ```bash lt dev up ``` **Alias:** `lt d u` **Environment variables injected:** | Variable | Consumer | Example value | |----------|----------|---------------| | `PORT` | Nest (api) / Nuxt (app) | auto-allocated 4000+ | | `BASE_URL` / `NSC__BASE_URL` | nest-server canonical API URL | `https://api.crm.localhost` | | `APP_URL` / `NSC__APP_URL` | nest-server frontend origin (CORS, BetterAuth) | `https://crm.localhost` | | `NUXT_API_URL` | Nuxt vite-proxy target for `/api`, `/iam`, … | `https://api.crm.localhost` | | `NUXT_PUBLIC_API_URL` | Nuxt `useRuntimeConfig().public.apiUrl` | `https://api.crm.localhost` | | `NUXT_PUBLIC_SITE_URL` | Nuxt `useRuntimeConfig().public.siteUrl` + Playwright | `https://crm.localhost` | | `NUXT_PUBLIC_STORAGE_PREFIX` | namespaces sessionStorage/localStorage | `crm` | | `NUXT_PUBLIC_API_PROXY` | always `false` — Caddy + cookie-domain make it obsolete | `false` | | `NSC__MONGOOSE__URI` | nest-server Mongoose URI | `mongodb://127.0.0.1/crm-local` | | `DATABASE_URL` | Postgres convenience URL (for nest-base-style projects) | `postgresql://crm-local:crm-local@localhost:5432/crm-local` | **Override the binary** for both spawns via `LT_PNPM_BIN` (e.g. `LT_PNPM_BIN=/usr/local/bin/pnpm lt dev up`). **Pre-flight guards (exit code 1 each):** - Caddy not installed (`lt dev install` first) - Caddy daemon not running (run `lt dev install` — it bootstraps the lt-dev service) - Already running for this project (`lt dev down` first) - Internal port already in use **Logs:** `<root>/.lt-dev/api.log`, `<root>/.lt-dev/app.log` (append-mode). --- ### `lt dev down` Stop processes started by `lt dev up` and remove the project's Caddy block. **Usage:** ```bash lt dev down ``` **Alias:** `lt d d` Sends `SIGTERM` to the detached process group (negative PID) so descendants — Vite, the Nest watcher, etc. — receive the signal too. PID values from `state.json` are validated before signaling. Best-effort: removes the project's Caddy block and reloads even if no session was active. --- ### `lt dev status` Show what is registered + running. **Usage:** ```bash lt dev status # current project lt dev status --all # every project in the registry ``` **Alias:** `lt d s` The current-project view shows subdomains → upstream ports, db URI, session PIDs (alive/dead), and live `lsof` state. The `--all` view lists every project, with a `●`/`○` indicator for running state. --- ### `lt dev tunnel` Expose a running `lt dev up` project to the public internet via a Cloudflare Quick Tunnel. Foreground command — runs until Ctrl-C. **Usage:** ```bash lt dev tunnel # tunnel the App lt dev tunnel --api # tunnel the API instead ``` **Alias:** `lt d tun` **What it does:** 1. Checks `cloudflared` is on PATH (suggests `brew install cloudflared` otherwise). 2. Confirms the Caddy daemon is up (`lt dev install` must have run). 3. Spawns `cloudflared tunnel --url https://<slug>.localhost --http-host-header <slug>.localhost --no-tls-verify`. The host-header rewrite is required — without it Caddy would not match the project block for the random `*.trycloudflare.com` hostname. 4. Waits for cloudflared to publish the public URL (usually 5-10s) and prints it prominently. **Caveats (also printed at runtime):** - Auth cookies on the localhost domain are NOT valid on the `*.trycloudflare.com` URL — users log in again on the tunnel URL. - Better-Auth's `trustedOrigins` won't include the random tunnel URL — login flows that validate the origin reject the request unless the URL is added explicitly to the API config. - Default tunnels expose ONLY the App. For full external usage (e.g. external client calling the API), start a second `lt dev tunnel --api` in another shell — the API will be reachable on its own `*.trycloudflare.com` URL. **Not yet supported (intentional scope limit):** - Named tunnels with a persistent URL (`cloudflared tunnel create`) - Multi-host tunneling in one process - Background/detached mode --- ### `lt dev doctor` Diagnose Caddy / CA / DNS / port issues. Exit code 0 = all green, 1 = at least one FAIL. **Usage:** ```bash lt dev doctor ``` **Alias:** `lt d doc` **Checks:** 1. `caddy` on PATH 2. Caddy daemon running (admin endpoint `:2019` reachable) 3. Caddyfile validates 4. Ports 80 + 443 free or held by Caddy 5. `*.localhost` resolves to `127.0.0.1` (RFC 6761) 6. Registry status --- ### `lt dev test` One-shot E2E wrapper: ensure `up`, wait for the App URL, run `pnpm run test:e2e` with the `.lt-dev/.env` bridge loaded. Optional teardown after. **Usage:** ```bash lt dev test # App E2E (projects/app) lt dev test --api # API E2E (projects/api) — no Caddy required lt dev test --teardown # plus `lt dev down` after lt dev test --debug # PWDEBUG=1 + HEADED=1 lt dev test -- --ui spec.ts # everything after `--` is forwarded to playwright ``` **Alias:** `lt d t` **Behaviour:** 1. Pre-flight: Caddy installed + daemon running (App mode only). 2. If no `lt dev up` session is alive: invokes `lt dev up` first. 3. Waits up to 30 s for the App URL to respond. 4. Reads `<root>/.lt-dev/.env` and merges into the spawn env (existing process.env wins for keys it defines). 5. Spawns `pnpm run test:e2e [forwarded args]` in `projects/api` (with `--api`) or `projects/app` (default). 6. With `--teardown`, runs `lt dev down` after. **When to use this vs. `pnpm run test:e2e` directly:** - Use **`lt dev test`** for TDD loops, ad-hoc reproduction, or when you want a single-command "ensure-up + run + teardown" flow. - Use **direct `pnpm run test:e2e`** (or VS Code Playwright Extension, IDE test runners) for everyday work — the auto-injected `playwright.config.ts` bridge loads the `.lt-dev/.env` automatically, so the env is correct without the wrapper. --- ### ENV bridge for external test runners `lt dev up` writes a `<root>/.lt-dev/.env` file with the following keys: | Key | Source | |-----|--------| | `BASE_URL`, `APP_URL`, `NSC__BASE_URL`, `NSC__APP_URL` | Identity → `https://api.<slug>.localhost` / `https://<slug>.localhost` | | `NUXT_API_URL`, `NUXT_PUBLIC_API_URL`, `NUXT_PUBLIC_SITE_URL` | Same URLs for Nuxt | | `NUXT_PUBLIC_STORAGE_PREFIX` | Project slug | | `NUXT_PUBLIC_API_PROXY` | Always `false` under `lt dev` | | `NSC__MONGOOSE__URI`, `DATABASE_URL` | Project-namespaced DB URI (when `dbName` known) | | `LT_DEV_ACTIVE`, `LT_DEV_DB_NAME` | Marker keys for consumers | | `NODE_EXTRA_CA_CERTS` | Path to Caddy's root CA cert (auto-detected) | `lt dev init` injects a tiny `// >>> lt-dev:bridge >>>` block at the top of `playwright.config.ts` that loads this file at config-load time — making Playwright (CLI, IDE, VS Code extension) automatically use the `lt dev` URLs and trust the local CA, without inheriting the parent shell. `lt dev down` removes the bridge file so subsequent runs without `lt dev up` fall back cleanly to the classic `localhost:3000`/`localhost:3001` defaults. --- ## Git Commands All git commands support the `--noConfirm` flag and can be configured via `defaults.noConfirm` or `commands.git.noConfirm`. **Commands with `--dry-run` support:** create, update, clear, force-pull, reset, undo, clean, squash, rebase, rename - preview changes without executing them. ### `lt git create` Creates a new git branch from a base branch. **Usage:** ```bash lt git create <branch-name> [base-branch] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--base <branch>` | Base branch for the new branch | | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview what would be created without making changes | **Configuration:** `commands.git.create.base`, `commands.git.baseBranch`, `defaults.baseBranch` --- ### `lt git get` Checks out a git branch (local or remote). **Usage:** ```bash lt git get <branch-name> [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--mode hard` | Remove local commits automatically | **Configuration:** `commands.git.get.*`, `defaults.noConfirm` --- ### `lt git squash` Squashes all commits in the current branch. **Usage:** ```bash lt git squash [base-branch] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview commits that would be squashed | | `--author <name>` | Author for the squash commit | | `--message <text>` | Commit message | **Configuration:** `commands.git.squash.*`, `defaults.noConfirm`, `defaults.baseBranch`, `defaults.author` --- ### `lt git rebase` Rebases the current branch onto another branch. **Usage:** ```bash lt git rebase [base-branch] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview commits that would be rebased | | `--base <branch>` | Base branch for rebase | **Configuration:** `commands.git.rebase.*`, `defaults.noConfirm`, `defaults.baseBranch` --- ### `lt git clear` Clears all current changes (hard reset). **Usage:** ```bash lt git clear [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview what would be discarded | **Configuration:** `commands.git.clear.noConfirm`, `defaults.noConfirm` --- ### `lt git force-pull` Force pulls the current branch, discarding local changes. **Usage:** ```bash lt git force-pull [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview what would be lost | **Configuration:** `commands.git.forcePull.noConfirm`, `defaults.noConfirm` --- ### `lt git reset` Resets the current branch to match the remote. **Usage:** ```bash lt git reset [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview what would be reset | **Configuration:** `commands.git.reset.noConfirm`, `defaults.noConfirm` --- ### `lt git undo` Undoes the last commit (keeps files). **Usage:** ```bash lt git undo [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview the commit that would be undone | **Configuration:** `commands.git.undo.noConfirm`, `defaults.noConfirm` --- ### `lt git rename` Renames the current branch. **Usage:** ```bash lt git rename <new-name> [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview the rename operation | | `--deleteRemote` | Delete remote branch after rename | **Configuration:** `commands.git.rename.noConfirm`, `defaults.noConfirm` --- ### `lt git update` Updates the current branch (fetch + pull + npm install). **Usage:** ```bash lt git update [options] ``` **Options:** | Option | Description | |--------|-------------| | `--skipInstall` | Skip npm install after update | | `--dry-run` | Preview incoming commits without making changes | **Configuration:** `commands.git.update.skipInstall`, `defaults.skipInstall` --- ### `lt git clean` Removes local merged branches. **Usage:** ```bash lt git clean [options] ``` **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | | `--dry-run` | Preview which branches would be deleted | **Configuration:** `commands.git.clean.noConfirm`, `defaults.noConfirm` --- ### `lt git install-scripts` Installs bash scripts for git operations to `~/.local/bin/`. **Usage:** ```bash lt git install-scripts ``` Installs helper scripts: - `git-squash` - Squash commits - `git-rebase` - Rebase branch - `git-clear` - Clear changes - `git-force-pull` - Force pull - etc. --- ## Fullstack Commands ### `lt fullstack init` Creates a new fullstack workspace with API and frontend. **Usage:** ```bash lt fullstack init [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Project name | | `--frontend <type>` | Frontend framework: `angular` or `nuxt` | | `--api-branch <branch>` | Branch of nest-server-starter to use for API | | `--api-copy <path>` | Copy API from local template directory | | `--api-link <path>` | Symlink API to local template (fastest, changes affect original) | | `--frontend-branch <branch>` | Branch of frontend starter to use (ng-base-starter or nuxt-base-starter) | | `--frontend-copy <path>` | Copy frontend from local template directory | | `--frontend-link <path>` | Symlink frontend to local template (fastest, changes affect original) | | `--framework-mode <mode>` | Backend framework consumption mode: `npm` (classic) or `vendor` (pilot, core copied to `src/core/`) | | `--framework-upstream-branch <ref>` | Upstream `nest-server` branch/tag to vendor from (only with `--framework-mode vendor`) | | `--frontend-framework-mode <mode>` | Frontend framework consumption mode: `npm` or `vendor` (nuxt-extensions copied to `app/core/`) | | `--next` | **Experimental:** clone [`nest-base`](https://github.com/lenneTech/nest-base) (Bun + Prisma 7 + Postgres + Better-Auth) for the API instead of `nest-server-starter`. Forces `--api-mode Rest` and `--framework-mode npm`, skips workspace install (run `pnpm install` for app and `bun install` for api manually). | | `--dry-run` | Print the resolved plan without making any changes | | `--git` | Push initial commit to remote repository (git is always initialized) | | `--git-link <url>` | Git remote repository URL (required when `--git` is true) | | `--noConfirm` | Skip confirmation prompts | **Note:** Git is always initialized with the `dev` branch. The `--git` flag only controls whether the initial commit is pushed to a remote repository. **Note:** For Nuxt frontends with `--frontend-copy` or `--frontend-link`, specify the path to the `nuxt-base-template/` subdirectory, not the repository root. **CLAUDE.md Patching:** If the workspace contains a `CLAUDE.md` file, the following template placeholders are replaced with project-specific values: | Placeholder | Replaced with | |-------------|---------------| | `{{PROJECT_NAME}}` | Project name | | `{{PROJECT_DIR}}` | Absolute project directory path | | `{{API_MODE}}` | Selected API mode (`Rest`, `GraphQL`, or `Both`) | | `{{FRONTEND_FRAMEWORK}}` | Frontend framework (`Nuxt 4` or `Angular`) | Additionally, the API's `CLAUDE.md` is patched to reflect the selected API mode — the generic "API Mode" description is replaced with the chosen mode, and in single-mode projects (`Rest` or `GraphQL`), the "API Mode System" section is condensed. **Configuration:** `commands.fullstack.*`, `defaults.noConfirm` **Auto-detection in existing workspaces:** When `lt fullstack init` runs without a name argument inside a directory that already looks like a fullstack workspace (contains `pnpm-workspace.yaml` or `projects/`), it inspects the layout and dispatches to the matching incremental command: - both `projects/api` and `projects/app` exist → refuses with a hint to use `add-api` / `add-app` directly - only `projects/app` exists → delegates to `lt fullstack add-api` (with all original flags forwarded) - only `projects/api` exists → delegates to `lt fullstack add-app` - neither exists → falls through to the regular new-workspace flow To force a brand-new workspace from inside an existing one, pass `--name <slug>`. --- ### `lt fullstack add-api` Add a NestJS API (`projects/api/`) to an existing fullstack workspace that currently only contains a frontend (`projects/app/`). Mirrors every API-related flag from `lt fullstack init` so configuration stays consistent across both flows. **Usage:** ```bash lt fullstack add-api [options] ``` **Options:** | Option | Description | |--------|-------------| | `--api-mode <mode>` | API mode: `Rest`, `GraphQL`, or `Both` | | `--framework-mode <mode>` | Backend framework consumption mode: `npm` (classic) or `vendor` (core copied to `src/core/`) | | `--framework-upstream-branch <ref>` | Upstream `nest-server` branch/tag/commit to vendor (only with `--framework-mode vendor`) | | `--api-branch <branch>` | Branch of `nest-server-starter` to clone | | `--api-copy <path>` | Copy API from a local template directory | | `--api-link <path>` | Symlink API to a local template directory (fastest, changes affect original) | | `--next` | **Experimental:** clone [`nest-base`](https://github.com/lenneTech/nest-base) (Bun + Prisma 7 + Postgres + Better-Auth) instead of `nest-server-starter`. Forces `--api-mode Rest` and `--framework-mode npm`, runs `bun run rename` post-clone, skips workspace install. | | `--workspace-dir <path>` | Workspace root. When omitted, defaults to cwd; if cwd is not a workspace, the command walks up until it finds one (so it works from inside `projects/api/src/`). | | `--skip-install` | Skip `pnpm install` and the post-install format pass | | `--dry-run` | Print the resolved plan without making any changes | | `--noConfirm` | Skip all interactive prompts | **Refusal cases:** - `projects/api/` already exists → suggests `lt fullstack init` in a fresh directory - no workspace detected at the target path → asks the user to run `lt fullstack init` first **Side effects:** writes `projects/api/lt.config.json` with the resolved `apiMode` + `frameworkMode`, hoists workspace-scoped `pnpm.overrides` from sub-projects to the root, runs `pnpm install` + `oxfmt` on the new sub-project (unless `--skip-install` is set). **Configuration:** Reads `commands.fullstack.*` (same keys as `lt fullstack init`). --- ### `lt fullstack add-app` Add a frontend app (`projects/app/`) to an existing fullstack workspace that currently only contains an API (`projects/api/`). Mirrors every frontend-related flag from `lt fullstack init`. **Usage:** ```bash lt fullstack add-app [options] ``` **Options:** | Option | Description | |--------|-------------| | `--frontend <type>` | Frontend framework: `nuxt` or `angular` | | `--frontend-framework-mode <mode>` | Frontend framework consumption mode: `npm` or `vendor` (nuxt-extensions copied to `app/core/`) | | `--frontend-branch <branch>` | Branch of the frontend starter to clone (`ng-base-starter` or `nuxt-base-starter`) | | `--frontend-copy <path>` | Copy frontend from a local template directory | | `--frontend-link <path>` | Symlink frontend to a local template directory (fastest, changes affect original) | | `--next` | Default the nuxt-base-starter ref to the `next` branch (auth `basePath` aligned with the experimental `--next` API) | | `--workspace-dir <path>` | Workspace root. When omitted, defaults to cwd; if cwd is not a workspace, the command walks up until it finds one (so it works from inside `projects/api/src/`). | | `--skip-install` | Skip `pnpm install` and the post-install format pass | | `--dry-run` | Print the resolved plan without making any changes | | `--noConfirm` | Skip all interactive prompts | **Refusal cases:** - `projects/app/` already exists → suggests `lt fullstack init` in a fresh directory - no workspace detected at the target path → asks the user to run `lt fullstack init` first **Side effects:** patches `projects/app/.env` with a project-specific `NUXT_PUBLIC_STORAGE_PREFIX`, optionally vendorizes `nuxt-extensions` into `app/core/`, hoists workspace-scoped `pnpm.overrides`, runs `pnpm install` + `oxfmt` on the new sub-project (unless `--skip-install` is set). **Configuration:** Reads `commands.fullstack.*` (same keys as `lt fullstack init`). --- ### `lt fullstack convert-mode` Convert **both** backend (`projects/api/`) and frontend (`projects/app/`) of a fullstack monorepo between npm mode and vendor mode in a single command. Auto-detects the subprojects, shows the plan for each side, and orchestrates the backend + frontend conversions sequentially. **Usage:** ```bash lt fullstack convert-mode --to <vendor|npm> [options] ``` **Options:** | Option | Description | |--------|-------------| | `--to <mode>` | Target mode: `vendor` or `npm` (required) | | `--framework-upstream-branch <ref>` | Backend upstream branch/tag (only with `--to vendor`, e.g. `11.24.3`) | | `--frontend-framework-upstream-branch <ref>` | Frontend upstream branch/tag (only with `--to vendor`, e.g. `1.5.3`) | | `--framework-version <version>` | Backend nest-server version (only with `--to npm`, default: from `VENDOR.md` baseline) | | `--frontend-framework-version <version>` | Frontend nuxt-extensions version (only with `--to npm`, default: from `VENDOR.md` baseline) | | `--skip-backend` | Skip backend conversion (frontend only) | | `--skip-frontend` | Skip frontend conversion (backend only) | | `--dry-run` | Show the resolved plan without making any changes | | `--noConfirm` | Skip confirmation prompt | **Subproject Detection:** The command searches for subprojects in this order: - Backend: `projects/api/` → `packages/api/` - Frontend: `projects/app/` → `packages/app/` Subprojects that are already in the target mode or not found are gracefully skipped. **Behavior:** For each subproject that needs conversion: - **Backend**: delegates to the same pipeline as `lt server convert-mode` - **Frontend**: delegates to the same pipeline as `lt frontend convert-mode` - **Failure isolation**: If backend fails, frontend still runs (unless `--dry-run`). Final summary lists per-subproject status. **Examples:** ```bash # Convert both subprojects to vendor mode at current versions (auto-detected) cd my-monorepo lt fullstack convert-mode --to vendor --noConfirm # Convert to vendor with explicit versions lt fullstack convert-mode --to vendor \ --framework-upstream-branch 11.24.3 \ --frontend-framework-upstream-branch 1.5.3 \ --noConfirm # Preview the plan without changes lt fullstack convert-mode --to vendor --dry-run # Convert back to npm (preserves local patches by warning before execution) lt fullstack convert-mode --to npm --noConfirm # Only convert backend (frontend stays as-is) lt fullstack convert-mode --to vendor --skip-frontend --noConfirm ``` **Note:** nest-server tags use **no** `v` prefix (e.g. `11.24.3`). nuxt-extensions tags also use **no** `v` prefix (e.g. `1.5.3`). For mode-aware update workflows after conversion, use: - `/lt-dev:fullstack:update-all` (comprehensive, mode-aware) - `/lt-dev:backend:update-nest-server-core` (backend vendor mode) - `/lt-dev:frontend:update-nuxt-extensions-core` (frontend vendor mode) --- ## Deployment Commands ### `lt deployment create` Creates deployment configuration for a monorepo. **Usage:** ```bash lt deployment create [name] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--domain <domain>` | Main domain for the project | | `--gitHub` | Enable GitHub pipeline | | `--gitLab` | Enable GitLab pipeline | | `--testRunner <tag>` | GitLab test runner tag | | `--prodRunner <tag>` | GitLab production runner tag | | `--noConfirm` | Skip confirmation prompts | **Configuration:** `commands.deployment.*`, `defaults.domain`, `defaults.noConfirm` --- ## NPM Commands ### `lt npm reinit` Reinitializes npm packages (removes node_modules and reinstalls). **Usage:** ```bash lt npm reinit [options] ``` **Options:** | Option | Description | |--------|-------------| | `--update` / `-u` | Update package.json before reinstall | | `--noConfirm` | Skip confirmation prompts | **Configuration:** `commands.npm.reinit.*`, `defaults.noConfirm` --- ### `lt npm update` Updates npm packages. **Usage:** ```bash lt npm update ``` --- ## Frontend Commands ### `lt frontend angular` Creates a new standalone Angular workspace using ng-base-starter. For an in-workspace app, prefer [`lt fullstack add-app --frontend angular`](#lt-fullstack-add-app). **Usage:** ```bash lt frontend angular [name] [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Workspace name (preferred over the positional argument) | | `--branch <branch>` / `-b` | Branch of ng-base-starter to use as template | | `--copy <path>` / `-c` | Copy from local template directory instead of cloning | | `--link <path>` | Symlink to local template directory (fastest, changes affect original) | | `--localize` | Enable Angular localize | | `--noLocalize` | Disable Angular localize | | `--gitLink <url>` | Git repository URL to link | | `--dry-run` | Print the resolved plan and exit without making any changes | | `--force` | Override the workspace-detection abort under `--noConfirm` | | `--noConfirm` / `-y` | Skip confirmation prompts | **Workspace-awareness:** Inside a fullstack workspace the command is interactive (confirm prompt), but under `--noConfirm` it **refuses** with exit code 1 and points the caller to `lt fullstack add-app --frontend angular`. Pass `--noConfirm --force` to override (rare). **Configuration:** `commands.frontend.angular.*`, `defaults.noConfirm` --- ### `lt frontend nuxt` Creates a new standalone Nuxt workspace using nuxt-base-starter. For an in-workspace app, prefer [`lt fullstack add-app --frontend nuxt`](#lt-fullstack-add-app). **Usage:** ```bash lt frontend nuxt [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` | Workspace name | | `--branch <branch>` / `-b` | Branch of nuxt-base-starter to use (uses git clone instead of create-nuxt-base) | | `--copy <path>` / `-c` | Copy from local template directory instead of cloning | | `--link <path>` | Symlink to local template directory (fastest, changes affect original) | | `--frontend-framework-mode <npm\|vendor>` | Frontend framework consumption mode (`vendor` copies `nuxt-extensions` into `app/core/`) | | `--next` | Default branch to `nuxt-base-starter#next` (auth `basePath` aligned with the experimental `--next` API) | | `--dry-run` | Print the resolved plan and exit without making any changes | | `--force` | Override the workspace-detection abort under `--noConfirm` | | `--noConfirm` | Skip confirmation prompts (requires `--name`) | **Note:** For `--copy` and `--link`, specify the path to the `nuxt-base-template/` subdirectory, not the repository root: ```bash lt frontend nuxt --copy /path/to/nuxt-base-starter/nuxt-base-template ``` **Workspace-awareness:** Inside a fullstack workspace the command is interactive (confirm prompt), but under `--noConfirm` it **refuses** with exit code 1 and points the caller to `lt fullstack add-app --frontend nuxt`. Pass `--noConfirm --force` to override (rare). **Configuration:** `commands.frontend.nuxt.*`, `commands.fullstack.frontendFrameworkMode` (shared with `init` / `add-app`) --- ### `lt frontend convert-mode` Convert an existing frontend (Nuxt) project between npm mode and vendor mode for `@lenne.tech/nuxt-extensions`. **Usage:** ```bash lt frontend convert-mode --to <vendor|npm> [options] ``` **Options:** | Option | Description | |--------|-------------| | `--to <mode>` | Target mode: `vendor` or `npm` (required) | | `--upstream-branch <ref>` | Upstream branch/tag to vendor from (only with `--to vendor`) | | `--version <version>` | nuxt-extensions version to install (only with `--to npm`, default: from VENDOR.md baseline) | | `--dry-run` | Show the resolved plan without making any changes | | `--noConfirm` | Skip confirmation prompt | **Behavior:** - **npm → vendor:** - Clones `@lenne.tech/nuxt-extensions` from GitHub at the specified tag (default: currently installed version) - Copies `src/module.ts`, `src/index.ts`, `src/runtime/`, and `LICENSE` to `<app-root>/app/core/` - Rewrites `nuxt.config.ts` module entry from `'@lenne.tech/nuxt-extensions'` to `'./app/core/module'` - Rewrites explicit consumer imports in `app/**/*.{ts,vue}` and `tests/**/*.ts` to relative paths - Removes `@lenne.tech/nuxt-extensions` from `package.json` dependencies - Merges upstream runtime dependencies (e.g. `@nuxt/kit`) - Adds `check:vendor-freshness` script - Creates `app/core/VENDOR.md` with baseline version + commit SHA - Prepends a vendor-mode notice block to `CLAUDE.md` - **vendor → npm:** - Extracts baseline version from `app/core/VENDOR.md` (warns if local patches exist) - Rewrites consumer imports back to `@lenne.tech/nuxt-extensions` - Deletes `app/core/` - Restores `@lenne.tech/nuxt-extensions` dependency in `package.json` - Rewrites `nuxt.config.ts` module entry back - Removes vendor scripts and `CLAUDE.md` marker **Examples:** ```bash # Convert existing npm project to vendor mode at a specific version cd projects/app lt frontend convert-mode --to vendor --upstream-branch 1.5.3 --noConfirm # Convert vendored project back to npm with a specific version lt frontend convert-mode --to npm --version 1.5.3 --noConfirm ``` **Note:** nuxt-extensions tags have **no** `v` prefix — use e.g. `1.5.3`, not `v1.5.3`. For mode-aware update workflows after conversion, use: - `/lt-dev:frontend:update-nuxt-extensions-core` (vendor mode) - `/lt-dev:fullstack:update-all` (coordinated backend + frontend) --- ## Config Commands ### `lt config init` Creates a new `lt.config` file interactively. **Usage:** ```bash lt config init [options] ``` **Options:** | Option | Description | |--------|-------------| | `--format <type>` | File format: `json` or `yaml` | | `--controller <type>` | Default controller type | | `--frontend <type>` | Default frontend framework | | `--interactive <bool>` | Enable/disable interactive mode | | `--noConfirm` | Skip confirmation prompts (overwrite existing) | **Configuration:** `commands.config.init.noConfirm`, `defaults.noConfirm` --- ### `lt config show` Displays the merged configuration for the current directory. **Usage:** ```bash lt config show ``` --- ### `lt config help` Shows help for the configuration system. **Usage:** ```bash lt config help ``` --- ### `lt config validate` Validates the current `lt.config` file. **Usage:** ```bash lt config validate ``` Reports syntax errors, type mismatches, and unknown keys. --- ## Utility Commands ### `lt status` Shows project status and context. **Usage:** ```bash lt status ``` Displays: - Project type detection (nest-server, nuxt, angular, etc.) - Package information - Git branch and repository status - Configuration file status - Available commands for the project type --- ### `lt doctor` Diagnoses common development environment issues. **Usage:** ```bash lt doctor [options] ``` **Options:** | Option | Description | |--------|-------------| | `--fix` | Attempt automatic fixes | Checks: - Node.js version - npm version - Git installation - lt CLI version and updates - Project configuration - Dependencies installation --- ### `lt history` Views and manages command history. **Usage:** ```bash lt history [count] lt history search <pattern> lt history clear ``` **Arguments:** - `count` - Number of recent commands to show (default: 20) - `search <pattern>` - Search history for matching commands - `clear` - Clear command history **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation when clearing | --- ### `lt completion` Generates and installs shell completion scripts. **Usage:** ```bash lt completion install # Install completions (recommended) lt completion <bash|zsh|fish> # Output completion script ``` **How it works:** - Generates **static completion files** at install time (no runtime overhead) - Completions are **auto-updated** when CLI is installed/updated - Files are loaded once at shell startup **Installation:** ```bash # Automatic (recommended) lt completion install # Manual (if needed) lt completion bash > ~/.local/share/lt/completions/lt.bash lt completion zsh > ~/.local/share/lt/completions/_lt lt completion fish > ~/.config/fish/completions/lt.fish ``` **Completion file locations:** - Bash: `~/.local/share/lt/completions/lt.bash` - Zsh: `~/.local/share/lt/completions/_lt` - Fish: `~/.config/fish/completions/lt.fish` --- ### `lt templates list` Lists available templates. **Usage:** ```bash lt templates list ``` Shows: - Built-in templates - Custom templates (~/.lt/templates) - Project templates (./lt-templates) --- ## Database Commands ### `lt mongodb collection-export` Exports a MongoDB collection to JSON file. **Usage:** ```bash lt mongodb collection-export [options] ``` **Options:** | Option | Description | |--------|-------------| | `--mongoUri <uri>` | MongoDB connection URI | | `--database <name>` | Database name | | `--collection <name>` | Collection name | | `--output <path>` | Output file path | --- ### `lt mongodb s3-restore` Restores a MongoDB database from an S3 backup. **Usage:** ```bash lt mongodb s3-restore [options] ``` **Options:** | Option | Description | |--------|-------------| | `--bucket <name>` | S3 bucket name | | `--key <key>` | S3 access key ID | | `--secret <secret>` | S3 secret access key | | `--url <url>` | S3 endpoint URL | | `--region <region>` | S3 region | | `--folder <folder>` | S3 folder/prefix | | `--mongoUri <uri>` | MongoDB connection URI | | `--database <name>` | Target database name | --- ### `lt qdrant stats` Shows statistics for Qdrant collections. **Usage:** ```bash lt qdrant stats ``` --- ### `lt qdrant delete` Deletes a Qdrant collection. **Usage:** ```bash lt qdrant delete ``` --- ## Directus Commands ### `lt directus docker-setup` Sets up a local Directus Docker instance using docker-compose. **Usage:** ```bash lt directus docker-setup [options] ``` **Options:** | Option | Description | |--------|-------------| | `--name <name>` / `-n` | Instance name (stored in ~/.lt/directus/<name>) | | `--version <version>` / `-v` | Directus version (default: latest) | | `--database <type>` / `--db <type>` | Database type: `postgres`, `mysql`, `sqlite` | | `--port <number>` / `-p` | Port number (default: auto-detect starting from 8055) | | `--update` | Update existing instance configuration | | `--noConfirm` | Skip confirmation prompts | **Configuration:** `commands.directus.dockerSetup.*`, `defaults.noConfirm` **Port Auto-detection:** - If `--port` is not specified, the CLI automatically finds an available port starting from 8055 - Each instance gets its own port (8055, 8056, 8057, etc.) - This allows running multiple Directus instances simultaneously **Generated files:** - `~/.lt/directus/<name>/docker-compose.yml` - Container configuration - `~/.lt/directus/<name>/.env` - Secrets and environment variables - `~/.lt/directus/<name>/README.md` - Usage instructions **Examples:** ```bash # Create PostgreSQL instance (auto-detects port 8055) lt directus docker-setup --name my-project --database postgres # Create second instance (auto-detects port 8056) lt directus docker-setup --name another-project --database mysql # Create with specific port lt directus docker-setup --name custom-app --database sqlite --port 9000 # Create with specific version lt directus docker-setup --name my-app --database mysql --version 10 # Update existing instance lt directus docker-setup --name my-project --version 11 --update ``` --- ### `lt directus remove` Removes a Directus Docker instance and all its data. **Usage:** ```bash lt directus remove [name] [options] ``` **Arguments:** | Argument | Description | |----------|-------------| | `name` | Instance name to remove (optional, will prompt if omitted) | **Options:** | Option | Description | |--------|-------------| | `--noConfirm` | Skip confirmation prompts | **Configuration:** `commands.directus.remove.*`, `defaults.noConfirm` **What gets removed:** - Stops and removes Docker containers - Removes all Docker volumes (database, uploads, extensions)