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

# Vigolium Cheat Sheet

> A one-page, copy-paste reference for the workflows you reach for most: live traffic mirroring, replaying through Burp, passive/secret scanning of forwarded traffic, importing external data, parallel fan-out, resuming, spec-driven scans, single-request scans, content discovery, filtering to one vulnerability class or technology, browsing recorded traffic in the database, triaging findings with a coding agent, reproducing an exploit, setting up the AI agent, and inspecting or editing config.

A fast, copy-paste reference for Vigolium's most common real-world workflows. Each block is self-contained, adjust hosts, ports, and file paths to your environment. For the full explanation behind any command, follow the cross-links into the rest of the docs.

<Callout icon="lightbulb" color="#00b368" iconType="regular">
  Every command here works against the open-source binary. `vigolium <command> -h` prints the full flag list for any subcommand.
</Callout>

***

## 1. Mirror ingested traffic + findings to a live filesystem tree

Run the ingestion server with `--mirror-fs` to write every saved HTTP record and finding to a **flat, browsable directory tree** as it is persisted, in addition to the database. This pairs perfectly with the **Vigolium Burp extension**: as you browse, requests/responses and findings land on disk where your coding agent can read them with plain `ls` / `grep` / `jq`.

```bash theme={null}
# Mirror ingested traffic + findings to a live filesystem tree.
# Writes <dir>/traffic and <dir>/findings as records arrive.
vigolium server --mirror-fs output-dir -A
```

What you get under `output-dir/`:

| Path                               | Contents                                                                                                               |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `traffic/<host>/<id>.req`          | Raw request (leading `@target <scheme>://<authority>` line, then the request verbatim, replayable by stripping line 1) |
| `traffic/<host>/<id>.resp.headers` | Status line + response headers                                                                                         |
| `traffic/<host>/<id>.resp.body`    | Response body (gzip-decoded so it greps clean)                                                                         |
| `traffic/<host>/index.jsonl`       | Append-only, jq-friendly map of ids → method/url/status/content-type                                                   |
| `findings/<host>/<id>.md`          | Each finding, cross-linked to its `.req` file                                                                          |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Mirroring never blocks the database save path (it runs on a background writer) and resumes per-host id numbering across server restarts. Config equivalent: `server.mirror_fs_path`. Add `-S`/`--scan-on-receive` to also scan the traffic as it arrives (see [section 3](#3-passive-secret-scan-on-forwarded-traffic)).
</Callout>

Read it back from an agent or shell:

```bash theme={null}
# List every request Vigolium has ingested for a host
ls output-dir/traffic/example.com/

# Find all findings mentioning "token"
grep -ril token output-dir/findings/

# Pull the method/url/status of every record as JSON
jq . output-dir/traffic/example.com/index.jsonl
```

***

## 2. Replay ALL stored traffic through Burp Suite

Re-send stored records through an intercepting proxy so you can inspect and manipulate them manually in Burp. Keep concurrency low (`-c`) so you don't overwhelm the proxy.

```bash theme={null}
# Replay every stored record in your project DB through Burp
vigolium replay --all --proxy http://127.0.0.1:8080 -c 5
```

Replay directly from a standalone export (project scoping off, nothing written to your project DB):

```bash theme={null}
# BULK: replay every record from a standalone .sqlite export
vigolium replay -S --db scan.sqlite --all --proxy http://127.0.0.1:8080 -c 5
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--all` lifts the default `-n/--limit` cap (100). You can narrow the bulk set instead of `--all` with `--host`, `--method`, `--status`, `--path`, `--source`, `--search`, or `--body`. `-S/--stateless` reads records from a `.jsonl` export **or** a standalone `.sqlite` with project scoping off, it never writes to your project DB.
</Callout>

***

## 3. Passive / secret scan on forwarded traffic

When you forward traffic into Vigolium from another source (the Burp extension, a proxy, or the `vigolium ingest` client), start the **server in scan-on-receive mode**. Use `--passive-only` to run passive modules **only**, no active scan traffic is sent, and secret detection is included.

```bash theme={null}
# Passive-only, continuously scan forwarded traffic as it arrives.
# No active requests are sent; secret detection runs.
vigolium server -S --passive-only -A

# Same, but also mirror everything to disk for your agent to read
vigolium server -S --passive-only --mirror-fs output-dir -A

# Record + passively scan HTTP(S) through the transparent ingest proxy
vigolium server -S --passive-only --ingest-proxy-port 9003 -A
```

Scan-on-receive modes at a glance:

| Flag                               | Behavior                                                                                                                 |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `-S` / `--scan-on-receive`         | Continuously scans new records with the **dynamic-assessment** phase (active + passive modules).                         |
| `-S --passive-only`                | Passive modules only, **no active traffic**. Includes secret detection, security headers, cookie flags, disclosure, etc. |
| `-S --full-native-scan-on-receive` | Runs the **full native pipeline** (discovery + spidering + dynamic-assessment) on received records.                      |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Server mode always enables **every** passive module. `--passive-only` simply zeroes the active modules so the scanner analyzes forwarded request/response pairs without sending any new requests, ideal for scanning traffic you've captured elsewhere. Point the Burp extension (or `vigolium ingest`) at the server's ingestion endpoint and findings appear as traffic flows in. See [Server & Ingestion](/getting-started/server-and-ingestion).
</Callout>

***

## 4. Import external scan data into the database

Use `vigolium import` to pull existing data, **JSONL exports**, **audit output folders**, and **archives**, into your database. It auto-detects the input by inspecting the path.

```bash theme={null}
# JSONL export (http_record + finding envelopes, e.g. from `vigolium export --format jsonl`)
vigolium import data.jsonl

# Audit output folder (contains audit-state.json + findings-draft/)
vigolium import ./audit-output/

# Merge an external vigolium scan DB into the default database
vigolium import other-vigolium-scan.sqlite

# Compressed archive of either of the above
vigolium import bundle.tar.gz      # also .tgz, .zip

# Remote object in cloud storage (downloaded, then imported)
vigolium import gs://<project-uuid>/<key>

# Import and emit a branded HTML report in one step
vigolium import ./audit-output/ --format html -o report.html --report-title "My Report"
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Imported findings are scoped to the active project (`--project` / `VIGOLIUM_PROJECT`). `import` initializes the schema on a fresh `--db` path, so it's safe as the first command against a brand-new database. Supported JSONL types are `http_record` and `finding`; other envelope types are counted and skipped.
</Callout>

### Merging a standalone SQLite database

`vigolium import` detects a SQLite result database by its magic header (works for `.sqlite`, `.sqlite3`, `.db`, or no extension) and performs a **lossless, idempotent SQLite→SQLite merge** of the scan-result tables (http\_records, findings, scans, agentic\_scans, oast\_interactions, projects), deduping on natural keys:

```bash theme={null}
# Merge an external scan DB into the default database
vigolium import other-vigolium-scan.sqlite

# Merge into a specific destination DB
vigolium import other-vigolium-scan.sqlite --db team.sqlite

# Merge several scans at once — pass them positionally…
vigolium import --db combined.sqlite scan-a.sqlite scan-b.sqlite scan-c.sqlite

# …or expand a glob with --glob-db (idempotent, so re-runs are no-ops)
vigolium import --db combined.sqlite --glob-db 'scans/*.sqlite'

# --glob-db also works for JSONL exports (use one format per run)
vigolium import --glob-db '*.jsonl'
```

If you'd rather **read** a colleague's export without merging it into your own DB, open it in place with project scoping off. Point `-S` at a single file with `--db`, or read across **many** files at once with `--glob-db` (they're merged into one throwaway in-memory DB, so `--glob-db` implies `-S`):

```bash theme={null}
# A single standalone export
vigolium finding -S --db scan.sqlite
vigolium traffic -S --db scan.sqlite

# Across a whole directory of exports (.sqlite and/or .jsonl)
vigolium finding --glob-db 'scans/*.sqlite'
vigolium traffic --glob-db 'scans/*.sqlite'
vigolium export --glob-db 'scans/*.sqlite' --format jsonl -o all.jsonl
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Merged rows keep their **original** `project_uuid`, so imported data stays scoped to whatever project it was scanned under. Importing the same database twice adds nothing the second time (dedup on natural keys). Requires a SQLite destination — a Postgres destination returns a clear error. To merge many **parallel** scans into one shared DB during scanning instead, use `--db-isolate` (see [section 5](#5-scan-a-large-list-of-targets-in-parallel)).
</Callout>

***

## 5. Scan a large list of targets in parallel

Point Vigolium at a large target list and use `-P/--parallel N` to scan several hosts at once. Each target runs in its own **isolated child process**, so there is no cross-contamination between workers, and each child keeps its own `--concurrency`, meaning real in-flight requests are roughly `N × --concurrency`.

`-P` requires one of two output strategies so results never collide:

* **`--stateless --split-by-host`** — each target runs against its own temporary database and writes a separate per-host output file (`base-<host>.<ext>`). Nothing is persisted. Best for stateless, fire-and-forget batches.
* **`--db-isolate`** — each worker scans into a private temporary SQLite database, then merges its results into the shared `--db` (or the default DB) at the end. This lets many parallel scans share one database without write contention, and you export one unified report from the merged DB afterward.

```bash theme={null}
# Stateless fan-out: per-host JSONL + HTML files, 3 targets at a time
vigolium scan -T list-of-targets.txt -P 3 \
  --stateless --split-by-host \
  --format jsonl,html --output prefix-output \
  --fuzz-wordlist ~/Tools/contents/fast.txt

# Shared-DB fan-out: 4 targets at a time merged into one local.db, one unified output
vigolium scan -T list-of-targets.txt -P 4 \
  --db-isolate --db local.db \
  --format jsonl,html --output report \
  --fuzz-wordlist ~/Tools/contents/fast.txt
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--db-isolate` is SQLite-only and cannot be combined with `--stateless` (they are two different ways to avoid write contention). Pressing `Ctrl-C` during a `-P` batch is treated as an operator stop: un-started and cut-short targets are reported as "not scanned" rather than failures.
</Callout>

***

## 6. Resume a large parallel scan

A stateless parallel fan-out (`-S -T --split-by-host -P`) writes a tiny line-cursor manifest, `<output>.progress.json`, tracking the targets that completed cleanly. If the batch is interrupted (Ctrl-C, a crash, a CI timeout), re-run it with `--resume` to skip the finished targets and scan only the remainder, Vigolium also prints a copy-pasteable resume command on Ctrl-C/failure:

```bash theme={null}
# Original run
vigolium scan -T targets.txt -P 4 --stateless --split-by-host --format jsonl -o results

# Resume only the targets that didn't finish
vigolium scan -T targets.txt -P 4 --stateless --split-by-host --format jsonl -o results --resume
```

Run `vigolium scan --resume` bare, with no other flags, and it auto-discovers the `*.progress.json` in the current directory and relaunches the saved run from it (pass `-o <prefix>` to disambiguate when several manifests exist).

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--resume` currently applies only to the parallel fan-out (`-S -T --split-by-host -P > 1`). Resuming a plain sequential scan re-runs it in full.
</Callout>

***

## 7. Scan from an OpenAPI / Swagger / Postman / Burp / HAR input

Feed a spec or capture with `-i <file>` and select the format with `-I <format>`. Auto-discovery/crawling is skipped, Vigolium scans exactly the endpoints defined in the input.

```bash theme={null}
# OpenAPI / Swagger spec
vigolium scan --stateless -i api.yaml -I openapi \
  -t https://api.example.com --format jsonl -o results

# Postman collection
vigolium scan --stateless -i collection.json -I postman \
  -t https://api.example.com --format jsonl -o results

# Burp Suite XML export
vigolium scan --stateless -i export.xml -I burpxml --format jsonl -o results

# HAR capture
vigolium scan --stateless -i traffic.har -I har --format jsonl -o results

# Nuclei JSONL
vigolium scan --stateless -i nuclei.jsonl -I nuclei --format jsonl -o results
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Format aliases: `openapi`/`swagger`, `postman`, `burpxml`/`burp`/`burp-xml`, `burpraw`/`raw`, `har`/`http-archive`, `nuclei`/`nuclei-output`. Run `vigolium scan --list-input-mode` for the full list. Use `-t/--target` to supply the base URL when a spec carries only paths.
</Callout>

***

## 8. Scan a single request, no crawling or discovery

`scan-request` runs scanner modules against exactly one raw HTTP request, keeping all its parameters, cookies, and headers, with no crawling or discovery.

```bash theme={null}
# From a file containing a raw HTTP request
vigolium scan-request -i request.txt

# From stdin
printf 'GET /api/users?id=1 HTTP/1.1\r\nHost: example.com\r\n\r\n' \
  | vigolium scan-request

# From a curl command (auto-detected)
echo "curl -X POST -d 'user=admin' https://example.com/login" \
  | vigolium scan-request
```

Override the host when the request file has only a path:

```bash theme={null}
vigolium scan-request -i request.txt --target https://staging.example.com
```

### Piping from stdin

Both `scan-url` and `scan-request` auto-detect the stdin format, plain URL, curl command, or raw HTTP request:

```bash theme={null}
# Plain URL
echo 'https://example.com/search?q=test' | vigolium scan-url

# Curl command
echo "curl -H 'Content-Type: application/json' -d '{\"id\":1}' https://example.com/api" \
  | vigolium scan-url

# Raw HTTP request (keeps the cookie + body verbatim)
printf 'POST /api/login HTTP/1.1\r\nHost: example.com\r\nContent-Type: application/x-www-form-urlencoded\r\nCookie: session=abc123\r\n\r\nuser=admin&pass=secret' \
  | vigolium scan-request

# Scan whatever is on your clipboard (macOS)
pbpaste | vigolium scan-url -j
```

***

## 9. Target one vulnerability class or technology

Every scan command (`scan`, `scan-url`, `scan-request`, `run`, `ingest`) accepts two module filters. Use `-m/--modules` to enable a subset by **fuzzy match on module ID/name**, or `--module-tag` to select by **tag** (repeatable, OR-combined). Both default to "all" when omitted; when you pass both, the results are **merged** (union).

```bash theme={null}
# Only run the XSS modules against a single URL
vigolium scan-url -t 'https://example.com/search?q=1' -m xss

# Technology-scoped scans by tag — GraphQL, Adobe AEM, or IIS only
vigolium scan -t https://example.com --module-tag graphql
vigolium scan -t https://example.com --module-tag aem
vigolium scan -t https://example.com --module-tag iis

# Combine tags (OR): run every AEM or GraphQL module
vigolium scan -t https://example.com --module-tag aem --module-tag graphql

# Pin an exact module by its ID (repeatable)
vigolium scan -t https://example.com -m graphql-scan
vigolium scan-url -t 'https://example.com/p?id=1' -m xss-light-url-params -m sqli
```

Discover what's available before you filter:

```bash theme={null}
# List modules whose id/name/description/tag matches a term
vigolium module ls xss
vigolium module ls aem

# Dump every unique tag you can pass to --module-tag
vigolium module ls --tags

# Full descriptions + confirmation criteria for matched modules
vigolium module ls graphql -v
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  By default a module only fires when the target's detected tech stack matches it (so the GraphQL, AEM, and IIS modules stay dormant on unrelated hosts). If auto-detection misses the stack, add `--no-tech-filter` to run the selected modules regardless (this is auto-enabled by `--intensity=deep`). `-m` matches loosely (`-m xss` selects every XSS module); pass a full ID like `-m xss-light-url-params` to pin exactly one. See [Modules](/native-scan/modules-reference).
</Callout>

***

## 10. Run only specific phases (or skip some)

Use `--only` to run a subset of phases, or `--skip` to exclude phases from an otherwise-full scan. Both accept comma-separated phase names and aliases.

```bash theme={null}
# Phase isolation: run only one phase
vigolium scan -t https://example.com --only discovery
vigolium scan -t https://example.com --only known-issue-scan
vigolium scan -t https://example.com --only dynamic-assessment

# Skip specific phases (aliases like kis = known-issue-scan are accepted)
vigolium scan -t https://example.com --skip discovery,spidering,kis
```

Canonical phase names and their accepted aliases:

| Phase                           | Aliases                       |
| ------------------------------- | ----------------------------- |
| `discovery`                     | `deparos`, `discover`         |
| `spidering`                     | `spitolas`                    |
| `known-issue-scan`              | `cve`, `kis`, `known-issues`  |
| `dynamic-assessment`            | `audit`, `dast`, `assessment` |
| `extension`                     | `ext`                         |
| `external-harvest`, `ingestion` | —                             |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `dynamic-assessment` is the canonical name for the module-based vulnerability-scanning phase (formerly `audit`). The same phase names work as the argument to `vigolium run <phase>`, e.g. `vigolium run cve`.
</Callout>

***

## 11. Run a JavaScript extension only

Load one or more custom JS extensions with `--ext` (repeatable) and restrict the run to the extension phase with `--only extension`, no built-in modules, just your script.

```bash theme={null}
# Run only your extension against the target
vigolium scan -t https://example.com --only extension --ext custom-check.js

# Load several extensions
vigolium scan -t https://example.com --only extension \
  --ext custom-check.js --ext another-check.js
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--ext` is a global flag, so it works on any scan command. Drop `--only extension` to run your extension **alongside** the built-in modules. See [Writing Extensions](/customization/writing-extensions) for the `vigolium.*` API.
</Callout>

***

## 12. Content discovery only

Run **only** the discovery/fuzzing phase, no crawling, no vulnerability modules. The most direct way is `vigolium run discover`, the phase runner: it executes a single named phase and nothing else. Point it at a wordlist with `--fuzz-wordlist`.

```bash theme={null}
# Discovery-only against a whole host (brute-force paths from a wordlist)
vigolium run discover -S -t https://example.com --fuzz-wordlist ~/Tools/contents/fast.txt

# Fuzz a SPECIFIC insertion point with an inline FUZZ marker in the URL —
# each word replaces FUZZ (here: /api/<word>/users)
vigolium run discover -S --fuzz-wordlist ~/Tools/contents/fast.txt \
  -t 'https://example.com/api/FUZZ/users'
```

The **`FUZZ` marker** works anywhere in the target path: put it where you want the wordlist injected. With no marker, vigolium fuzzes off the target's directory (equivalent to appending `/FUZZ`). You can get the same discovery-only behavior on the full `scan` command with `--only discovery --discover`:

```bash theme={null}
# Same idea via `scan`: run every phase-gate off except discovery
vigolium scan -t https://example.com --only discovery \
  --discover --fuzz-wordlist ~/.vigolium/wordlists/fuzz.txt

# Discovery as part of a full scan (fuzz, then keep going into vuln scanning)
vigolium scan -t https://example.com --discover --fuzz-wordlist ~/.vigolium/wordlists/fuzz.txt
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `vigolium run <phase>` runs one phase in isolation (`discover` is an alias for `discovery`; see [section 10](#10-run-only-specific-phases-or-skip-some) for the full phase/alias list). `-S/--stateless` keeps it throwaway (nothing written to your project DB); combine with `--format fs` or `-o` to persist the discovered surface for later scans. `--fuzz-wordlist` enables on-the-fly fuzzing; the `FUZZ` marker pins the exact insertion point. See [Discovery phase](/native-scan/phases/discovery).
</Callout>

***

## 13. Add custom HTTP headers

Inject headers, such as auth tokens or cookies, with `-H/--header` (repeatable). Works on `scan`, `scan-url`, and `scan-request`.

```bash theme={null}
# One or more custom headers on every request
vigolium scan -t https://example.com \
  -H 'Authorization: Bearer eyJhbGciOi...' \
  -H 'X-Api-Key: secret' \
  -H 'Cookie: session=abc123'
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  For richer authenticated scans (login flows, token refresh, multi-step sessions), use an auth session file instead, see [Authentication](/native-scan/authentication) and the `vigolium auth` command.
</Callout>

***

## 14. Control scan speed & duration

Cap the wall-clock time with `--scanning-max-duration`, and tune throughput with `-c/--concurrency`, `-r/--rate-limit`, and `--max-per-host`.

```bash theme={null}
# Override max scan duration
vigolium scan -t https://example.com --scanning-max-duration 2h

# Adjust concurrency and rate limit
vigolium scan -T targets.txt -c 100 --rate-limit 200 --max-per-host 5
```

| Flag                      | Default          | Effect                                                          |
| ------------------------- | ---------------- | --------------------------------------------------------------- |
| `--scanning-max-duration` | `0` (use config) | Hard cap on total scan wall-clock time (e.g. `30m`, `1h`, `2h`) |
| `-c` / `--concurrency`    | `50`             | Number of concurrent scan workers                               |
| `-r` / `--rate-limit`     | `100`            | Maximum HTTP requests per second (global)                       |
| `--max-per-host`          | `50`             | Maximum concurrent requests to any single host                  |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Lower `--rate-limit` and `--max-per-host` to stay gentle on fragile targets; raise `-c` and `--rate-limit` to go faster against robust infrastructure. Under `-P/--parallel`, each child keeps its own `--concurrency`, so real in-flight requests are roughly `P × --concurrency`.
</Callout>

***

## 15. Inspect & change any config value

Vigolium settings live in `~/.vigolium/vigolium-configs.yaml`. Read them with `vigolium config view` (alias for `config ls`) and write them with `vigolium config set <key> <value>` using dot-notation — no need to hand-edit the YAML.

```bash theme={null}
# View everything, or filter by a substring / fuzzy key match
vigolium config view
vigolium config view notify
vigolium config view database.sqlite

# Filter with a glob pattern (matches the full key or any dot-segment)
vigolium config view 'oast*'
vigolium config view 'kno*'          # → known_issue_scan.*

# Reveal redacted secrets (tokens, API keys) with --force / -F
vigolium config view notify -F
```

Set values with dot-notation keys — the three forms below are equivalent, so you can copy a line straight out of `config view` output:

```bash theme={null}
vigolium config set notify.enabled true
vigolium config set database.driver postgres
vigolium config set server.service_port 8080

# List-valued keys take comma-separated values
vigolium config set notify.severities high,critical

# 'key = value' and 'key=value' also work (paste-friendly)
vigolium config set 'oast.server_url = your-oast-domain.com'
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `config view` sorts keys and prints the active config file path at the bottom. Sensitive values show as `[redacted]` unless you pass `-F/--force`. `config set` validates the key and writes it back to the same file. Reset everything to clean defaults with `vigolium config clean`. See [Configuration](/getting-started/configuration) for the full key reference.
</Callout>

***

## 16. Set a custom OAST domain

Out-of-band callback detection (SSRF, blind RCE, OOB SQLi, etc.) uses an [interactsh](https://github.com/projectdiscovery/interactsh) server, `oast.pro` by default. Point Vigolium at your own server with the `oast.server_url` / `oast.token` config keys:

```bash theme={null}
# Point Vigolium at your own interactsh / OAST server
vigolium config set oast.server_url your-oast-domain.com
vigolium config set oast.token your-oast-token
```

Or set it directly in `~/.vigolium/vigolium-configs.yaml`:

```yaml theme={null}
oast:
  enabled: true
  server_url: your-oast-domain.com
  token: your-oast-token
```

Config values support `${VAR}` / `${VAR:-default}` expansion, so you can keep the domain and token in environment variables instead of writing them into the file:

```yaml theme={null}
oast:
  server_url: ${VIGOLIUM_OAST_DOMAIN:-oast.pro}
  token: ${VIGOLIUM_OAST_TOKEN}
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  OAST is enabled by default (`oast.enabled: true`). The token is optional (only needed by servers that require auth). See the full field list, poll interval, grace period, and blind-XSS payload source, in [Configuration → `oast`](/getting-started/configuration#oast).
</Callout>

***

## 17. Generate a static HTML report

Add `--format html` with `-o/--output` to render a self-contained, ag-grid HTML report. You can produce it **during a scan**, or after the fact from data already stored or imported.

```bash theme={null}
# During a scan (combine formats, e.g. jsonl,html)
vigolium scan -t https://example.com --format html -o report.html

# From data already in the database
vigolium export --format html -o report.html --report-title "Acme Q3 Scan"

# From an imported audit / JSONL / SQLite, in one step
vigolium import ./audit-output/ --format html -o report.html

# One consolidated report across many standalone scan files (no import needed)
vigolium export --glob-db 'scans/*.sqlite' --format html -o report.html
```

Brand and filter the report with the same flags across `export` / `import`:

```bash theme={null}
vigolium export --format html -o report.html \
  --report-title "Acme External Scan" \
  --report-target https://acme.example.com \
  --severity critical,high \
  --search sqli
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  HTML requires `-o/--output`. Other report formats: `report`, `pdf` (rendered via headless Chrome), and `markdown` (alias `md`). The output path accepts `gs://<project>/<key>` URLs and a `{ts}` timestamp placeholder. See [Output & Reporting → HTML](/getting-started/output-and-reporting#html).
</Callout>

***

## 18. Notify (webhook) when a scan completes

The `webhook` notify provider fires **one POST per scan** when it reaches a terminal state (completed or failed), regardless of severity, perfect for CI pipelines and dashboards.

```bash theme={null}
# Fire a webhook POST when each scan finishes
vigolium config set notify.enabled true
vigolium config set notify.provider webhook
vigolium config set notify.webhook.url https://hooks.example.com/vigolium
```

Or configure it in `~/.vigolium/vigolium-configs.yaml`:

```yaml theme={null}
notify:
  enabled: true
  provider: webhook               # webhook | telegram | discord ("" = all configured)
  webhook:
    url: https://hooks.example.com/vigolium
    authorization: "Bearer xxx"   # optional Authorization header
    timeout_sec: 10
  severities: [high, critical]    # gate the per-finding telegram/discord alerts
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `webhook` fires once per scan regardless of severity; `telegram` and `discord` instead fire **per finding**, gated by `notify.severities`. Telegram/Discord also honor env-var fallbacks (`TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`, `DISCORD_WEBHOOK_URL`), so you can keep tokens out of the config file. See [Configuration → `notify`](/getting-started/configuration#notify).
</Callout>

***

## 19. Update Vigolium

`vigolium update` re-runs the official installer to fetch the latest release binary, then refreshes the local nuclei-templates checkout used by the known-issue scan.

```bash theme={null}
# Update the binary + nuclei templates to the latest release
vigolium update

# Only refresh nuclei templates (skip the binary)
vigolium update --skip-binary

# Only reinstall the binary (skip templates)
vigolium update --skip-templates

# Check the version you're running
vigolium version
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `vigolium update` runs the same installer as `curl -fsSL https://vigolium.com/install.sh | bash`, installing to `~/.local/bin/vigolium` (checksum-verified). **Homebrew, npm, and Docker** installs upgrade through their own tooling instead: `brew upgrade vigolium`, `npm update -g @vigolium/vigolium`, or `docker pull j3ssie/vigolium:latest`. Vigolium also checks for a newer release on startup (at most once/day); silence it with `VIGOLIUM_DISABLE_UPDATE_CHECK=1`, or auto-apply and re-exec with `VIGOLIUM_AUTO_UPDATE=1`.
</Callout>

***

## 20. Install the Vigolium Burp extension

The Burp extension forwards traffic you browse/proxy in Burp Suite into a running Vigolium server, so it lands in the database (and, with `--mirror-fs`, on disk) for scanning and agent triage.

<Steps>
  <Step title="Download the extension JAR">
    Grab the latest `.jar` from the releases page: [github.com/vigolium/burp-vigolium/releases](https://github.com/vigolium/burp-vigolium/releases/tag/0.1.0)
  </Step>

  <Step title="Load it into Burp Suite">
    In Burp, go to **Extensions → Installed → Add**. Set **Extension type: Java**, then **Select file...** and choose the downloaded `.jar`. Click **Next** — a **Vigolium** tab appears.
  </Step>

  <Step title="Point it at your Vigolium server">
    Start an ingestion server and enter its URL (and API key, if set) in the extension's Vigolium tab:

    ```bash theme={null}
    # Start the ingestion server (add --mirror-fs to also write traffic to disk)
    vigolium server --mirror-fs output-dir -A
    ```
  </Step>

  <Step title="Browse — traffic flows into Vigolium">
    Every request/response Burp sees is forwarded and persisted. Scan it passively as it arrives, or mirror it to files for your agent.
  </Step>
</Steps>

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Pairs naturally with [section 1 (live filesystem mirror)](#1-mirror-ingested-traffic-findings-to-a-live-filesystem-tree) and [section 3 (passive/secret scan on forwarded traffic)](#3-passive-secret-scan-on-forwarded-traffic): run `vigolium server -S --passive-only --mirror-fs output-dir -A` and the extension feeds it while findings and readable request/response files appear in real time.
</Callout>

***

## 21. Triage findings with a coding agent (Claude, Codex)

Vigolium is built to be shelled out to by an LLM/coding agent. The `finding` and `traffic` read commands emit **compact, token-aware** output under `-j/--json` (headers kept, bodies bounded to \~1–2 KB with `body_size`/`body_sha256`/`body_truncated`, binary bodies stubbed, findings windowed to a `response_evidence` snippet), so an agent can survey dozens of findings without blowing its context window and pull full detail only for the ones worth confirming.

Teach your agent to drive Vigolium by installing the **`vigolium-scanner` skill**. The copy embedded in your binary always matches the CLI version, so prefer the native installer:

```bash theme={null}
# Install the embedded skill (recommended — version-matched to your binary)
vigolium skills install --agent claude --scope project   # --agent claude|codex|agents, --scope project|global
vigolium skills                                          # list what's bundled

# Or pull the latest from the repo (github.com/vigolium/skills)
bunx skills add vigolium/skills --skill vigolium-scanner --agent <agent-name> --yes
```

A two-pass triage loop that keeps tokens in check:

```bash theme={null}
# Pass 1 — cheap survey: rank many findings, only the fields you need.
vigolium finding --min-severity high --json --compact \
  --fields id,severity,module_id,url,matched_at

# Pass 2a — deep-read one finding as a self-contained, parseable bundle
# (finding + linked request/response embedded, bodies still bounded).
vigolium finding --id 42 --json --with-records

# Pass 2b — deep-read as Markdown (verbatim request/response in fenced http blocks,
# plus the What/Exploit/Fix prose) — often the nicest format for an agent or a
# human to judge a single finding. Window it with -S --compact so a big page
# doesn't flood the context.
vigolium finding -S --db ./scan.jsonl --id 42 --markdown --compact
```

Output-shaping flags on `finding` / `traffic` / `db ls`:

| Flag                           | Effect                                                                                                                                                     |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-j`/`--json`                  | machine-readable compact output (the entry point)                                                                                                          |
| `--compact`                    | metadata only, drop bodies — cheapest survey pass                                                                                                          |
| `--fields a,b,c`               | project to just these top-level keys, cuts tokens hard                                                                                                     |
| `--with-records`               | *(finding)* embed the linked HTTP records → self-contained triage bundle                                                                                   |
| `--full-body`                  | complete decoded bodies (use when writing an exploit — see [section 22](#22-show-how-to-exploit-a-finding)); also un-compacts `--markdown` response bodies |
| `--markdown`                   | render the finding with request/response in fenced `http` blocks (response bodies compacted to a preview by default)                                       |
| `--tree` *(finding / traffic)* | host/path hierarchy view; recurring findings collapse by title + severity into one `×N` node                                                               |
| `--pick 2-4` *(finding)*       | narrow to specific 1-based positions after filters + sort (`2`, `1,3`, `2-4`); composes with `--raw`/`--burp`/`--markdown`/`--json`                        |
| `--search a --search b`        | repeatable, AND-combined — each added term further narrows the match                                                                                       |
| `--min-severity high`          | filter to the severities that matter                                                                                                                       |
| `--agentic-scan <uuid>`        | only findings from a given agent run (expands to the whole run tree)                                                                                       |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  Under `--json`, bodies are **always** bounded regardless of `-S`. As of v0.2.1, `--markdown` also **compacts response bodies by default** — the response renders as a window around the finding's `matched_at`/evidence (or a leading preview) rather than a whole page, regardless of `-S`/`--compact`; pass `--full-body` to render bodies whole. The request is always shown whole (it carries the payload). On an interactive terminal the Markdown is syntax-highlighted; piped/redirected output stays plain, greppable Markdown. An agent run (`agent autopilot|swarm|audit`) under `--json` even prints a ready-made follow-up command in its summary: `vigolium finding --agentic-scan <uuid> --json --with-records`. Full guide: [Using Vigolium in your agent](/agentic-scan/using-vigolium-in-your-agent).
</Callout>

***

## 22. Show how to exploit a finding

Once a finding is confirmed, pull the exact request that triggered it, then re-fire it (mutating the payload) to build a reproducible proof-of-concept. Start by fetching the finding with full, decoded bodies so you have the complete request to work from:

```bash theme={null}
# Self-contained bundle with COMPLETE bodies — everything needed to write an exploit.
vigolium finding --id 42 --json --with-records --full-body

# Or as a report-ready Markdown PoC (request/response in fenced http blocks).
# --markdown compacts response bodies by default; add --full-body for the whole page.
vigolium finding --id 42 --markdown --full-body > finding-42.md
```

Reproduce and iterate the payload by replaying the finding's linked record. `vigolium replay --finding-id` re-sends the request behind a finding, and `-m/--mutate` lets you change one insertion point at a time to prove exploitability:

```bash theme={null}
# Re-fire the exact request that produced finding 42, human-readable summary.
vigolium replay --finding-id 42 --pretty

# Prove the injection: mutate one insertion point with your payload.
vigolium replay --finding-id 42 --pretty \
  -m "id=,type=query,payload=1 OR 1=1--"

# Send the reproduction through Burp so you can inspect/step it manually.
vigolium replay --finding-id 42 --proxy http://127.0.0.1:8080

# Point the same request at a staging host, carrying an auth session.
vigolium replay --finding-id 42 --pretty \
  --target https://staging.example.com --auth-session my-session
```

If you mirrored traffic to disk ([section 1](#1-mirror-ingested-traffic-findings-to-a-live-filesystem-tree)) or used `--format fs`, each `<id>.req` file is **directly replayable**: its leading `@target <scheme>://<authority>` line names the destination, so strip line 1 to get raw HTTP you can hand to `curl`, an agent, or feed back into `vigolium replay --raw-request-file <file>` (pass the target from that first line with `-t`).

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  With the [`vigolium-scanner` skill](#21-triage-findings-with-a-coding-agent-claude-codex) installed, you can ask your agent in plain language — *"confirm finding 42 is exploitable and give me a PoC"* — and it will run the `finding` + `replay` commands above, mutate the payload, and compare responses for you. `-m/--mutate` accepts `name=…,type=…,payload=…` (or `name:type:payload`) and is repeatable; `--raw-request`/`-i` replace the whole request when you need full control. Only test targets you are authorized to assess.
</Callout>

***

## 23. Run an exact set of modules (passive-only, JS beautify)

[Section 9](#9-target-one-vulnerability-class-or-technology)'s `-m/--modules` is a **fuzzy** filter that only narrows the **active** modules (passive modules always stay "all"). When you want to run a **precise** set — including passive modules on their own — reach for `--module-id` (exact match against **both** the active and passive registries, repeatable) and `--passive-only`.

```bash theme={null}
# Run EXACTLY these modules and nothing else (repeatable, or comma-separated)
vigolium scan-url -S -t https://example.com --module-id js-beautify --module-id secret-detect
vigolium scan-url -S -t https://example.com --module-id js-beautify,secret-detect

# JavaScript beautify only — unminify/unpack a bundle into readable modules
vigolium scan-url -S -t https://example.com/app.min.js --module-id js-beautify

# Passive modules only — no active traffic is sent (secrets, headers, disclosure, ...)
vigolium scan-url -S -t https://example.com --passive-only

# Passive-only, narrowed to a specific passive module
vigolium scan-url -S -t https://example.com --passive-only --module-id secret-detect
```

`-m` vs `--module-id`, side by side:

| Flag               | Matching                     | Registries it selects from            | Repeatable |
| ------------------ | ---------------------------- | ------------------------------------- | ---------- |
| `-m` / `--modules` | fuzzy (substring on id/name) | **active** only (passive stays "all") | yes        |
| `--module-id`      | **exact** module ID          | **both** active **and** passive       | yes        |

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--module-id` requires an **exact** id — an unknown value warns (`does not match any known module`) rather than silently matching nothing, so reach for `-m` when you want loose matching. Find exact ids with `vigolium module ls <term>`. `--passive-only` and `--no-passive` are mutually exclusive (nothing would run). Available on `scan`, `scan-url`, and `scan-request`. For fuzzy `-m` / `--module-tag` filtering, see [section 9](#9-target-one-vulnerability-class-or-technology).
</Callout>

***

## 24. Scan a URL and print findings to the console

For a quick single-URL scan where you just want the results on screen, add `--print-finding`. After the scan it renders each finding to stdout as **Markdown** — description, matched evidence, and the raw request/response in fenced `http` blocks — exactly like `vigolium finding --markdown` ([section 21](#21-triage-findings-with-a-coding-agent-claude-codex)), with no follow-up command and nothing persisted. Pair it with `-S` (throwaway database) and `--silent` (drop the banner and progress noise) for clean output.

```bash theme={null}
# Quick scan → findings printed inline as Markdown, nothing persisted
vigolium scan-url -S -t https://example.com -m js-beautify -m secret-detect --silent --print-finding

# Same, but pin the EXACT modules (--module-id also restricts passive; see section 23)
vigolium scan-url -S -t https://example.com \
  --module-id js-beautify --module-id secret-detect \
  --silent --print-finding

# Passive-only sweep of one URL, printed to the console
vigolium scan-url -S -t https://example.com --passive-only --silent --print-finding

# Also dump the scan's HTTP traffic — as a host/path tree, or raw request/response pairs
vigolium scan-url -S -t https://example.com --silent --print-traffic-tree
vigolium scan-url -S -t https://example.com --silent --print-traffic
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  `--print-finding` works on `scan`, `scan-url`, `scan-request`, and `run`. It prints **nothing** when the scan finds nothing, so `--silent --print-finding` yields either the findings or an empty screen — ideal for a fast triage loop. The Markdown is identical to `vigolium finding --markdown` ([section 21](#21-triage-findings-with-a-coding-agent-claude-codex)); to save it, redirect stdout (`... --print-finding > findings.md`). Enabling it routes the scan through the full runner so each finding's linked request/response is available to render, which is why it pairs naturally with `-S`. The same commands take **`--print-traffic-tree`** (host/path hierarchy, like `traffic --tree`) and **`--print-traffic`** (raw request/response pairs, like `traffic --raw`) to dump the run's traffic after it finishes — set both to print the tree first, then the raw pairs.
</Callout>

***

## 25. View HTTP traffic in the database

Everything Vigolium scans, ingests, or records lands in the database. Browse it with `vigolium traffic` (aliases `tf`, and `vigolium db ls --table http_records`). With no flags it shows the 100 most recent records, newest first; add filters, search, or a display format to narrow and shape the output.

```bash theme={null}
# Browse recent traffic (newest first, capped at 100)
vigolium traffic

# List EVERY stored record (lift the -n/--limit cap), or page through
vigolium traffic --all
vigolium traffic -n 50 --offset 100

# Host/path hierarchy tree
vigolium traffic tree
```

Search and filter to find the records you care about:

```bash theme={null}
# Fuzzy search across URLs, paths, and hosts (positional term or --search)
vigolium traffic admin
vigolium traffic --search "/api/users"

# Search within header names/values, or request/response body content
vigolium traffic --header "Authorization"
vigolium traffic --body "password"

# Filter by host, status, method, path, source, or date range
vigolium traffic --host "*.example.com"
vigolium traffic --status 401,403,500 --method POST
vigolium traffic --source ingest-proxy
vigolium traffic --from 2026-01-01 --to 2026-02-01

# Combine filters: POSTs to the API that returned 200 and leaked a token
vigolium traffic --host api.example.com --method POST --body "token" --status 200
```

Choose how each record is rendered:

```bash theme={null}
# Burp Suite-style colored request/response, or full raw HTTP
vigolium traffic --burp --host example.com -n 5
vigolium traffic --raw --host example.com -n 5

# Pick / drop columns
vigolium traffic --columns host,method,path,status,size
vigolium traffic --exclude-columns source,words

# Machine-readable JSON for scripting / jq (compact, token-aware bodies)
vigolium traffic -j
vigolium traffic --host api.example.com --status 200 -j
```

Read a colleague's standalone export without touching your own DB by pointing `-S` at the file (a `.jsonl` export or a standalone `.sqlite`), or read across many at once with `--glob-db`:

```bash theme={null}
vigolium traffic -S --db scan.sqlite
vigolium traffic --glob-db 'scans/*.sqlite'
```

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  All filter flags (`--host`, `--status`, `--method`, `--path`, `--source`, `--search`, `--header`, `--body`, `--from`/`--to`) stack, and `--sort` + `--asc` control ordering. Add `--replay` to re-send the matched records instead of listing them (see [section 2](#2-replay-all-stored-traffic-through-burp-suite)). The compact `-j/--json` output is the same agent-friendly serializer described in [section 21](#21-triage-findings-with-a-coding-agent-claude-codex).
</Callout>

***

## 26. Set up the AI agent (Codex or Claude CLI)

Vigolium's AI features (autopilot, swarm, source-code audit, query) all run through one in-process runtime called **olium**, which talks to a provider. Pick one provider and give it credentials. The two most common setups are below; verify any of them with `vigolium ol -p 'what model are you running'`.

**Method 1 — Codex (cheapest, with a ChatGPT subscription).** If you already use OpenAI's **Codex CLI**, vigolium reuses the same OAuth credential file, no API key, refresh handled automatically. This is the recommended default.

```bash theme={null}
# 1. Install the Codex CLI (one-time) and log in.
codex login
codex exec 'hello'             # sanity check — should print a model name

# 2. Pin vigolium to it (defaults already match; this just makes it explicit).
vigolium config set agent.olium.provider openai-codex-oauth
vigolium config set agent.olium.oauth_cred_path ~/.codex/auth.json
vigolium config set agent.olium.model gpt-5.5

# 3. Verify.
vigolium ol -p 'what model are you running'
```

**Method 2 — Claude CLI (`claude` shell-out).** Delegate to the `claude` binary on your `$PATH`, so olium uses whatever auth `claude` itself is configured with (plus your personal `CLAUDE.md`, MCP servers, and installed skills).

```bash theme={null}
which claude   # must resolve

vigolium config set agent.olium.provider anthropic-cli   # alias: anthropic-claude-cli
vigolium config set agent.olium.model claude-opus-4-7

vigolium ol -p 'what model are you running'
```

Once `vigolium ol` returns a model name, every agent command works: `vigolium agent autopilot`, `vigolium agent swarm`, `vigolium agent query`, and `vigolium agent audit`.

<Callout icon="circle-info" color="#3B82F6" iconType="regular">
  These are two of several providers, olium also supports the Claude Code Agent SDK bridge, Anthropic OAuth/API-key, and any OpenAI-compatible backend (Ollama, OpenRouter, LM Studio, vLLM). For the full provider matrix, credential handling, and the source-code audit drivers, see the setup guide, starting with the recommended Codex path: [Set up the agent → Codex](https://docs.vigolium.com/getting-started/setup-agent#2-codex-cheapest-with-a-chatgpt-subscription-recommended).
</Callout>

***

<Callout icon="key" color="#8B5CF6" iconType="regular">
  **Oh dear, you actually read to the end.** Here's the secret the config file
  kept nudging you toward: by default every Vigolium request announces itself
  with a `Vigolium/<version>` User-Agent, so a friendly blue team can spot your
  authorized scan in their logs in seconds. Go full ninja only when you *mean*
  to be sneaky:

  ```bash theme={null}
  # Persist it in your config
  vigolium config set scanning_strategy.http.user_agent random

  # Or a one-off via env var (overrides the config value for that run)
  export VIGOLIUM_DEFAULT_UA=random
  ```
</Callout>
