# How SkillSpector Handles Different Output Formats for Scan Results

> SkillSpector expertly manages scan results across multiple formats. Learn how it supports terminal, JSON, Markdown, and SARIF outputs via the `--format` CLI flag for flexible reporting.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-07-12

---

**SkillSpector routes scan findings through a centralized report node that dispatches to format-specific helpers based on the `--format` CLI flag, supporting terminal, JSON, Markdown, and SARIF outputs.**

NVIDIA's SkillSpector implements a flexible reporting pipeline that converts scan findings into multiple **output formats for scan results**. The system uses a graph-based architecture where a single report node selects the appropriate formatter based on user input. This design allows security teams to consume vulnerability data in whatever format best fits their workflow—whether human-readable terminal output or machine-readable SARIF for CI integration.

## CLI Format Parsing and State Initialization

The format selection begins in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py), where the `FormatChoice` **StrEnum** defines the supported options: `terminal`, `json`, `markdown`, and `sarif` (lines 75‑82). The `--format` (or `-f`) argument captures the user’s selection and stores it in the graph state.

When the scan initializes, the `_scan_state` function creates the state dictionary and inserts the selected format under the key `output_format` (lines 28‑34).

```python

# From src/skillspector/cli.py

class FormatChoice(StrEnum):
    terminal = "terminal"
    json = "json"
    markdown = "markdown"
    sarif = "sarif"

# Parsed via --format and stored in state

```

## Report Node Dispatch Architecture

The `report` node in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) serves as the central dispatcher. It retrieves `state["output_format"]` (defaulting to `"sarif"` if unspecified) and branches to the appropriate formatter helper via an `if/elif/else` block starting at line 44 (lines 44‑90).

The dispatch logic follows this precedence:

1. **`terminal`** → Calls `_format_terminal` for Rich-styled console output.
2. **`json`** → Calls `_format_json` for structured JSON reports.
3. **`markdown`** → Calls `_format_markdown` for human-readable documentation.
4. **fallback** → Calls `_build_sarif` to generate SARIF 2.1.0 compliant JSON.

```python

# From src/skillspector/nodes/report.py

output_format = state.get("output_format") or "sarif"
if output_format == "terminal":
    report_body = _format_terminal(...)
elif output_format == "json":
    report_body = _format_json(...)
elif output_format == "markdown":
    report_body = _format_markdown(...)
else:
    report_body = json.dumps(sarif_report, indent=2)

```

### Terminal Output with Rich Formatting

The `_format_terminal` helper (lines 8‑23) uses the **Rich** library to construct colored tables and panels. This produces an interactive console view with risk scores, component lists, and styled findings optimized for terminal readability.

### Structured JSON Reports

The `_format_json` function (lines 38‑53) assembles a Python dictionary containing scan metadata and findings, then serializes it using `json.dumps(..., indent=2)`. This produces formatted JSON suitable for programmatic parsing by downstream tools.

### Human-Readable Markdown

For documentation workflows, `_format_markdown` (lines 66‑76) generates markdown strings including risk tables, component tables, and per-finding sections. This allows direct inclusion of scan results into README files or security documentation.

### SARIF 2.1.0 Compliance

The `_build_sarif` helper creates SARIF-compatible output using data classes defined in [`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py) (report.py lines 16‑22). This format follows the OASIS SARIF standard, enabling integration with security platforms like GitHub Advanced Security and Azure DevOps.

## Output Delivery and File Handling

After the report node generates the `report_body`, the `_write_result` function in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) (lines 55‑67) handles final delivery. If the format is `terminal`, the Rich-rendered output prints directly to stdout. For all other formats (`json`, `markdown`, `sarif`), the raw string is emitted to either stdout or the file path specified by the `--output` option.

## Practical Usage Examples

Invoke SkillSpector with different output formats using the CLI:

```bash

# Terminal output (explicit)

skillspector scan ./my-skill/ --format terminal

# JSON report to file

skillspector scan ./my-skill/ --format json --output report.json

# Markdown redirection

skillspector scan ./my-skill/ -f markdown > report.md

# SARIF output (default behavior)

skillspector scan ./my-skill/ -f sarif > report.sarif

```

## Summary

- SkillSpector supports four distinct **output formats for scan results**: terminal, JSON, Markdown, and SARIF.
- The `FormatChoice` enum in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) defines available formats and validates CLI input.
- The report node in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) dispatches to specialized formatters based on the `output_format` state key.
- **SARIF** serves as the default format when no explicit choice is provided.
- Terminal output leverages Rich for styling, while other formats emit raw strings suitable for file storage or piping.

## Frequently Asked Questions

### What is the default output format if I don't specify one?

SARIF is the default format. According to the dispatch logic in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py), the code calls `state.get("output_format") or "sarif"`, ensuring that missing or undefined format selections always fall back to SARIF 2.1.0 JSON output.

### How does SkillSpector handle terminal output differently from file formats?

The `_write_result` function checks the format type before writing. For `terminal`, it prints the Rich-rendered output directly to stdout. For JSON, Markdown, or SARIF, it writes the raw string content, allowing these formats to be redirected to files or piped to other tools without Rich markup artifacts.

### Can I export scan results to a file instead of stdout?

Yes. Use the `--output` (or `-o`) flag to specify a destination file path. The `_write_result` method in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) handles file I/O for all non-terminal formats, writing the `report_body` string to the specified location.

### Is the SARIF output compatible with standard security analysis tools?

Yes. The `_build_sarif` function generates SARIF 2.1.0 compliant logs using data classes from [`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py). This adheres to the OASIS standard, ensuring compatibility with GitHub Code Scanning, Azure DevOps, and other SARIF-consuming security platforms.