# Installing the LenserFight CLI

The `lf` CLI (`@lenserfight/cli`) is a Node.js binary distributed through npm. This page covers every supported installation method, system requirements, and how to verify a working install on macOS, Linux, and Windows.

---

## System requirements

| Requirement | Version |
|-------------|---------|
| **Node.js** | **≥ 22** (LTS recommended — v22.x or v24.x) |
| npm / pnpm / yarn | any |
| OS | macOS 12+, Linux (glibc ≥ 2.17), Windows 10+ |

> **Why Node.js 22?**
> The CLI is shipped as an **ES Module** (`"type": "module"`). ESM support in Node.js matured in v18, but stable `require()` interop of ESM packages (used by internal dependencies such as `citty`) was not finalised until Node.js 22.12. Building for the broadest compatibility while relying on modern ESM semantics requires ≥ 22.
>
> The binary checks the running Node.js version at startup and exits immediately with a clear error message if it is too old — no cryptic stack trace.

---

## Quick install (recommended)

```bash
npm install -g @lenserfight/cli
```

After installation, both the `lenserfight` binary and its `lf` alias are registered in your PATH.

```bash
lf --version
# lenserfight/0.x.x node/v22.x linux-x64
```

---

## Platform-specific notes

### macOS

Use the system or Homebrew Node.js. The Homebrew formula `node` ships v22+ by default.

```bash
# Verify Node.js
node --version   # must be v22.0.0 or newer

# Install via npm
npm install -g @lenserfight/cli

# Or via pnpm
pnpm add -g @lenserfight/cli
```

If you get `EACCES` permission errors with `npm install -g`, see the [npm docs on fixing permissions](https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally).

### Linux

Use [NodeSource](https://github.com/nodesource/distributions) or [fnm](https://github.com/Schniz/fnm) to install Node.js 22:

```bash
# NodeSource (Debian / Ubuntu)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs

# NodeSource (RHEL / Fedora / Amazon Linux)
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo dnf install -y nodejs

# Or via fnm (version manager, no sudo needed)
curl -fsSL https://fnm.vercel.app/install | bash
fnm install 22
fnm use 22

# Then install the CLI
npm install -g @lenserfight/cli
```

### Windows

Install Node.js 22 from the official installer or via `winget`:

```powershell
# winget (Windows 10 1709+ / Windows 11)
winget install OpenJS.NodeJS.LTS

# Or download the .msi installer from:
# https://nodejs.org/en/download/
```

Then install the CLI in a PowerShell or Command Prompt terminal:

```powershell
npm install -g @lenserfight/cli
lf --version
```

**Shell completion on Windows:** Bash and Zsh completion scripts are generated by `lf completion bash` / `lf completion zsh`. For PowerShell, add completion manually or use Git Bash. See [Shell Completion](completion.md).

**File permissions:** The CLI writes credentials to `%APPDATA%\lenserfight\auth.json` on Windows. POSIX `chmod 600` calls are silently ignored by Node.js on Windows; the directory is protected through NTFS ACLs instead.

**Bash scripts:** Some development commands (e.g., `lf dev seed` with a `combine-seeds.sh` present) require `bash`. Install [Git for Windows](https://git-scm.com/) or enable WSL to provide a `bash` binary.

---

## Build from source (monorepo)

If you are working inside the LenserFight monorepo, build and link the CLI locally:

```bash
# From the repository root
pnpm nx run cli:build        # compile TypeScript → dist/apps/cli/main.js
pnpm nx run cli:chmod        # make the output executable
pnpm nx run cli:link         # npm link into global PATH
```

Verify:

```bash
lf --version
```

> The linked binary points directly into `dist/apps/cli/main.js`. Rebuilding (`pnpm nx run cli:build`) updates it in place — no re-linking required.

---

## Updating

```bash
npm update -g @lenserfight/cli
```

The CLI also prints an update hint to stderr when a newer version is available:

```
  ╭────────────────────────────────────────────────────╮
  │  Update available: v0.15.0 → v0.16.0              │
  │  Run `lf update` to upgrade.                       │
  ╰────────────────────────────────────────────────────╯
```

You can also run `lf update` directly to trigger an npm-based self-update.

---

## Uninstalling

```bash
npm uninstall -g @lenserfight/cli
```

User data (credentials, project config, audit log) is stored separately:

| Platform | Path |
|----------|------|
| macOS | `~/Library/Application Support/lenserfight/` |
| Linux | `~/.config/lenserfight/` (or `$XDG_CONFIG_HOME/lenserfight/`) |
| Windows | `%APPDATA%\lenserfight\` |

Project-level config lives in `.lenserfight/` inside your project directory.

---

## CI / headless environments

Set `LENSERFIGHT_API_KEY` to a developer or service token — this bypasses interactive auth:

```yaml
# GitHub Actions example
env:
  LENSERFIGHT_API_KEY: ${{ secrets.LF_API_KEY }}

steps:
  - run: npm install -g @lenserfight/cli
  - run: lf run exec --lens my-lens-slug --param input="hello"
```

Color output is automatically disabled when `stdout` is not a TTY. You can also force plain-text output explicitly:

```bash
NO_COLOR=1 lf lenses list
```

> `NO_COLOR` is honoured per the [no-color.org](https://no-color.org/) specification: **any value, including an empty string**, disables color.

---

## Troubleshooting

### `ERR_REQUIRE_ESM`

You are running Node.js older than 22. The CLI is an ES Module; older Node.js versions cannot load it via `require()`.

**Fix:** Upgrade Node.js to v22 or newer. The startup banner prints a clear error:

```
Error: @lenserfight/cli requires Node.js v22 or newer (you have v18.20.4).
Download the latest LTS from https://nodejs.org/en/download
```

### `command not found: lf`

The npm global bin directory is not in `PATH`.

```bash
# Find the global bin directory
npm bin -g

# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
export PATH="$(npm bin -g):$PATH"
```

### Permission errors on Linux

Run the install as your user (not root) and configure npm's global prefix to a user-writable directory:

```bash
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
npm install -g @lenserfight/cli
```

### `lf doctor` for post-install verification

After installing, run `lf doctor` to confirm the environment is correctly set up:

```bash
lf doctor
```

It checks Node.js version, API reachability, auth token validity, and Ollama connectivity.

---

## Related

- [Getting Started Tutorial](../../tutorials/cli/cli-getting-started.md)
- [Cross-Platform Compatibility](compatibility.md)
- [Global Flags](global-flags.md)
- [Shell Completion](completion.md)
- [Environment Variables](env.md)
