Skip to main content
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.
Every command here works against the open-source binary. vigolium <command> -h prints the full flag list for any subcommand.

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.
# 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/:
PathContents
traffic/<host>/<id>.reqRaw request (leading @target <scheme>://<authority> line, then the request verbatim, replayable by stripping line 1)
traffic/<host>/<id>.resp.headersStatus line + response headers
traffic/<host>/<id>.resp.bodyResponse body (gzip-decoded so it greps clean)
traffic/<host>/index.jsonlAppend-only, jq-friendly map of ids → method/url/status/content-type
findings/<host>/<id>.mdEach finding, cross-linked to its .req file
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).
Read it back from an agent or shell:
# 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.
# 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):
# 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
--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.

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.
# 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:
FlagBehavior
-S / --scan-on-receiveContinuously scans new records with the dynamic-assessment phase (active + passive modules).
-S --passive-onlyPassive modules only, no active traffic. Includes secret detection, security headers, cookie flags, disclosure, etc.
-S --full-native-scan-on-receiveRuns the full native pipeline (discovery + spidering + dynamic-assessment) on received records.
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.

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.
# 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"
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.

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

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

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

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

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

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.
# 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:
PhaseAliases
discoverydeparos, discover
spideringspitolas
known-issue-scancve, kis, known-issues
dynamic-assessmentaudit, dast, assessment
extensionext
external-harvest, ingestion
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.

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.
# 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
--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 for the vigolium.* API.

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.
# 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:
# 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
vigolium run <phase> runs one phase in isolation (discover is an alias for discovery; see section 10 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.

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.
# 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'
For richer authenticated scans (login flows, token refresh, multi-step sessions), use an auth session file instead, see Authentication and the vigolium auth command.

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.
# 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
FlagDefaultEffect
--scanning-max-duration0 (use config)Hard cap on total scan wall-clock time (e.g. 30m, 1h, 2h)
-c / --concurrency50Number of concurrent scan workers
-r / --rate-limit100Maximum HTTP requests per second (global)
--max-per-host50Maximum concurrent requests to any single host
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.

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.
# 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:
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'
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 for the full key reference.

16. Set a custom OAST domain

Out-of-band callback detection (SSRF, blind RCE, OOB SQLi, etc.) uses an interactsh server, oast.pro by default. Point Vigolium at your own server with the oast.server_url / oast.token config keys:
# 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:
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:
oast:
  server_url: ${VIGOLIUM_OAST_DOMAIN:-oast.pro}
  token: ${VIGOLIUM_OAST_TOKEN}
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.

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.
# 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:
vigolium export --format html -o report.html \
  --report-title "Acme External Scan" \
  --report-target https://acme.example.com \
  --severity critical,high \
  --search sqli
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.

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

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

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.
1

Download the extension JAR

Grab the latest .jar from the releases page: github.com/vigolium/burp-vigolium/releases
2

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.
3

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:
# Start the ingestion server (add --mirror-fs to also write traffic to disk)
vigolium server --mirror-fs output-dir -A
4

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.
Pairs naturally with section 1 (live filesystem mirror) and section 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.

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:
# 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:
# 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:
FlagEffect
-j/--jsonmachine-readable compact output (the entry point)
--compactmetadata only, drop bodies — cheapest survey pass
--fields a,b,cproject to just these top-level keys, cuts tokens hard
--with-records(finding) embed the linked HTTP records → self-contained triage bundle
--full-bodycomplete decoded bodies (use when writing an exploit — see section 22); also un-compacts --markdown response bodies
--markdownrender 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 brepeatable, AND-combined — each added term further narrows the match
--min-severity highfilter to the severities that matter
--agentic-scan <uuid>only findings from a given agent run (expands to the whole run tree)
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.

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:
# 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:
# 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) 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).
With the vigolium-scanner skill 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.

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

Section 9’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.
# 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:
FlagMatchingRegistries it selects fromRepeatable
-m / --modulesfuzzy (substring on id/name)active only (passive stays “all”)yes
--module-idexact module IDboth active and passiveyes
--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.

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), 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.
# 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
--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); 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.

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.
# 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:
# 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:
# 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:
vigolium traffic -S --db scan.sqlite
vigolium traffic --glob-db 'scans/*.sqlite'
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). The compact -j/--json output is the same agent-friendly serializer described in section 21.

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.
# 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).
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.
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.

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