vlt 1.5.0 adds a command that turns npm dependencies into a source of agent skills. According to Socket's announcement, vlt skills finds skills, meaning folders that contain a SKILL.md file, inside packages already installed in your project and links them where coding agents look for them. It is opt-in, and when you give it no explicit selection it filters out packages that Socket flags as malware. That is a sensible default for a feature with a clear supply-chain angle: a skill is a set of instructions your agent follows, so a dependency that ships skills can now influence what the agent does. This post explains how the command works from the vlt reference, what the filter does and does not cover, and what to check before you link anything.
| Question | Short answer |
|---|---|
| What is new? | vlt skills lists and links SKILL.md folders from installed dependencies |
| Is it automatic? | No. Linking is opt-in and saved as allow-skills in vlt.json |
| Where do links go? | .agents/skills by default, plus agent folders such as .claude/skills |
| What is the default filter? | :not(:malware), based on Socket's high-confidence malware alerts |
| Does it download anything? | No. It only reads packages you already installed |
| Does the filter make skills safe? | No. Read each skill first |
How vlt skills works
The documented workflow is three commands:
vlt install agent-browser
vlt skills
vlt skills link "#agent-browser"
vlt install adds the package as usual. vlt skills (the default list subcommand) shows the skills found, marked (linked) where they are already in place; it creates and saves nothing. vlt skills link sets and saves allow-skills, then applies it.
Where vlt looks inside a package
The reference says vlt checks, in order: SKILL.md at the package root, skills/<name>/SKILL.md, dist/skills/<name>/SKILL.md, and .agents/skills/<name>/SKILL.md. If a skill name appears in more than one place, the first match wins. Folder names must start with a letter or digit. Symlinked skill folders, SKILL.md files or path segments are skipped, and nested folders such as skills/group/<name>/ are not found. Direct and transitive dependencies in node_modules/.vlt are both candidates, though the project itself, workspaces and file: dependencies are excluded.
That transitive point matters. A skill does not have to come from a package you chose; it can come from something your dependency installed. Whether it is linked depends on your selection, but the candidates list can include packages you have never read.
Where links are created
Unless skills-dir is set, vlt always targets .agents/skills, which Socket says Codex, Cursor, GitHub Copilot and Gemini CLI read. It also targets <folder>/skills for each agent folder at the project root (for example .claude/skills), and .claude/skills when the CLAUDECODE environment variable is set, even without a .claude/ folder. Existing .cursor/skills or .github/skills directories are used but never created. Links are symlinks on Unix and directory junctions on Windows; vlt also adds a marked block to each directory's .gitignore.
Selecting skills
The :skill() selector narrows the choice, for example vlt skills link ":root > *:skill(vercel*, *-review)". A selector without :skill() selects every skill in its packages. The selection is saved, so later install, update and ci runs reuse it. During installs vlt only adds or re-points links; vlt skills link is the only command that removes links to installed skills.
Versioning
Skills come from the package version in the lockfile. Socket says updating a library updates its linked skills to match, with no manual copying. That removes drift between a library and the guidance written for it.
The security model
Socket states that linking is opt-in. With no saved selection, vlt skills link uses :not(:malware), which excludes packages with Socket's high-confidence malware alerts. Socket-powered selectors can also exclude packages flagged for typosquatting, vulnerabilities or obfuscated code. The vlt reference adds that security queries fail closed: packages without security data are not linked and are reported, existing links are kept during install, and vlt skills link removes them. It also says vlt only replaces or removes links pointing into a node_modules/.vlt store, never other files at a link path, and never removes directories.
These are good properties. They are also limited, and the limits are the part to understand.
What the filter covers
A malware alert is about the package: known-malicious code, install scripts, typosquats. Socket's announcement does not say whether the filter reads SKILL.md content, and the reference describes selection by package-level security data. Neither source discusses integrity or provenance of the skill files themselves, and the announcement is silent on them. So the safe reading is that the filter screens known-bad packages, not that it reviews instructions.
Why instructions are a different risk
A skill is natural-language instructions plus optional scripts that an agent loads and follows with your permissions. A skill that tells the agent to read ~/.aws/credentials, post a file to a URL, or run curl | sh is not malware in the package sense and may not appear in any alert. Our guide to agent skills and their security review covers what to look for, and the Cloudflare security audit skill is an example of a skill that is legitimately powerful because of what it directs an agent to do.
The versioning feature adds a second consideration. Because skills track the lockfile, a dependency bump changes the text your agent reads. A package that was fine at 1.2.0 can ship different instructions at 1.2.1 and, if you linked by package, the new text reaches the agent on the next install. That is the same shape as the dependency-confusion and worm incidents in our npm supply-chain worms post, applied to a new file type.
What this means if you run AI coding agents
- Link by exact skill, not by package. Use
:skill(name)selectors rather than selecting everything a package ships. - Read the
SKILL.mdand any scripts before the first link, and diff them when the version changes.vlt skills --view=jsonlists name, description, dependency name, package ID and path. - Commit your selection.
allow-skillsinvlt.jsonmakes the choice reviewable in a pull request. Note thatvlt cinever writes config. - Check the links. On Linux or macOS,
ls -l .agents/skills .claude/skillsshows which symlinks point intonode_modules/.vlt. After moving a project on Windows, re-runvlt skills linkbecause junctions use absolute paths. - Treat transitive skills with suspicion. If
vlt skillslists something you did not expect, find the dependency that brought it in before linking. - Watch what the agent does next, not just what it was told. A skill's effect appears in commands and file reads.
A review walkthrough before the first link
Here is a concrete routine, using only commands from the vlt reference. First, install the package and run vlt skills to see what it ships; nothing is linked yet. Second, run vlt skills --view=json and read the name, description and path for each entry. Third, open the SKILL.md and anything it references. Ask three questions of every skill. Does it ask the agent to read files outside the project, such as shell history, cloud credentials or SSH keys? Does it tell the agent to run a downloaded script, or to send data to a URL? Does it tell the agent to ignore confirmation prompts or to hide what it is doing from you? A yes to any of these is a reason to skip it, however well the package scores.
Fourth, link only what you read: vlt skills link ":root > *:skill(the-skill-you-reviewed)". Fifth, commit the resulting vlt.json change in its own pull request so a reviewer sees the selection. After that, the hard part is keeping the review current. When a dependency update lands, look at the package diff for the skill folder specifically; a quick git diff on a vendored copy, or npm diff --diff=pkg@old --diff=pkg@new where you use npm alongside vlt, shows whether instructions changed. If you cannot afford to re-read every update, restrict linked skills to a small set from publishers you trust and leave the rest unlinked.
How this compares with other ways of getting skills
Before this feature, skills reached projects by copying a folder, cloning a repository, or using an agent's own plugin mechanism. Each of those is manual, which made drift and silent staleness the main problem. vlt skills trades that friction for convenience: skills now ride the same dependency graph as code, with the same lockfile and the same update path. The security consequence is that skills inherit the dependency ecosystem's failure modes, including typosquatting, maintainer takeover and compromised releases, which are exactly the cases Socket's selectors aim to catch. What the dependency graph does not give you is any review of what a skill says.
Two design choices deserve credit. Opt-in linking means installing a package does not silently change your agent's behaviour, and failing closed on missing security data means unknown packages stay out by default. Two choices to be aware of: linking at the project root only, so workspaces share one set of links, and the fact that the same selection applies to every agent whose directory exists, so a skill you linked for one tool is visible to all of them.
What Beam can and cannot do here
Beam scans skills and MCP configs before you run them using 11 heuristics (patterns such as piping a download into a shell) plus a version-pin check for MCP configs, and it watches what Claude Code and Codex do afterwards, flagging credential exposure and destructive commands. Hook-based deny works for Claude Code and Codex PreToolUse. Everything runs on-device. See our post on Beam's security skills and subagents and how it works. The limits: the scan is heuristic pattern matching, not semantic analysis of what a skill means, and the deny is hook-based rather than a kernel sandbox and fails open without cached policy. Beam does not integrate with vlt; it works on the skill files wherever they are linked.
Frequently asked questions
What does vlt skills do?
It finds agent skills, meaning folders with a SKILL.md file, shipped by packages already installed in your project and links them into agent skill directories such as .agents/skills and .claude/skills. It never downloads anything itself.
Is linking automatic?
No. Socket says linking is opt-in. Nothing is linked until you run vlt skills link or set allow-skills, and your selection is saved to vlt.json so later installs and vlt ci runs reuse it.
What is the default safety filter?
With no saved selection, vlt skills link uses :not(:malware), which relies on Socket high-confidence malware alerts to exclude flagged packages. The vlt docs say security queries fail closed: packages without security data are not linked.
Does the malware filter make a skill safe?
No. It screens known-malicious packages. A skill is instructions your agent follows, and a legitimate package can ship instructions that are risky or change on update. Read each skill before linking it.
What changes when a dependency updates?
Skills come from the package version in your lockfile, so updating the package updates the linked skill to match. That is convenient and also means a dependency bump can change the instructions your agent receives.
How can Beam help?
Beam scans skills and MCP configs with 11 heuristics and a version-pin check before you run them, and watches what the agent then does. It is heuristic, not semantic malware analysis.
Related reading
- Agent skills: specification and security review
- npm supply-chain worms and AI tooling
- Beam's security skills and subagents
- AI agent application and supply-chain security
- vlt skills reference
Details reflect Socket's announcement and the vlt documentation as of October 22, 2026 and may change in later releases. Beam is a local prototype; features described are as documented at the time of writing.

