Skip to content

Latest commit

 

History

History
1893 lines (1358 loc) · 61.3 KB

File metadata and controls

1893 lines (1358 loc) · 61.3 KB

Command Reference for lt

This document provides a comprehensive reference for all lt CLI commands. For configuration file options, see lt.config.md.

Related Documentation

  • LT-ECOSYSTEM-GUIDE — Complete reference for lt CLI and the lt-dev Claude-Code Plugin including architecture, vendor-mode workflows, agents, and skills
  • VENDOR-MODE-WORKFLOW — Step-by-step guide for converting a project from npm mode to vendor mode, updating it, and optional rollback
  • lt.config.md — Configuration file reference

Table of Contents


CLI Commands

lt cli create

Creates a new CLI project based on the lenne.Tech CLI starter.

Usage:

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:

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.

Usage:

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 (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 --forcerefuses 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:

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:

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:

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:

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:

lt server create-secret

lt server set-secrets

Sets secrets in environment files.

Usage:

lt server set-secrets [options]

lt server test

Runs server tests.

Usage:

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:

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:

# 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:

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:

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:
    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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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 (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:

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 (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:

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:

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:

# 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:

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:

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:

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.

Usage:

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.

Usage:

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:

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:

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:

# 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:

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:

lt config show

lt config help

Shows help for the configuration system.

Usage:

lt config help

lt config validate

Validates the current lt.config file.

Usage:

lt config validate

Reports syntax errors, type mismatches, and unknown keys.


Utility Commands

lt status

Shows project status and context.

Usage:

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:

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:

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:

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:

# 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:

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:

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:

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:

lt qdrant stats

lt qdrant delete

Deletes a Qdrant collection.

Usage:

lt qdrant delete

Directus Commands

lt directus docker-setup

Sets up a local Directus Docker instance using docker-compose.

Usage:

lt directus docker-setup [options]

Options:

Option Description
--name <name> / -n Instance name (stored in ~/.lt/directus/)
--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:

# 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:

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)
  • Deletes instance directory from ~/.lt/directus/

Examples:

# Interactive (shows list of instances)
lt directus remove

# Remove specific instance
lt directus remove my-project

# Skip confirmation
lt directus remove my-project --noConfirm

lt directus typegen

Generates TypeScript types from Directus collections.

Usage:

lt directus typegen [options]

Options:

Option Description
--url <url> / -u Directus API URL
--token <token> / -t Directus API token (Administrator permissions required)
--output <path> / -o Output file path
--noConfirm Skip confirmation prompts

Configuration: commands.directus.typegen.*, defaults.noConfirm

Examples:

# Interactive
lt directus typegen

# With all options
lt directus typegen --url http://localhost:8055 --token <token> --output ./types.ts

TypeScript Commands

lt typescript create

Creates a new TypeScript project.

Usage:

lt typescript create [name] [options]

Options:

Option Description
--author <name> Author name
--noConfirm Skip confirmation prompts
--updatePackages Update packages to latest versions

Configuration: commands.typescript.create.*, defaults.author, defaults.noConfirm


lt typescript playground

Opens TypeScript playground.

Usage:

lt typescript playground

Starter Commands

lt starter chrome-extension

Creates a Chrome extension project.

Usage:

lt starter chrome-extension [name]

Claude Commands

lt claude plugins

Installs and manages Claude Code plugins from multiple marketplaces.

Usage:

lt claude plugins [plugin-name] [options]

Parameters:

Parameter Description
plugin-name Optional. Name of a specific plugin to install

Options:

Option Description
--list List available plugins from all marketplaces
--uninstall Uninstall a plugin

Plugin Sources:

Default Behavior: When run without a plugin name, all lenne.Tech plugins plus recommended external plugins (like typescript-lsp) are installed automatically.

Examples:

# Install all recommended plugins (lenne.Tech + recommended external)
lt claude plugins

# Install a specific plugin
lt claude plugins typescript-lsp

# List available plugins
lt claude plugins --list

# Uninstall a plugin
lt claude plugins lt-dev --uninstall

lt claude shortcuts

Installs Claude Code shell shortcuts (aliases) for quick access to common commands.

Usage:

lt claude shortcuts

Alias: lt claude s

Shortcuts installed:

Alias Command Description
c claude --dangerously-skip-permissions Start new Claude Code session
cc claude --dangerously-skip-permissions --continue Continue last session
cr claude --dangerously-skip-permissions --resume Select and resume previous session

Note: These shortcuts use --dangerously-skip-permissions which enables autonomous operation by bypassing permission prompts. Ensure you have proper data backups before using them.

Examples:

# Install shortcuts to ~/.zshrc (or detected shell config)
lt claude shortcuts

# After installation, use:
c        # Start new session
cc       # Continue last session
cr       # Resume a previous session

Blocks & Components

lt blocks add

Adds code blocks to your project from the lenne.tech component library.

Usage:

lt blocks add [block-name] [options]

Options:

Option Description
--noConfirm Skip confirmation prompts (auto-install dependencies)

Configuration: commands.blocks.add.noConfirm, defaults.noConfirm


lt components add

Adds components to your project from the lenne.tech component library.

Usage:

lt components add [component-name] [options]

Options:

Option Description
--noConfirm Skip confirmation prompts (auto-install dependencies)

Configuration: commands.components.add.noConfirm, defaults.noConfirm


Template Commands

lt templates llm

Gets LLM prompt templates.

Usage:

lt templates llm [prompt-name] [options]

Options:

Option Description
--output <path> / -o Save to file
--clipboard / -c Copy to clipboard
--display / -d Display in terminal

Other Commands

lt update

Updates the lt CLI to the latest version.

Usage:

lt update

lt docs open

Opens documentation in the browser.

Usage:

lt docs open [doc]

Arguments:

  • lenne.Tech - lenne.Tech documentation
  • NestJS - NestJS documentation
  • GlueGun - GlueGun documentation

lt tools crypt

Generates a password hash.

Usage:

lt tools crypt [password]

lt tools sha256

Generates a SHA256 hash.

Usage:

lt tools sha256 [text]

lt tools jwt-read

Reads and decodes a JWT token.

Usage:

lt tools jwt-read [token]

lt tools regex

Tests regular expressions.

Usage:

lt tools regex [pattern] [text]

lt tools crawl

Crawls a website and stores each page as a Markdown file (with YAML frontmatter containing source_url, download_date, first_downloaded, description, language, word count, etc.) so it can be consumed as a Claude Code knowledge base. Optionally follows same-origin links up to a configurable depth, seeds the queue from <origin>/sitemap.xml, and downloads referenced images into a shared images/ folder (deduplicated by content hash). Re-running the command against the same output directory updates existing pages while preserving their original first_downloaded timestamp.

Alias: cr

Usage:

lt tools crawl <url> [options]

Options:

  • --out <dir> — Output directory (default: current directory). Single-page crawls write the .md directly here; multi-page crawls generate <out>/README.md plus <out>/pages/ and <out>/images/.
  • --depth <n|all> — Link depth (default 0). 0 = only the start page, 1 = start page + direct same-origin links, 2 = and their links, ... Use --depth all (or --depth -1, or the shortcut flag --all) to follow every same-origin link transitively; the crawl then stops when --max-pages is reached.
  • --all — Shortcut for --depth all.
  • --render / --no-render — Render each page through a headless browser before extraction (default on). Required for SPAs (Vue/Nuxt/React/Angular) whose content is client-rendered. Uses playwright-core with system Chrome / Edge first, then Playwright's bundled Chromium. Use --no-render for a plain HTTP fetch when you know the site is static (faster, no browser needed).
  • --install-browser — If --render finds no browser, auto-install Playwright's Chromium (one-time ~170 MB download).
  • --prune / --no-prune — After a multi-page crawl, remove any .md or image files inside <out>/pages and <out>/images that were not written by the current run (default on). Keeps the knowledge base aligned with the live site on update runs. Empty subdirectories are cleaned up too. Ignored in single-page mode. Use --no-prune to preserve old files.
  • --no-images — Disable image downloads.
  • --no-sitemap — Skip discovery via <origin>/sitemap.xml.
  • --concurrency <n> — Parallel HTTP requests (default 4).
  • --max-pages <n> — Safety cap on total pages (default 200).
  • --selector <css> — CSS selector scoping the main content (e.g. article, main).
  • --timeout <ms> — HTTP request timeout in ms (default 20000).
  • --noConfirm — Skip confirmation prompts.

Examples:

# Single page into the current directory
lt tools crawl https://example.com/article --noConfirm

# Crawl start page + direct links into ./knowledge
lt tools crawl https://example.com --out ./knowledge --depth 1 --noConfirm

# Full mini-site with sitemap seeding and images
lt tools crawl https://example.com --out ./kb --depth 2 --max-pages 100 --noConfirm

# Crawl every reachable same-origin page (safety cap via --max-pages)
lt tools crawl https://example.com --out ./kb --depth all --max-pages 500 --noConfirm

# Same, using the --all shortcut
lt tools crawl https://example.com --out ./kb --all --max-pages 500 --noConfirm

# Full SPA-aware crawl (render + prune are on by default)
lt tools crawl https://lenne.tech --all --noConfirm

# Opt-out: plain HTTP fetch for a known-static site, keep orphans
lt tools crawl https://example.com --all --no-render --no-prune --noConfirm

lt tools ocr

Converts PDFs to clean Markdown using marker-pdf — a PyTorch-based, layout-aware OCR engine that produces real Markdown tables, headings and lists. On Apple Silicon (M-series) inference runs on the GPU via Metal Performance Shaders (MPS) and is typically 5–15× faster than CPU-only PDF text extractors. Marker is auto-installed into an isolated virtualenv at ~/.lt/marker/.venv/ on first use; subsequent runs reuse the cached environment and ~3 GB of model weights.

Aliases: ocr, pdf2md

Usage:

lt tools ocr <file.pdf|directory> [options]
lt tools ocr --status              # Show installation status
lt tools ocr --install             # Install marker-pdf without converting anything

Options:

  • --output-dir <dir> — Output directory (default: <input>-MD/ for batch, <input>.md-out/ for single).
  • --workers <n> — Parallel worker processes for batch mode (default 3).
  • --device <auto|mps|cuda|cpu> — Override TORCH_DEVICE. Default auto picks mps on Apple Silicon, cpu elsewhere. Set cuda if running on a Linux machine with an NVIDIA GPU and the appropriate PyTorch CUDA build.
  • --skip-existing / --no-skip-existing — Skip already-converted files in batch mode (default on).
  • --keep-images — Extract embedded images alongside the Markdown (default off — Markdown only).
  • --format <markdown|json|html|chunks> — Output format (default markdown).

Setup notes:

  • Requires python3 (≥ 3.10) on PATH.
  • Uses uv if available (fastest install path); falls back to python3 -m venv + pip otherwise.
  • The first conversion is slower because the model weights download (~3 GB). Subsequent runs start instantly.
  • Apple Silicon: device: mps is auto-selected. Linux/CUDA: pass --device cuda.

Examples:

# Inspect tooling status (python3, uv, venv path, auto-detected device)
lt tools ocr --status

# One-time install (skip if you just want to convert and let auto-install handle it)
lt tools ocr --install

# Convert a single PDF (creates ./report.pdf.md-out/report/report.md)
lt tools ocr ./report.pdf

# Batch a directory with 4 parallel workers
lt tools ocr ./pdfs --output-dir ./md --workers 4

# Force CPU mode (e.g. when MPS-related crashes occur on Sonoma)
lt tools ocr ./report.pdf --device cpu

When to reach for this command vs. the lt-knowledge ingest pipeline: lt tools ocr is for local developer workflows — quick PDF → Markdown for research, demos, validation sets, sanity checks. For productive ingestion (Vector / Graph / Wiki layers, confidence-based fallback, Whisper for audio, archive-aware processing) use the lt-knowledge stack with its Docling + LightOnOCR sidecars. Marker is intentionally not added there because its MPS advantage doesn't apply in Linux containers and Docling already covers the same use cases with native confidence scoring (see lt-knowledge/docs/OCR-COMPARISON-MARKER.md).


Configuration Priority

All configurable commands follow this priority order (highest to lowest):

  1. CLI parameters (e.g., --noConfirm)
  2. Command-specific config (e.g., commands.git.get.noConfirm)
  3. Category-level config (e.g., commands.git.noConfirm)
  4. Global defaults (e.g., defaults.noConfirm)
  5. Code defaults
  6. Interactive user input (only if no value determined from above)

For detailed configuration options, see lt.config.md.