Install
$ agentstack add skill-thapr0digy-skills-vuln-scan ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
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:
- Compute the relative path of
TARGET_PATHfrom the current working directory. IfTARGET_PATHis the current working directory, use the directory's basename. - Replace path separators (
/) with hyphens (-). Remove leading/trailing hyphens. - Set
OUTPUT_DIRto{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/api→OUTPUT_DIR=/home/user/myapp/vuln-scan-results/src-api/vuln-scan /other/repo→OUTPUT_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.
- Use the Read tool to read the file at
{SKILL_DIR}/phases/recon.mdwhere{SKILL_DIR}is the directory containing this SKILL.md file (i.e., theskills/vuln-scan/directory within the repository where you were loaded from). - In the loaded text, replace every occurrence of
{{TARGET_PATH}}with the actual value ofTARGET_PATH, and every occurrence of{{OUTPUT_DIR}}with the actual value ofOUTPUT_DIR. - Use the Agent tool to dispatch the prepared prompt as a subagent. Use this description:
"Run Phase 1 recon". - Wait for the subagent to return.
- 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": ""}
- Use the Read tool to load
{OUTPUT_DIR}/repo-profile.json.
- If this file does not exist or is not valid JSON: write a
failedlog 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.
- Store the file contents as
REPO_PROFILE.
Step 5 — Phase 2: Threat Model
Goal: Produce {OUTPUT_DIR}/threat-model.json.
- Use the Read tool to read
{SKILL_DIR}/phases/threat-model.md. - Replace every occurrence of
{{REPO_PROFILE}}with the contents ofREPO_PROFILE. - Replace
{{OUTPUT_DIR}}with the actual value ofOUTPUT_DIR. - Replace
{{SERVICES}}with theservicesarray fromREPO_PROFILE(extracted as a JSON array string). Ifis_monorepoisfalsein the repo profile, replace{{SERVICES}}with[]. - Dispatch the prepared prompt as an Agent subagent. Description:
"Run Phase 2 threat model". - Wait for the subagent to return.
- 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 acompletedlog entry. - If the file is missing or invalid: store
THREAT_MODELas the string{}. Append afailedlog 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 ofREPO_PROFILE. - Replace
{{THREAT_MODEL}}with the contents ofTHREAT_MODEL. - Replace
{{OUTPUT_DIR}}with the actual value ofOUTPUT_DIR. - Replace
{{SERVICES}}with theservicesarray fromREPO_PROFILE(extracted as a JSON array string). Ifis_monorepoisfalsein 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.
- Use the Read tool to read
{SKILL_DIR}/phases/validation.md.
- Perform these replacements:
- Replace
{{THREAT_MODEL}}with the contents ofTHREAT_MODEL. - Replace
{{OUTPUT_DIR}}with the actual value ofOUTPUT_DIR. - Replace
{{FINDINGS_DIR}}with the path{OUTPUT_DIR}/findings. - Replace
{{SERVICES}}with theservicesarray fromREPO_PROFILE(extracted as a JSON array string). Ifis_monorepoisfalsein the repo profile, replace{{SERVICES}}with[].
- 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 |
- Dispatch the prepared prompt as an Agent subagent. Description:
"Run Phase 6 validation". - Wait for the subagent to return.
- 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 acompletedlog entry. - If the file is missing or invalid: store
VALIDATED_FINDINGSas{}. Append afailedlog entry. Do not abort.
Step 8 — Phase 7: Reporting
Goal: Produce the final markdown and SARIF report files in {OUTPUT_DIR}/.
- Use the Read tool to read
{SKILL_DIR}/phases/reporting.md. - Perform these replacements:
- Replace
{{VALIDATED_FINDINGS}}with the contents ofVALIDATED_FINDINGS. - Replace
{{REPO_PROFILE}}with the contents ofREPO_PROFILE. - Replace
{{THREAT_MODEL}}with the contents ofTHREAT_MODEL. - Replace
{{OUTPUT_DIR}}with the actual value ofOUTPUT_DIR. - Replace
{{SERVICES}}with theservicesarray fromREPO_PROFILE(extracted as a JSON array string). Ifis_monorepoisfalsein the repo profile, replace{{SERVICES}}with[].
- Dispatch the prepared prompt as an Agent subagent. Description:
"Run Phase 7 reporting". - Wait for the subagent to return.
- Append a
completedorfailedlog entry toscan.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 toscan.log:{"ts": "", "phase": "", "event": "write_violation", "file": "", "action": "reverted"}. - Error messages go to
scan.logas 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.
- Author: thapr0digy
- Source: thapr0digy/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.