> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iriscode.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Iris Code CLI Command Reference

> Full reference for all thirteen Iris Code CLI commands: iris check, iris secrets, iris security, iris deps, iris cve, iris sbom, iris todos, iris gate, iris slack, iris report, iris hook, iris auth, and iris config.

Thirteen commands, covering scanning, dependency audits, CVE gating, SBOM export, enforcement and hooks. Anything marked **Pro** needs a licence; the rest work with no account at all.

If you only ever learn two: `iris check` for a score, `iris gate` for CI.

***

### iris check

Scores source files and prints health findings. Single-file scans are free; scanning a directory or using `--staged` / `--changed` requires Pro.

| Flag                | Description                                                               |
| ------------------- | ------------------------------------------------------------------------- |
| `[path]`            | File or directory to scan (defaults to current directory)                 |
| `--staged`          | Scan staged git files only **(Pro)**                                      |
| `--changed`         | Scan files changed since the last commit **(Pro)**                        |
| `--min-score <n>`   | Minimum health score 0–100; overrides `.irisconfig.json`                  |
| `--config <path>`   | Use a specific `.irisconfig.json`                                         |
| `--format <fmt>`    | Output format: `pretty` (default), `json`, or `github`                    |
| `--output <path>`   | Write JSON result to file (requires `--format json`)                      |
| `--verbose`         | Show individual findings per file                                         |
| `--show-suppressed` | List each finding suppressed by an `iris-ignore` comment, with its reason |
| `--slack-on <when>` | `failure` (default) or `always`                                           |
| `--slack-dry-run`   | Print the Slack payload instead of posting it                             |

Findings silenced by [inline suppressions](/enforcement/suppressions) (`// iris-ignore: <ruleId> -- <reason>`) do not count against the score, but the suppressed count always appears in the output; `--show-suppressed` lists each one individually. JSON reports include a per-file `suppressed` array.

Directory checks also find [duplicate code blocks](/features/duplicate-detection) across files; JSON file entries carry an additive `duplicateBlocks` array, and files excluded from duplicate comparison (too large or minified-looking) are disclosed rather than silently skipped.

```bash theme={null}
# Score a single file (free)
iris check src/index.ts

# Score a directory with a custom threshold (Pro)
iris check src/ --min-score 80

# Score staged files only (Pro)
iris check --staged
```

| Exit code | Meaning                           |
| --------- | --------------------------------- |
| `0`       | All files at or above threshold   |
| `1`       | One or more files below threshold |
| `2`       | Bad arguments or config error     |

***

### iris secrets

Scans the project for hardcoded credentials, API keys, tokens, and passwords. **Free - no authentication required.**

| Flag              | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `[path]`          | File or directory to scan (defaults to current directory)            |
| `--history`       | Scan the git commit history instead of the working tree (**Pro**)    |
| `--depth <n>`     | With `--history`: commits to walk (default `50`; `0` = full history) |
| `--format <fmt>`  | Output format: `pretty` (default) or `json`                          |
| `--output <path>` | Write JSON result to file (requires `--format json`)                 |

```bash theme={null}
# Scan the current directory
iris secrets

# Scan a specific path and output JSON
iris secrets ./src --format json

# Scan the last 50 commits of git history (Pro)
iris secrets --history

# Scan the full history
iris secrets --history --depth 0
```

`--history` finds secrets that were committed and later removed: every file version introduced by each commit (committed `.env` files included) runs through the same two-layer detection. Findings are deduplicated per distinct secret, always masked, and show first/last sighting, the commits and files involved, and whether the secret is still in HEAD. Merge-commit content is covered, and coverage limits - depth, size caps, shallow clones - are always disclosed rather than implying a clean full history. Everything runs against local git; nothing leaves the machine. Rotation is the real fix: a secret that reached history should be rotated even if it was removed later.

| Exit code | Meaning                                                                |
| --------- | ---------------------------------------------------------------------- |
| `0`       | No secrets found                                                       |
| `1`       | Secrets found (working tree, or anywhere in the scanned history range) |
| `2`       | Bad arguments                                                          |

***

### iris security

Scans the project for nine security anti-patterns: eval/exec usage, SQL built by string concatenation, insecure RNG, ReDoS-prone regex, hardcoded localhost URLs, disabled TLS verification, debug flags, weak hashing (MD5/SHA-1), and open redirects. See [Security Smells](/features/security-smells) for the full pattern reference. **Free - no authentication required.**

| Flag              | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `[path]`          | File or directory to scan (defaults to current directory) |
| `--format <fmt>`  | Output format: `pretty` (default) or `json`               |
| `--output <path>` | Write JSON result to file (requires `--format json`)      |

```bash theme={null}
# Scan the current directory
iris security

# Scan a specific path and output JSON
iris security ./src --format json
```

| Exit code | Meaning                  |
| --------- | ------------------------ |
| `0`       | No security smells found |
| `1`       | Security smells found    |
| `2`       | Bad arguments            |

***

### iris deps

**Pro.** Audits dependencies in `package.json`, `go.mod`, `requirements.txt`, or `pyproject.toml` for outdated versions and known CVEs via the [OSV.dev](https://osv.dev) database.

Installed versions are resolved from your lockfile when one is present (`package-lock.json` v1-v3, `pnpm-lock.yaml`, `yarn.lock` classic and Berry, `poetry.lock`, `Pipfile.lock`), so the audit reflects what is actually installed rather than the manifest range, and advisories are filtered to that installed version. Monorepo workspace members (npm and yarn workspaces, `pnpm-workspace.yaml`) are discovered and deduplicated automatically, and internal `workspace:` / `file:` / `link:` dependencies are excluded.

| Flag               | Description                                          |
| ------------------ | ---------------------------------------------------- |
| `[path]`           | Directory to scan (defaults to current directory)    |
| `--no-cache`       | Skip the 24-hour local cache and re-fetch            |
| `--verbose`        | Show individual CVE titles and URLs                  |
| `--format <fmt>`   | Output format: `pretty` (default) or `json`          |
| `--output <path>`  | Write JSON result to file (requires `--format json`) |
| `--allow-network`  | Re-enable network lookups after a revoke             |
| `--revoke-network` | Disable version and advisory lookups                 |

```bash theme={null}
# Audit dependencies in the current project
iris deps

# Bypass the cache and output JSON
iris deps --no-cache --format json
```

The first network lookup asks for consent and discloses exactly what is sent: package names and versions, nothing else. Your choice is persisted in `~/.iris/preferences.json`. Run with `--revoke-network` to disable lookups later, or `--allow-network` to re-enable them. When results come from the 24-hour cache, the output prints the age of the cached scan.

No token or rate-limit setup is needed - OSV.dev lookups are unauthenticated and only the package name, ecosystem, and version are sent. Each advisory in the output carries a confidence label (`fix-available`, `direct`, `transitive`, or `manual-review`) plus the fixed-in version where one exists. Advisories without a verifiable id or severity are never shown - they are dropped and the skip count is disclosed in the output. Dependencies whose lookup errored are marked "not checked", never assumed clean.

| Exit code | Meaning                                |
| --------- | -------------------------------------- |
| `0`       | No vulnerabilities found               |
| `1`       | One or more vulnerabilities detected   |
| `2`       | Invalid arguments or no manifest found |

***

### iris cve

**Pro.** Runs the same dependency and CVE scan as `iris deps` (sharing its 24-hour cache and network consent), but exits `1` only when a vulnerability at or above the `--severity` threshold is found. This is the command to use for CI gates: block merges on high or critical advisories without failing the pipeline on low-severity noise. Each matched advisory row shows its confidence label (`fix-available`, `direct`, `transitive`, or `manual-review`) and the fixed-in version where one exists.

| Flag               | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| `[path]`           | Directory to scan (defaults to current directory)                                     |
| `--severity <lvl>` | Minimum severity that fails the run: `low`, `medium`, `high` (default), or `critical` |
| `--no-cache`       | Skip the 24-hour local cache and re-fetch                                             |
| `--format <fmt>`   | Output format: `pretty` (default) or `json`                                           |
| `--output <path>`  | Write JSON result to file (requires `--format json`)                                  |
| `--allow-network`  | Re-enable network lookups after a revoke                                              |
| `--revoke-network` | Disable version and advisory lookups                                                  |

```bash theme={null}
# Fail on high or critical advisories (default threshold)
iris cve

# Gate on critical advisories only
iris cve --severity critical

# Include everything, down to low severity
iris cve --severity low
```

| Exit code | Meaning                                    |
| --------- | ------------------------------------------ |
| `0`       | No CVEs at or above the threshold          |
| `1`       | One or more CVEs at or above the threshold |
| `2`       | Invalid arguments or no manifest found     |

***

### iris sbom

**Pro.** Exports a CycloneDX 1.5 software bill of materials covering npm, Go, Python, RubyGems, NuGet, Cargo, and Maven manifests in the project. The command is fully offline: no network requests are made and no consent prompt appears.

Each component carries the package name, the exact installed version (lockfile-resolved), a `purl`, and a `required` or `optional` scope depending on whether the dependency is direct or dev-only. If a cached `iris deps` scan exists, known vulnerabilities are folded in as CycloneDX `vulnerabilities` entries cross-referenced by `purl`.

Some dependencies have no version to report: a NuGet `PackageReference` with no version and no Central Package Management entry, or two projects pinning different versions of the same package. Those components are still listed, because an SBOM that quietly omits a dependency is worse than one that admits it does not know the version. They carry a version-less `purl` such as `pkg:nuget/CsvHelper`, no `version` field, and an `iris:version-unresolved` property naming the reason. A purl with an invented version would be well-formed, so a scanner reading it would fail to match the package without reporting a problem.

| Flag              | Description                                        |
| ----------------- | -------------------------------------------------- |
| `[path]`          | Directory to scan (defaults to current directory)  |
| `--output <path>` | Output file path (default: `./iris-sbom.json`)     |
| `--stdout`        | Print the SBOM to stdout instead of writing a file |

```bash theme={null}
# Write iris-sbom.json in the current directory
iris sbom

# Print the SBOM to stdout for piping into other tools
iris sbom --stdout
```

| Exit code | Meaning                                |
| --------- | -------------------------------------- |
| `0`       | SBOM generated successfully            |
| `2`       | Invalid arguments or no manifest found |

***

### iris todos

**Pro.** Lists every `TODO`, `FIXME`, and `HACK` comment found across the project. This command is informational - it does not fail the run based on findings.

| Flag              | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `[path]`          | File or directory to scan (defaults to current directory) |
| `--format <fmt>`  | Output format: `pretty` (default) or `json`               |
| `--output <path>` | Write JSON result to file (requires `--format json`)      |

```bash theme={null}
# List all TODO/FIXME/HACK comments in the project
iris todos

# Scan a specific path and output JSON
iris todos ./src --format json
```

| Exit code | Meaning                          |
| --------- | -------------------------------- |
| `0`       | Success (regardless of findings) |
| `2`       | Bad arguments                    |

***

### iris gate

**Pro.** Runs the full enforcement gate - every rule configured in `.irisconfig.json`, including `gateMaxNamingViolations` - and shows each rule's threshold vs actual value with per-rule PASS/FAIL. This is the recommended command for CI quality gates. There is no CLI flag to override thresholds; set them in `.irisconfig.json`.

Findings silenced by [inline suppressions](/enforcement/suppressions) (`// iris-ignore: <ruleId> -- <reason>`) do not count against gate rules, but the suppressed count always appears in the output. Set `gateMaxSuppressions` to cap suppressions per file, or `ignoreSuppressions: true` to make all directives inert so suppressed findings count as live.

| Flag                | Description                                                               |
| ------------------- | ------------------------------------------------------------------------- |
| `[path]`            | File or directory to scan (defaults to current directory)                 |
| `--config <path>`   | Use a specific `.irisconfig.json`                                         |
| `--format <fmt>`    | Output format: `pretty` (default), `json`, or `github`                    |
| `--output <path>`   | Write JSON result to file (requires `--format json`)                      |
| `--show-suppressed` | List each finding suppressed by an `iris-ignore` comment, with its reason |
| `--slack-on <when>` | `failure` (default) or `always`                                           |
| `--slack-dry-run`   | Print the Slack payload instead of posting it                             |

```bash theme={null}
# Run the gate against the configured rules
iris gate

# Emit inline PR annotations in GitHub Actions format
iris gate . --format github

# Post the outcome to a Slack channel from your own CI
IRIS_SLACK_WEBHOOK="$SLACK_WEBHOOK_URL" iris gate .
```

| Exit code | Meaning                       |
| --------- | ----------------------------- |
| `0`       | All rules pass                |
| `1`       | One or more rules fail        |
| `2`       | Bad arguments or config error |

***

### iris slack

Sets up and tests Slack notifications for `iris check` and `iris gate`. The command is **free**. Iris Code reads the webhook only from `IRIS_SLACK_WEBHOOK` and sends messages directly from your machine or CI.

| Subcommand            | Description                                                                   |
| --------------------- | ----------------------------------------------------------------------------- |
| `iris slack setup`    | Validate a webhook, send a test message, and show the CI secret configuration |
| `iris slack test`     | Send a test message using `IRIS_SLACK_WEBHOOK`                                |
| `iris slack manifest` | Print a link and manifest for creating a pre-configured Slack app             |

The complete setup, payload contents and credential rules are covered in [Slack notifications](/enforcement/slack-notifications).

***

### iris report

Runs a workspace scan and exports the results as a standalone HTML file. The output mirrors the export produced by the editor extension. **Free.**

| Flag              | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `[path]`          | File or directory to scan (defaults to current directory) |
| `--output <path>` | Output file path (default: `./iris-report.html`)          |
| `--config <path>` | Use a specific `.irisconfig.json`                         |
| `--min-score <n>` | Health score threshold 0–100                              |

```bash theme={null}
# Export a report to the default location
iris report

# Export a report to a custom path
iris report --output ./reports/latest.html
```

| Exit code | Meaning                                   |
| --------- | ----------------------------------------- |
| `0`       | Report written successfully               |
| `2`       | Bad arguments or could not write the file |

***

### iris hook

Installs and removes the git pre-push hook and the build gate hook - equivalent to the VS Code command palette hook commands. The type (`git` or `build`) comes before the action. `status` is **free**; `install` and `uninstall` require **Pro**.

| Subcommand                         | Description                                                     |
| ---------------------------------- | --------------------------------------------------------------- |
| `iris hook git status [path]`      | Show whether the git pre-push hook is installed **(free)**      |
| `iris hook git install [path]`     | Write the Iris Code block to `.git/hooks/pre-push` **(Pro)**    |
| `iris hook git uninstall [path]`   | Remove the Iris Code block from `.git/hooks/pre-push` **(Pro)** |
| `iris hook build status [path]`    | Show whether the build hook is installed **(free)**             |
| `iris hook build install [path]`   | Wire Iris Code into the project build command **(Pro)**         |
| `iris hook build uninstall [path]` | Remove the Iris Code build entry **(Pro)**                      |

```bash theme={null}
# Check current hook status (free)
iris hook git status

# Install the git pre-push hook
iris hook git install

# Remove the build hook
iris hook build uninstall
```

| Exit code | Meaning                                                           |
| --------- | ----------------------------------------------------------------- |
| `0`       | Success                                                           |
| `2`       | Bad arguments, not a git repository, or no project manifest found |

***

### iris auth

Manages authentication credentials. Every subcommand is fully interactive - there is no non-interactive flag to pass a token directly on the command line; use the `IRIS_LICENCE_TOKEN` environment variable instead for CI runners. See the [Authentication](/cli/auth) page for the full guide.

| Subcommand | Description                                                                         |
| ---------- | ----------------------------------------------------------------------------------- |
| `login`    | Interactive prompt: browser-based sign-in or paste a licence token. Requires a TTY. |
| `status`   | Show the current authentication state                                               |
| `logout`   | Remove stored credentials                                                           |

```bash theme={null}
# Sign in interactively
iris auth login

# Check the current session
iris auth status
```

***

### iris config

Generates or validates `.irisconfig.json`.

| Subcommand        | Flag | Description                                                                                                                                                                                                                      |
| ----------------- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `init [path]`     | —    | Interactively pick a preset (`legacy`, `balanced`, `strict`) and write `.irisconfig.json`. Pro users are also prompted for gate limits. Falls back to a non-interactive `balanced` default when stdin is not a TTY (e.g. in CI). |
| `validate [path]` | —    | Validate an existing `.irisconfig.json` and print any schema or value problems                                                                                                                                                   |

```bash theme={null}
# Interactively generate a config
iris config init

# Validate an existing config
iris config validate
```

| Exit code | Meaning                                                                          |
| --------- | -------------------------------------------------------------------------------- |
| `0`       | Success / no validation issues                                                   |
| `1`       | `validate` found error-severity problems                                         |
| `2`       | Bad arguments, or `init` found an existing file with no TTY to confirm overwrite |
