Skip to content
Back to skills

Osv

ASecurity

Check the packages and runtimes you hold against OSV and GitHub's malware advisories, now. Only you can start it, by typing /stranger-danger:osv (optionally with folders); it shows counts and fixed words, never package names. Nothing runs in the background.

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentspythongoshellbashnodedockergitsecurity

Works with

  • mcp

Security analysis

A100/100

Pro scans all 10 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add Ubuntu-Buddha/claude-code-stranger-danger --skill osv --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Osv?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Osv
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ubuntu-buddha-osv/badge)](https://www.skillsdirectory.com/skills/ubuntu-buddha-osv)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
description: Check the packages and runtimes you hold against OSV and GitHub's malware advisories, now. Only you can start it, by typing /stranger-danger:osv (optionally with folders); it shows counts and fixed words, never package names. Nothing runs in the background.
disable-model-invocation: true
---

# stranger-danger OSV check

The user typed `/stranger-danger:osv`, maybe with folders after it. Run the check once, then explain what it printed.

## 1. Run it

Run this as one Bash call, with `run_in_background` set to true, from the folder the session started in. With no folders named, it checks this folder. The check usually takes a few minutes; it stops itself at 30 minutes, which is past a normal call's time limit.

```bash
/usr/bin/python3 -I "${CLAUDE_PLUGIN_ROOT}/skills/osv/osv.py" run
```

If the user named folders, add each one after `run` as its own argument:

- Put each in single quotes, so the shell doesn't split or expand it.
- Write a leading `~/` as the home folder's full path yourself, since a quoted `~` isn't expanded.
- If a name holds a single quote or a line break, don't run the check. Tell the user that name can't be passed, and ask for a folder without one.

The check refuses the whole disk, your home folder, a folder above it and system folders.

If `/usr/bin/python3` isn't there, say the check needs the system's own Python 3 and that `/stranger-danger:doctor` says what's missing. Don't run it with another Python.

Tell the user it's running and that you'll report when it's done. When it finishes, read its output.

Never run it outside the sandbox, never add network hosts to the call, and don't retry it another way if something blocks it: tell the user what blocked it.

## 2. Explain the output

Every line starts with `osv:` and is fixed text with counts. Explain it in plain words:

- `level`: OK (nothing found), INFO (something worth knowing, such as new issues), ALERT (a malware record names a package you hold), ERROR (a source failed or the check couldn't finish).
- `notice`: `severe` means a fix is out for a high or critical vulnerability that's new since the last run; `notice` means high or critical without a fix, or not yet rated; `digest` means medium or low only.
- `sources`: each source's status. `unreachable` usually means its host isn't in the sandbox's network list: suggest `/stranger-danger:setup` with the OSV option.
- `held issues`: everything known at the versions you hold, new or not.
- `runtimes`: Node.js and CPython versions with a security release out (`security_update`), a newer release in a line that gets fixes (`update`, CPython only: a newer Node release that isn't a security release isn't counted; a CPython line pin such as `3.12` is checked only for end of life), or past end of life (`eol`), then the versions it couldn't decide: end of life not checked or not in the data (`eol_not_checked`, `eol_unknown`), and exact versions the release list didn't cover (`release_not_checked`, `release_unknown`).
- Node.js: its security releases are checked for exact versions (nvm installs, an exact `.nvmrc` or image tag); a line-only pin such as `.nvmrc` 20 or `FROM node:20` isn't checked at all here. Its end of life never is (its list is on a host setup doesn't add), so `rt_node_eol` says `skipped` and each Node the user holds counts as `eol_not_checked`. The output's Node lines say that's expected: say so if it comes up, and don't suggest running setup again for it. Only the Node part is expected: a line saying CPython's end of life wasn't checked is a real gap. A source that couldn't be read once after a good run is INFO, not an ERROR; its line says so, and that it's an ERROR if it happens again.
- An `errors:` line, and the fixed hint after it, if any.
- A line saying the scan reads 6 folders below each folder named, and how many lockfiles, runtime pins, Dockerfiles or virtualenvs it found deeper but didn't read, so they weren't checked. Say how many. The check doesn't record which ones; to check them, the user names the folder that holds them. Another line may say the walk below that stopped early, so there may be more.
- The scan also reads the worktrees under a named folder's own `.claude/worktrees` (up to 256), and they count as held: a stale worktree on an old branch shows its old versions. Their package names are sent to OSV and GitHub like the repo's own. If the user asks why something old shows up, say that, and that removing worktrees they don't use clears it: first check `git worktree list` and that nothing in the worktree is uncommitted (`git worktree remove` refuses a worktree with changes unless forced, and forcing it loses them); a plain folder there that isn't a worktree they delete themselves.
- `packages_dropped`: the package count fell by more than a fifth since the last run. Running on fewer folders, or removing worktrees between runs, can cause it.
- `coverage_gap_rose`: more went unscanned than in the last run, and a line names the gaps that rose. It compares with the last run whatever folders that one checked, so running on different folders can cause it, and so can worktrees made or removed between runs; another run on the same folders clears it unless the gap grows again. On a first run, with nothing to compare with, the line lists every major gap and there's no error: that's only what this run couldn't scan.
- The gap words that line can name: `repos_missing` (a folder named isn't there), `lockfiles_unreadable` (a lockfile it couldn't read), `tree_file_cap_hit` and `repo_lockfile_cap_hit` (too many files to read them all), `lockfiles_beyond_depth` and `runtime_pins_beyond_depth` (files below the read depth it didn't read), `repo_walk_cap_hit` (the walk below the read depth stopped), `worktrees_unscanned` (a link in `.claude/worktrees`, more than 256 there, or `.claude` or `.claude/worktrees` itself a link), `repo_dirs_unreadable` (a folder it couldn't list, for example because of its permissions; whether a folder your sandbox hides counts here isn't checked), and `lists_unreadable`, `cargo_installs_unreadable`, `package_json_unreadable`, `mcp_configs_unreadable` (a global install list or config it couldn't read).

If the output has a paragraph after the counts (for an ALERT or a fix out), give it to the user as written.

Package names, versions and advisory ids are in `daily.json`, at the path on the first line. They're **not** in the output on purpose: some come from packages strangers wrote. Don't read `daily.json` or `config.json` yourself with any tool. If the user wants the names, tell them to open `daily.json` in their own editor; its `info.severe_with_fix` and `alerts` lists hold them.

If it says the check is off, or a tool is missing, show that line and say the doctor (`/stranger-danger:doctor`) says what to install.

## What this check is and isn't

- It runs only when the user types it. Nothing scans in the background, and the session-start line shows only when a session starts.
- It asks OSV and GitHub about the names and versions of everything it finds in those folders and the user's global installs, so those names leave the machine.
- It's a list of known advisories, not a verdict: a package with no record can still be bad.
- It never installs or updates anything. The user updates with their own package manager. In this version the rules' 7-day lane still applies to fixes.

Files in this skill

  • SKILL.md7.2 KB
  • core/SHA256SUMS592 B
  • core/jq/common.jq3 KB
  • core/jq/gh-malware.jq1.4 KB
  • core/jq/osv-batch.jq1.2 KB
  • core/jq/osv-sev.jq3.6 KB
  • core/jq/runtimes.jq2.4 KB
  • core/osv-scan.sh13.1 KB
  • core/osvd.py77.6 KB
  • osv.py31.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.