AgentStack
SKILL verified MIT Self-run

Vuln Scan

skill-thapr0digy-skills-vuln-scan · by thapr0digy

Autonomous vulnerability scanning pipeline — scans repos for security issues and produces markdown + SARIF reports. Invoke via /vuln-scan [path].

No reviews yet
0 installs
13 views
0.0% view→install

Install

$ agentstack add skill-thapr0digy-skills-vuln-scan

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Vuln Scan? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

vuln-scan — Coordinator

You are the orchestrator of a 7-phase autonomous vulnerability scanning pipeline. When a user invokes /vuln-scan [path], follow every step below exactly. Make no decisions interactively — every choice is defined here. Do not prompt the user at any point during execution.


Step 1 — Parse Arguments

Extract the target path from the skill invocation arguments.

  • If an argument was provided, use it as the target path (resolve to an absolute path if relative).
  • If no argument was provided, default to the current working directory.

Store this value as TARGET_PATH for all subsequent steps.

Derive OUTPUT_DIR

Compute the output directory by deriving a sanitized directory name from TARGET_PATH relative to the current working directory:

  1. Compute the relative path of TARGET_PATH from the current working directory. If TARGET_PATH is the current working directory, use the directory's basename.
  2. Replace path separators (/) with hyphens (-). Remove leading/trailing hyphens.
  3. Set OUTPUT_DIR to {CWD}/vuln-scan-results/{sanitized-name} where {CWD} is the current working directory.

Examples:

  • /vuln-scan (target = CWD /home/user/myapp) → OUTPUT_DIR = /home/user/myapp/vuln-scan-results/myapp
  • /vuln-scan src/apiOUTPUT_DIR = /home/user/myapp/vuln-scan-results/src-api
  • /vuln-scan /other/repoOUTPUT_DIR = /home/user/myapp/vuln-scan-results/other-repo

This ensures each scan target gets its own results directory that persists across runs.


Step 2 — Validate Target

Use the Bash tool to confirm the target is a usable directory:

[ -d "{TARGET_PATH}" ] && echo "exists" || echo "missing"

Then use Glob to check that the directory contains at least one source file (any file matching **/*.* excluding vuln-scan-results/**).

If the directory does not exist or contains no source files: output an error message to the user explaining the problem and stop. Do not proceed.


Step 3 — Setup Output Directory

Check whether {OUTPUT_DIR}/config.json exists (this file is user-created, NOT generated). If it exists, preserve it across the cleanup.

Execute the following using the Bash tool. Run these as a single shell script block.

# Preserve user config if it exists (stash in parent vuln-scan-results/ dir)
[ -f "{OUTPUT_DIR}/config.json" ] && mv "{OUTPUT_DIR}/config.json" "{OUTPUT_DIR}/../.vuln-scan-config-preserve.json"

# Remove previous scan output
rm -rf "{OUTPUT_DIR}"

# Create fresh output directories
mkdir -p "{OUTPUT_DIR}/findings"

# Restore user config if it was preserved
[ -f "{OUTPUT_DIR}/../.vuln-scan-config-preserve.json" ] && mv "{OUTPUT_DIR}/../.vuln-scan-config-preserve.json" "{OUTPUT_DIR}/config.json"

Initialize the scan log by writing the following JSON line to {OUTPUT_DIR}/scan.log using the Write tool:

{"ts": "", "phase": "coordinator", "event": "start", "target": "{TARGET_PATH}"}

Step 4 — Phase 1: Recon

Goal: Produce {OUTPUT_DIR}/repo-profile.json.

  1. Use the Read tool to read the file at {SKILL_DIR}/phases/recon.md where {SKILL_DIR} is the directory containing this SKILL.md file (i.e., the skills/vuln-scan/ directory within the repository where you were loaded from).
  2. In the loaded text, replace every occurrence of {{TARGET_PATH}} with the actual value of TARGET_PATH, and every occurrence of {{OUTPUT_DIR}} with the actual value of OUTPUT_DIR.
  3. Use the Agent tool to dispatch the prepared prompt as a subagent. Use this description: "Run Phase 1 recon".
  4. Wait for the subagent to return.
  5. Append this line to {OUTPUT_DIR}/scan.log:
  • On success: {"ts": "", "phase": "recon", "event": "completed", "duration_s": }
  • On failure: {"ts": "", "phase": "recon", "event": "failed", "reason": ""}
  1. Use the Read tool to load {OUTPUT_DIR}/repo-profile.json.
  • If this file does not exist or is not valid JSON: write a failed log entry, output a single error message to the user ("Phase 1 (Recon) failed — cannot continue without a repo profile"), and stop. Do not proceed to any further phase.
  1. Store the file contents as REPO_PROFILE.

Step 5 — Phase 2: Threat Model

Goal: Produce {OUTPUT_DIR}/threat-model.json.

  1. Use the Read tool to read {SKILL_DIR}/phases/threat-model.md.
  2. Replace every occurrence of {{REPO_PROFILE}} with the contents of REPO_PROFILE.
  3. Replace {{OUTPUT_DIR}} with the actual value of OUTPUT_DIR.
  4. Replace {{SERVICES}} with the services array from REPO_PROFILE (extracted as a JSON array string). If is_monorepo is false in the repo profile, replace {{SERVICES}} with [].
  5. Dispatch the prepared prompt as an Agent subagent. Description: "Run Phase 2 threat model".
  6. Wait for the subagent to return.
  7. Use the Read tool to load {OUTPUT_DIR}/threat-model.json.
  • If the file exists and is valid JSON: store its contents as THREAT_MODEL. Append a completed log entry.
  • If the file is missing or invalid: store THREAT_MODEL as the string {}. Append a failed log entry with "reason": "threat model output missing, continuing with empty model". Do not abort — partial results are acceptable.

Step 6 — Phases 3–5: Parallel Scanning

Goal: Run static analysis, code review, and dependency scan simultaneously.

6a — Prepare all three prompts

Use the Read tool three times (may be parallelized) to load:

  • {SKILL_DIR}/phases/static-analysis.md
  • {SKILL_DIR}/phases/code-review.md
  • {SKILL_DIR}/phases/dependency-scan.md

For each loaded text, perform the following replacements (skip a replacement if that placeholder does not appear in the file):

  • Replace {{REPO_PROFILE}} with the contents of REPO_PROFILE.
  • Replace {{THREAT_MODEL}} with the contents of THREAT_MODEL.
  • Replace {{OUTPUT_DIR}} with the actual value of OUTPUT_DIR.
  • Replace {{SERVICES}} with the services array from REPO_PROFILE (extracted as a JSON array string). If is_monorepo is false in the repo profile, replace {{SERVICES}} with [].

6b — Dispatch all three agents in a single message

CRITICAL: You MUST invoke all three Agent tool calls in a single response message. This triggers parallel execution. Do not send them in separate messages.

Use these descriptions:

  • Static analysis agent: "Run Phase 3 static analysis"
  • Code review agent: "Run Phase 4 code review"
  • Dependency scan agent: "Run Phase 5 dependency scan"

6c — Handle results

After all three subagents return, append a log entry for each:

  • {"ts": "", "phase": "", "event": "completed", "duration_s": }
  • {"ts": "", "phase": "", "event": "failed", "reason": ""}

If the parallel dispatch itself fails (e.g., tool error before any agent runs), fall back to dispatching each of the three agents sequentially, one at a time, with separate Agent tool calls. Log a skipped entry for parallel mode:

{"ts": "", "phase": "parallel-dispatch", "event": "skipped", "reason": "parallel dispatch failed, falling back to sequential"}

Do not abort if one or more of these phases fail — proceed to validation with whatever findings were produced.


Step 7 — Phase 6: Validation

Goal: Produce {OUTPUT_DIR}/validated-findings.json.

  1. Use the Read tool to read {SKILL_DIR}/phases/validation.md.
  1. Perform these replacements:
  • Replace {{THREAT_MODEL}} with the contents of THREAT_MODEL.
  • Replace {{OUTPUT_DIR}} with the actual value of OUTPUT_DIR.
  • Replace {{FINDINGS_DIR}} with the path {OUTPUT_DIR}/findings.
  • Replace {{SERVICES}} with the services array from REPO_PROFILE (extracted as a JSON array string). If is_monorepo is false in the repo profile, replace {{SERVICES}} with [].
  1. For each findings file, attempt to read it with the Read tool. If the file exists, replace the corresponding placeholder with its contents. If the file does not exist, leave the placeholder as-is (the validation phase prompt handles absent data gracefully).

| Placeholder | File path | |-------------------------------|--------------------------------------------------------| | {{STATIC_ANALYSIS_FINDINGS}} | {OUTPUT_DIR}/findings/static-analysis.json | | {{CODE_REVIEW_FINDINGS}} | {OUTPUT_DIR}/findings/code-review.json | | {{DEPENDENCY_FINDINGS}} | {OUTPUT_DIR}/findings/dependencies.json |

  1. Dispatch the prepared prompt as an Agent subagent. Description: "Run Phase 6 validation".
  2. Wait for the subagent to return.
  3. Use the Read tool to load {OUTPUT_DIR}/validated-findings.json.
  • If the file exists and is valid JSON: store its contents as VALIDATED_FINDINGS. Append a completed log entry.
  • If the file is missing or invalid: store VALIDATED_FINDINGS as {}. Append a failed log entry. Do not abort.

Step 8 — Phase 7: Reporting

Goal: Produce the final markdown and SARIF report files in {OUTPUT_DIR}/.

  1. Use the Read tool to read {SKILL_DIR}/phases/reporting.md.
  2. Perform these replacements:
  • Replace {{VALIDATED_FINDINGS}} with the contents of VALIDATED_FINDINGS.
  • Replace {{REPO_PROFILE}} with the contents of REPO_PROFILE.
  • Replace {{THREAT_MODEL}} with the contents of THREAT_MODEL.
  • Replace {{OUTPUT_DIR}} with the actual value of OUTPUT_DIR.
  • Replace {{SERVICES}} with the services array from REPO_PROFILE (extracted as a JSON array string). If is_monorepo is false in the repo profile, replace {{SERVICES}} with [].
  1. Dispatch the prepared prompt as an Agent subagent. Description: "Run Phase 7 reporting".
  2. Wait for the subagent to return.
  3. Append a completed or failed log entry to scan.log.

Step 9 — Present Results

After Phase 8 completes, read {OUTPUT_DIR}/validated-findings.json and extract the summary section. Then output the following to the user:

vuln-scan complete for: {TARGET_PATH}

Findings summary:
  Critical : 
  High     : 
  Medium   : 
  Low      : 
  Total    : 

Reports written to:
  {OUTPUT_DIR}/SECURITY_REPORT.md
  {OUTPUT_DIR}/report.sarif

Scan log: {OUTPUT_DIR}/scan.log

If the repo profile's is_monorepo is true, also display:

Service breakdown:
  {service_name}: {count} findings
  {service_name}: {count} findings
  shared ({shared_name}): {count} findings (affects: {consumers list})

Read the by_service counts from validated-findings.json's summary section.

If validated-findings.json is absent or unparseable, omit the findings summary section and note that validation output was unavailable.

Append a final log entry to scan.log:

{"ts": "", "phase": "coordinator", "event": "completed", "duration_s": }

scan.log Format Reference

Every log entry is a single JSON object written as one line. Append entries with the Write or Bash tool (append mode). Never overwrite the log — only append.

{"ts": "", "phase": "", "event": "", ...context}

Event types:

  • start — pipeline is beginning; include "target": ""
  • dispatched — agent has been sent (optional, use for long phases)
  • completed — phase finished successfully; include "duration_s":
  • failed — phase produced no usable output; include "reason": ""
  • skipped — phase was intentionally bypassed; include "reason": ""

Phase names: coordinator, recon, threat-model, static-analysis, code-review, dependency-scan, validation, reporting, parallel-dispatch


Key Constraints

  • Never prompt the user during execution. All decisions are defined in this document.
  • Never abort on phases 3–7 failures. Partial results are always better than no results. Only Phase 1 (Recon) is a hard abort condition.
  • Skill directory resolution: {SKILL_DIR} refers to the directory from which this SKILL.md was loaded. Phase prompts live in {SKILL_DIR}/phases/. When dispatching subagents, use absolute paths when reading phase files.
  • Template injection is simple string replacement. Replace {{PLACEHOLDER}} literally with the substituted content. Do not interpret or transform the content.
  • Output directory is always {OUTPUT_DIR}/. All phase output files are written there by the subagents — the coordinator only reads them.
  • Write boundary: Subagents must only write files inside {OUTPUT_DIR}/. If a subagent writes or modifies any file outside this directory, it must revert the change (e.g., git checkout -- ) and log a violation entry to scan.log: {"ts": "", "phase": "", "event": "write_violation", "file": "", "action": "reverted"}.
  • Error messages go to scan.log as JSON entries. Only surface errors to the user on a hard abort (Phase 1 failure) or in the final summary.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.