# How refresh-tool-index.ps1 Generates the Reverse-Skill Tool Index: A PowerShell Automation Deep Dive

> Learn how refresh-tool-index.ps1 generates the Reverse-Skill tool index. Discover its process of tool discovery, filtering, mapping, and output generation for developers and automation.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: deep-dive
- Published: 2026-08-16

---

**`refresh-tool-index.ps1` generates the Reverse-Skill tool index by discovering external tools through a helper library, filtering them against documented skills, combining static script mappings, and rendering both a markdown table for developers and a JSON payload for automated routing.**

The `refresh-tool-index.ps1` script sits at the heart of the [zhaoxuya520/reverse-skill](https://github.com/zhaoxuya520/reverse-skill) repository's tool management system. This PowerShell automation creates a living catalogue of every reverse-engineering utility the project can invoke—ensuring that both human developers and automated pipelines can quickly determine tool availability, versioning, and routing eligibility.

## How the Tool Index Generation Works

The script follows an 11-step pipeline that transforms scattered tool configurations into unified, queryable artefacts. Understanding this `refresh-tool-index.ps1` generation process is essential for contributors who need to add new skills or debug tool detection failures.

### Step 1: Load the Discovery Library

Every execution starts by importing the shared tooling functions. The script sources `lib/ToolDiscovery.ps1` to gain access to three critical functions: `Get-ReverseToolReport`, `Get-ReverseCapabilityState`, and `Resolve-ReverseToolSpec`.

```powershell
. (Join-Path $PSScriptRoot 'lib\ToolDiscovery.ps1')

```

*(Source: [`refresh-tool-index.ps1#L20`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L20))*

These functions abstract away the complexity of probing external binaries, checking MCP (Model Context Protocol) registration status, and resolving tool specifications from skill metadata.

### Step 2: Define Static Script-to-Tool Mappings

The script declares a hashtable called `$scriptRefs` (lines 22–50) that maps each tool name to the skill scripts that explicitly invoke it. For example, `jadx` links to `apk-reverse/scripts/decode.ps1`. This mapping powers the "脚本引用" (script reference) column in the final markdown table.

### Step 3: Resolve Repository Structure

The script calculates `$skillsRoot` as the parent directory of its own location. This path anchors all subsequent file system operations, particularly the discovery of `<skill>/SKILL.md` documentation files.

```powershell
$skillsRoot = (Get-Item $PSScriptRoot).Parent.Parent.FullName

```

*(Source: [`refresh-tool-index.ps1#L62`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L62))*

### Step 4: Collect and Filter Tool Reports

The core discovery phase calls `Get-ReverseToolReport` to enumerate all known tools. However, the pipeline aggressively filters these results—keeping only tools whose associated skill directory contains a valid [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file.

```powershell
$reports = @(Get-ReverseToolReport | Where-Object {
    $skill = [string]$_.Skill
    $keep = $true
    if ($keep -and -not [string]::IsNullOrWhiteSpace($skill)) {
        $skillMd = Join-Path $skillsRoot (($skill -replace '/', [IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar + 'SKILL.md')
        if (-not (Test-Path -LiteralPath $skillMd)) { $keep = $false }
    }
    $keep
})

```

*(Source: [`refresh-tool-index.ps1#L64-71`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L64-L71))*

This validation step guarantees that undocumented or orphaned tools never appear in the index—maintaining strict coupling between tool availability and human-readable documentation.

### Step 5: Capture Generation Timestamp

The script stores the current date-time in `$generatedAt` (line 73), which appears in the markdown header to help developers identify stale index files.

### Step 6-8: Build and Write the Markdown Table

The script constructs [`tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/tool-index.md) through three phases:

- **Header assembly** (lines 75–85): Creates the document title, scan timestamp, routing description, and table column headers.
- **Row population** (lines 87–96): Iterates through `$reports`, extracting `Name`, `Skill`, `Purpose`, availability status, resolved path, version, source, and static script references—escaping all values for markdown safety.
- **File output** (lines 99–100): Joins all lines and writes to the default path [`../tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/../tool-index.md).

```powershell
$markdownLines += "| $($report.Name) | $($report.Skill) | $($report.Purpose) | $availableText | $escapedPath | $escapedVersion | $($report.Source) | $escapedRefs |"

```

*(Source: [`refresh-tool-index.ps1#L96`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L96))*

### Step 9: Generate Capability Status View

Beyond basic tool listings, the script appends a second markdown table showing runtime capability states. It retrieves predefined capability names (line 103), then for each capability calls `Get-ReverseCapabilityState` and `Resolve-ReverseToolSpec` to determine flags like `Ready`, `MCP 已注册` (MCP registered), `服务在线` (service online), and others (lines 105–126).

```powershell
$markdownCapLines += "| $($cap.name) | $toolText | $readyText | $mcpText | $svcText | $mcpHttpText | $autoText | $kindText |"

```

*(Source: [`refresh-tool-index.ps1#L146-147`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L146-L147))*

This capability view enables the repository's routing logic to make informed decisions about which skill can handle a given request.

### Step 10: Produce the JSON Payload

The script creates `$jsonRows` from the same filtered `$reports` collection, enriches it with capability data, and serializes the complete structure to [`../tool-index.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/../tool-index.json).

```powershell
$jsonPayload | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath $OutputJson -Encoding utf8

```

*(Source: [`refresh-tool-index.ps1#L78`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L78))*

The `-Depth 6` parameter ensures nested objects survive serialization intact—critical for complex capability metadata.

### Step 11: Emit Console Summary

Finally, the script prints the output file paths and total tool count to stdout (lines 80–84), providing immediate feedback in CI/CD pipelines or local development workflows.

## Output Artefacts and Their Purposes

| Artefact | Format | Primary Consumer | Key Contents |
|----------|--------|------------------|--------------|
| [`tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/tool-index.md) | Markdown | Human developers | Sortable table with tool metadata, availability, and script references |
| [`tool-index.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/tool-index.json) | JSON | Automated routers, MCP clients | Machine-parseable array with capability status flags and routing hints |

The JSON file especially matters for the reverse-skill routing system, which queries it to match incoming requests against available tool capabilities without shelling out to PowerShell.

## Key Files Supporting the Generation Pipeline

| File Path | Role in Tool Index Generation |
|-----------|-------------------------------|
| `skills/scripts/refresh-tool-index.ps1` | [Main orchestration script](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1) — drives all generation steps |
| `skills/scripts/lib/ToolDiscovery.ps1` | [Discovery library](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/lib/ToolDiscovery.ps1) — implements `Get-ReverseToolReport`, `Get-ReverseCapabilityState`, `Resolve-ReverseToolSpec` |
| `skills/**/SKILL.md` | Skill documentation gates — existence determines tool inclusion |
| `tools/**` | External binaries discovered at runtime (e.g., `jadx`, `frida`, `r2`) |

## Summary

- **`refresh-tool-index.ps1`** automates tool catalogue maintenance through an 11-step PowerShell pipeline.
- **Discovery** relies on `lib/ToolDiscovery.ps1` functions that probe external binaries and resolve skill metadata.
- **Filtering** enforces documentation discipline—only tools with valid [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) files appear in outputs.
- **Dual output** serves both humans (markdown tables) and machines (JSON with capability routing data).
- **Capability tracking** extends beyond simple availability to include MCP registration and service health states.

## Frequently Asked Questions

### What triggers the need to run refresh-tool-index.ps1?

Run the script whenever you add new tools, modify skill structures, or update [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) files. The index is not automatically rebuilt on every repository change—it's designed for explicit generation to ensure controlled documentation updates. CI pipelines typically execute this script before packaging releases.

### Why does the script filter out tools without SKILL.md files?

The [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) requirement enforces documentation standards. As implemented in [lines 64–72](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/refresh-tool-index.ps1#L64-L72), this filter prevents orphaned tools from appearing in the index—ensuring that every listed utility has human-readable context explaining its purpose, parameters, and usage examples.

### How does the capability status view differ from the basic tool table?

The basic table shows static metadata: name, skill association, purpose, and installation details. The capability view (lines 103–148) adds **runtime state**: whether a tool's MCP server is registered, if its HTTP endpoint is reachable, and whether automatic routing is enabled. This dynamic information powers the repository's request routing decisions.

### Can I customize the output paths for tool-index.md and tool-index.json?

Yes. The script accepts `-OutputMarkdown` and `-OutputJson` parameters (defaults: [`../tool-index.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/../tool-index.md) and [`../tool-index.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/../tool-index.json)). These paths are resolved relative to the script's execution directory, allowing integration with different build environments or monorepo structures.