# How to Scan Skills from Git URLs or Compressed Archives with NVIDIA SkillSpector

> Easily scan skills from Git URLs or compressed archives with NVIDIA SkillSpector. Learn how to analyze code efficiently and gain insights into your project's capabilities.

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

---

**SkillSpector accepts Git repository URLs, ZIP archives, direct file URLs, and local directories, automatically normalizing them to local paths before analysis.**

NVIDIA SkillSpector is an open-source security analysis tool that evaluates AI skill bundles for potential vulnerabilities. Whether your skills reside in a remote Git repository, a downloadable ZIP archive, or a local directory, the tool's **InputHandler** class transparently manages the ingestion process. This article explains how to scan skills from Git URLs or compressed archives using the specific implementation details found in the NVIDIA/SkillSpector repository.

## Input Detection and Normalization

The `InputHandler` class in [`src/skillspector/input_handler.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/input_handler.py) serves as the entry point for all source ingestion. It examines the supplied path, normalizes it to a local directory, and passes that directory to the LangGraph-based analysis pipeline.

### Detecting Git URLs

The `_is_git_url()` method checks whether the supplied string matches known Git hosting patterns. It supports **github.com**, **gitlab.com**, **bitbucket.org**, or any URL ending with `.git`.

### Cloning Repositories

When a Git URL is detected, the handler delegates to `_clone_git()`. This method performs a shallow `git clone --depth 1` into a temporary directory created by `_get_temp_dir()`. The clone result is returned as a `Path` object with the source type `"git"` recorded for provenance tracking.

### Handling ZIP Archives

For paths ending with `.zip`, the handler calls `_extract_zip()`. The archive unpacks into a temporary directory. If the ZIP contains a single top-level folder, that folder is returned directly; otherwise, the entire extraction directory is used.

### Downloading File URLs

For non-Git HTTP(S) URLs, `_download_file()` retrieves the content via `httpx`. If the response indicates a ZIP file (by extension or `Content-Type`), the download routes through `_extract_zip()`. Otherwise, the file saves into a temporary directory and the temp dir path is returned.

## CLI Integration and Workflow

The `scan` command in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) orchestrates the entire workflow. It builds an initial graph state (`_scan_state`) containing the raw `input_path`. The graph immediately invokes `InputHandler.resolve()`, which returns the resolved local path fed to the rest of the analysis workflow.

## Automatic Cleanup

After the LangGraph pipeline finishes execution, temporary directories are removed via `InputHandler.cleanup()`. The CLI indirectly triggers this through `_cleanup_result()`, ensuring cloned repositories and extracted archives do not persist on disk.

## Practical Examples

### Scan a Public Git Repository

```bash
skillspector scan https://github.com/example/my-skill

```

The CLI passes the URL to `InputHandler`. The `_is_git_url()` method recognizes the pattern, triggering `_clone_git()` to perform a shallow clone into a temporary folder before analysis begins.

### Scan a Remote ZIP Archive

```bash
skillspector scan https://example.com/archives/my-skill.zip --format json --output report.json

```

The URL routes to `_download_file()`, which detects the ZIP format and delegates to `_extract_zip()`. The extracted contents are analyzed and results written to [`report.json`](https://github.com/NVIDIA/SkillSpector/blob/main/report.json).

### Scan a Local ZIP File

```bash
skillspector scan ./downloads/my-skill.zip -f sarif -o findings.sarif

```

Because the path ends with `.zip`, `InputHandler.resolve()` calls `_extract_zip()` directly without network traffic. The archive unpacks locally and the scan proceeds.

### Scan a Single Markdown File

```bash
skillspector scan ./my-skill/SKILL.md --no-llm

```

Single files are wrapped in a temporary folder via internal handling so downstream nodes treat them as directories. The `--no-llm` flag disables LLM-based analysis, running only static checks.

## Summary

- **InputHandler** in [`src/skillspector/input_handler.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/input_handler.py) automatically detects Git URLs, ZIP archives, and file URLs, normalizing all inputs to local directories.
- Git repositories are cloned with `--depth 1` for efficiency using `_clone_git()`.
- ZIP archives extract into temporary directories via `_extract_zip()`, with smart handling of single-root archives.
- The `scan` command in [`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py) manages the workflow through `_scan_state` and ensures cleanup via `_cleanup_result()`.
- All temporary files are removed after analysis completes, preventing disk pollution.

## Frequently Asked Questions

### Does SkillSpector support private Git repositories?

Currently, the `_clone_git()` method performs shallow clones of public repositories. For private repositories, you must clone them manually to a local directory and scan that path instead, as the current implementation does not handle authentication tokens in the URL.

### What archive formats are supported besides ZIP?

According to the source code in [`src/skillspector/input_handler.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/input_handler.py), the `_extract_zip()` method specifically handles `.zip` extensions. Other formats like `.tar.gz` or `.7z` are not natively supported and should be extracted manually before scanning.

### How does SkillSpector handle large ZIP files downloaded from URLs?

The `_download_file()` method uses `httpx` for streaming downloads, writing content to a temporary directory. Large files are supported as long as sufficient disk space exists in the system's temp directory, though the tool does not implement specific size limits in the current codebase.

### Where are temporary files stored during analysis?

Temporary directories are created using `_get_temp_dir()`, which utilizes the system's standard temporary directory location. These directories are automatically removed by `InputHandler.cleanup()` after the LangGraph analysis pipeline completes, regardless of success or failure.