@vltpkg/query 1.0.0-rc.32 → 1.0.0-rc.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +10 -6
- package/dist/parser.js +2 -1
- package/dist/pseudo/hostname.js +3 -1
- package/dist/pseudo/malware.d.ts +3 -16
- package/dist/pseudo/malware.js +11 -171
- package/dist/pseudo/scripts.js +1 -1
- package/dist/pseudo/vuln.d.ts +22 -0
- package/dist/pseudo/vuln.js +220 -0
- package/dist/pseudo.js +3 -3
- package/dist/types.d.ts +3 -2
- package/package.json +19 -10
- package/skills/dss-query/REFERENCE.md +123 -0
- package/skills/dss-query/SKILL.md +190 -0
- package/skills/dss-query/evals/README.md +79 -0
- package/skills/dss-query/evals/evals.json +89 -0
- package/skills/dss-query/evals/grade.mjs +480 -0
- package/src/attribute.ts +186 -0
- package/src/combinator.ts +132 -0
- package/src/id.ts +46 -0
- package/src/index.ts +620 -0
- package/src/parser.ts +122 -0
- package/src/pseudo/abandoned.ts +9 -0
- package/src/pseudo/attr.ts +92 -0
- package/src/pseudo/built.ts +19 -0
- package/src/pseudo/confused.ts +29 -0
- package/src/pseudo/cve.ts +93 -0
- package/src/pseudo/cwe.ts +97 -0
- package/src/pseudo/debug.ts +9 -0
- package/src/pseudo/deprecated.ts +9 -0
- package/src/pseudo/dev.ts +18 -0
- package/src/pseudo/diff.ts +90 -0
- package/src/pseudo/dist.ts +144 -0
- package/src/pseudo/dynamic.ts +9 -0
- package/src/pseudo/empty.ts +15 -0
- package/src/pseudo/entropic.ts +9 -0
- package/src/pseudo/env.ts +6 -0
- package/src/pseudo/eval.ts +9 -0
- package/src/pseudo/fs.ts +9 -0
- package/src/pseudo/helpers.ts +106 -0
- package/src/pseudo/host.ts +111 -0
- package/src/pseudo/hostname.ts +156 -0
- package/src/pseudo/license.ts +134 -0
- package/src/pseudo/link.ts +30 -0
- package/src/pseudo/malware.ts +41 -0
- package/src/pseudo/minified.ts +9 -0
- package/src/pseudo/missing.ts +16 -0
- package/src/pseudo/native.ts +9 -0
- package/src/pseudo/network.ts +9 -0
- package/src/pseudo/obfuscated.ts +9 -0
- package/src/pseudo/optional.ts +18 -0
- package/src/pseudo/outdated.ts +305 -0
- package/src/pseudo/overridden.ts +20 -0
- package/src/pseudo/path.ts +146 -0
- package/src/pseudo/peer.ts +18 -0
- package/src/pseudo/prerelease.ts +47 -0
- package/src/pseudo/private.ts +19 -0
- package/src/pseudo/prod.ts +18 -0
- package/src/pseudo/published.ts +248 -0
- package/src/pseudo/registry.ts +29 -0
- package/src/pseudo/root.ts +19 -0
- package/src/pseudo/scanned.ts +20 -0
- package/src/pseudo/score.ts +186 -0
- package/src/pseudo/scripts.ts +54 -0
- package/src/pseudo/semver.ts +320 -0
- package/src/pseudo/severity.ts +231 -0
- package/src/pseudo/shell.ts +9 -0
- package/src/pseudo/shrinkwrap.ts +9 -0
- package/src/pseudo/spec.ts +131 -0
- package/src/pseudo/squat.ts +225 -0
- package/src/pseudo/suspicious.ts +9 -0
- package/src/pseudo/tracker.ts +9 -0
- package/src/pseudo/trivial.ts +9 -0
- package/src/pseudo/type.ts +26 -0
- package/src/pseudo/undesirable.ts +9 -0
- package/src/pseudo/unknown.ts +9 -0
- package/src/pseudo/unmaintained.ts +9 -0
- package/src/pseudo/unpopular.ts +9 -0
- package/src/pseudo/unstable.ts +9 -0
- package/src/pseudo/vuln.ts +273 -0
- package/src/pseudo/workspace.ts +22 -0
- package/src/pseudo.ts +413 -0
- package/src/types.ts +165 -0
- package/tap-snapshots/test/attribute.ts.test.cjs +304 -0
- package/tap-snapshots/test/combinator.ts.test.cjs +333 -0
- package/tap-snapshots/test/id.ts.test.cjs +118 -0
- package/tap-snapshots/test/parser.ts.test.cjs +344 -0
- package/tap-snapshots/test/pseudo/abandoned.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/attr.ts.test.cjs +161 -0
- package/tap-snapshots/test/pseudo/built.ts.test.cjs +70 -0
- package/tap-snapshots/test/pseudo/confused.ts.test.cjs +32 -0
- package/tap-snapshots/test/pseudo/cve.ts.test.cjs +49 -0
- package/tap-snapshots/test/pseudo/cwe.ts.test.cjs +49 -0
- package/tap-snapshots/test/pseudo/debug.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/deprecated.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/dist.ts.test.cjs +30 -0
- package/tap-snapshots/test/pseudo/dynamic.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/empty.ts.test.cjs +50 -0
- package/tap-snapshots/test/pseudo/entropic.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/env.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/eval.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/fs.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/helpers.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/hostname.ts.test.cjs +148 -0
- package/tap-snapshots/test/pseudo/license.ts.test.cjs +41 -0
- package/tap-snapshots/test/pseudo/link.ts.test.cjs +36 -0
- package/tap-snapshots/test/pseudo/malware.ts.test.cjs +22 -0
- package/tap-snapshots/test/pseudo/minified.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/missing.ts.test.cjs +30 -0
- package/tap-snapshots/test/pseudo/native.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/network.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/obfuscated.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/outdated.ts.test.cjs +130 -0
- package/tap-snapshots/test/pseudo/overridden.ts.test.cjs +75 -0
- package/tap-snapshots/test/pseudo/prerelease.ts.test.cjs +101 -0
- package/tap-snapshots/test/pseudo/private.ts.test.cjs +38 -0
- package/tap-snapshots/test/pseudo/published.ts.test.cjs +171 -0
- package/tap-snapshots/test/pseudo/registry.ts.test.cjs +68 -0
- package/tap-snapshots/test/pseudo/root.ts.test.cjs +24 -0
- package/tap-snapshots/test/pseudo/scanned.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/score.ts.test.cjs +239 -0
- package/tap-snapshots/test/pseudo/scripts.ts.test.cjs +61 -0
- package/tap-snapshots/test/pseudo/semver.ts.test.cjs +575 -0
- package/tap-snapshots/test/pseudo/severity.ts.test.cjs +95 -0
- package/tap-snapshots/test/pseudo/shell.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/shrinkwrap.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/spec.ts.test.cjs +148 -0
- package/tap-snapshots/test/pseudo/squat.ts.test.cjs +129 -0
- package/tap-snapshots/test/pseudo/suspicious.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/tracker.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/trivial.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/type.ts.test.cjs +51 -0
- package/tap-snapshots/test/pseudo/undesirable.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unknown.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unmaintained.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unpopular.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unstable.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/vuln.ts.test.cjs +208 -0
- package/tap-snapshots/test/pseudo/vulnerable.ts.test.cjs +20 -0
- package/tap-snapshots/test/pseudo/workspace.ts.test.cjs +19 -0
- package/tap-snapshots/test/pseudo.ts.test.cjs +1247 -0
- package/test/attribute.ts +266 -0
- package/test/combinator.ts +168 -0
- package/test/fixtures/graph.ts +999 -0
- package/test/fixtures/selector.ts +103 -0
- package/test/fixtures/types.ts +7 -0
- package/test/id.ts +102 -0
- package/test/index.ts +1000 -0
- package/test/parser.ts +117 -0
- package/test/pseudo/abandoned.ts +98 -0
- package/test/pseudo/attr.ts +298 -0
- package/test/pseudo/built.ts +214 -0
- package/test/pseudo/confused.ts +160 -0
- package/test/pseudo/cve.ts +249 -0
- package/test/pseudo/cwe.ts +255 -0
- package/test/pseudo/debug.ts +98 -0
- package/test/pseudo/deprecated.ts +98 -0
- package/test/pseudo/dev.ts +61 -0
- package/test/pseudo/diff.ts +417 -0
- package/test/pseudo/dist.ts +215 -0
- package/test/pseudo/dynamic.ts +98 -0
- package/test/pseudo/empty.ts +108 -0
- package/test/pseudo/entropic.ts +101 -0
- package/test/pseudo/env.ts +98 -0
- package/test/pseudo/eval.ts +98 -0
- package/test/pseudo/fs.ts +98 -0
- package/test/pseudo/helpers.ts +370 -0
- package/test/pseudo/host-context.ts +276 -0
- package/test/pseudo/hostname.ts +314 -0
- package/test/pseudo/license.ts +265 -0
- package/test/pseudo/link.ts +94 -0
- package/test/pseudo/malware.ts +184 -0
- package/test/pseudo/minified.ts +98 -0
- package/test/pseudo/missing.ts +111 -0
- package/test/pseudo/native.ts +98 -0
- package/test/pseudo/network.ts +98 -0
- package/test/pseudo/obfuscated.ts +98 -0
- package/test/pseudo/optional.ts +73 -0
- package/test/pseudo/outdated.ts +331 -0
- package/test/pseudo/overridden.ts +317 -0
- package/test/pseudo/path.ts +680 -0
- package/test/pseudo/peer.ts +101 -0
- package/test/pseudo/prerelease.ts +279 -0
- package/test/pseudo/private.ts +108 -0
- package/test/pseudo/prod.ts +61 -0
- package/test/pseudo/published.ts +557 -0
- package/test/pseudo/registry.ts +122 -0
- package/test/pseudo/root.ts +66 -0
- package/test/pseudo/scanned.ts +78 -0
- package/test/pseudo/score.ts +591 -0
- package/test/pseudo/scripts.ts +294 -0
- package/test/pseudo/semver.ts +822 -0
- package/test/pseudo/severity.ts +310 -0
- package/test/pseudo/shell.ts +98 -0
- package/test/pseudo/shrinkwrap.ts +98 -0
- package/test/pseudo/spec.ts +525 -0
- package/test/pseudo/squat.ts +565 -0
- package/test/pseudo/suspicious.ts +98 -0
- package/test/pseudo/tracker.ts +98 -0
- package/test/pseudo/trivial.ts +98 -0
- package/test/pseudo/type.ts +105 -0
- package/test/pseudo/undesirable.ts +98 -0
- package/test/pseudo/unknown.ts +98 -0
- package/test/pseudo/unmaintained.ts +98 -0
- package/test/pseudo/unpopular.ts +98 -0
- package/test/pseudo/unstable.ts +98 -0
- package/test/pseudo/vuln.ts +625 -0
- package/test/pseudo/vulnerable.ts +137 -0
- package/test/pseudo/workspace.ts +111 -0
- package/test/pseudo.ts +558 -0
- package/tsconfig.json +3 -0
- package/tsconfig.publish.json +19 -0
- package/tsconfig.publish.tsbuildinfo +1 -0
- package/typedoc.mjs +2 -0
- package/dist/pseudo/vulnerable.d.ts +0 -8
- package/dist/pseudo/vulnerable.js +0 -17
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# DSS Reference
|
|
2
|
+
|
|
3
|
+
Compiled from https://docs.vlt.io/cli/selectors/ (source:
|
|
4
|
+
`www/docs/src/content/docs/cli/selectors/`). When in doubt, check
|
|
5
|
+
those docs — they are canonical.
|
|
6
|
+
|
|
7
|
+
## Attribute selectors
|
|
8
|
+
|
|
9
|
+
Match against `package.json` fields.
|
|
10
|
+
|
|
11
|
+
| Selector | Meaning |
|
|
12
|
+
| ---------------- | ------------------------------------------------ |
|
|
13
|
+
| `[attr]` | has the property |
|
|
14
|
+
| `[attr=value]` | equals |
|
|
15
|
+
| `[attr^=value]` | starts with |
|
|
16
|
+
| `[attr$=value]` | ends with |
|
|
17
|
+
| `[attr*=value]` | contains |
|
|
18
|
+
| `[attr~=value]` | whitespace-separated list contains |
|
|
19
|
+
| `[attr\|=value]` | equals value or starts with `value-` |
|
|
20
|
+
| `[attr=value i]` | case-insensitive (`s` = case-sensitive, default) |
|
|
21
|
+
|
|
22
|
+
Nested fields (e.g. `engines.node`) need `:attr()`:
|
|
23
|
+
`:attr(engines, [node])`,
|
|
24
|
+
`:attr(peerDependenciesMeta, foo, [optional=true])`.
|
|
25
|
+
|
|
26
|
+
`#foo` is shorthand for `[name=foo]`.
|
|
27
|
+
|
|
28
|
+
## Combinators
|
|
29
|
+
|
|
30
|
+
| Combinator | Meaning |
|
|
31
|
+
| ---------- | -------------------------------------------------------------------- |
|
|
32
|
+
| `A > B` | B is a **direct** dependency of A (chain for depth: `:root > * > *`) |
|
|
33
|
+
| `A B` | B is a direct **or transitive** dependency of A |
|
|
34
|
+
| `A ~ B` | B shares a parent with A (sibling) |
|
|
35
|
+
|
|
36
|
+
## Pseudo-states (no arguments)
|
|
37
|
+
|
|
38
|
+
Graph structure:
|
|
39
|
+
|
|
40
|
+
| Selector | Matches |
|
|
41
|
+
| ------------ | --------------------------------------- |
|
|
42
|
+
| `:root` | top-level package.json node |
|
|
43
|
+
| `:project` | root + all workspaces ("your code") |
|
|
44
|
+
| `:workspace` | workspaces from vlt.json |
|
|
45
|
+
| `:scope` | current selector scope (with `--scope`) |
|
|
46
|
+
|
|
47
|
+
Dependency type:
|
|
48
|
+
|
|
49
|
+
| Selector | Matches |
|
|
50
|
+
| ---------------------------------------- | ------------------------------------------------------ |
|
|
51
|
+
| `:prod` / `:dev` / `:optional` / `:peer` | by dependency type |
|
|
52
|
+
| `:missing` | declared but not installed (**edges only, not nodes**) |
|
|
53
|
+
| `:overridden` | has an override applied |
|
|
54
|
+
|
|
55
|
+
Package properties:
|
|
56
|
+
|
|
57
|
+
| Selector | Matches |
|
|
58
|
+
| ------------- | -------------------------------------------- |
|
|
59
|
+
| `:private` | `"private": true` |
|
|
60
|
+
| `:empty` | no dependencies |
|
|
61
|
+
| `:link` | linked packages |
|
|
62
|
+
| `:prerelease` | version has prerelease part (`1.0.0-beta.1`) |
|
|
63
|
+
| `:built` | built during reify |
|
|
64
|
+
| `:scanned` | has Socket security metadata |
|
|
65
|
+
|
|
66
|
+
## Pseudo-classes (take arguments)
|
|
67
|
+
|
|
68
|
+
| Selector | Meaning | Example |
|
|
69
|
+
| ------------------- | --------------------------------------- | ---------------------------------------------- |
|
|
70
|
+
| `:attr(...)` | nested package.json property | `:attr(engines, [node])` |
|
|
71
|
+
| `:dist(tag)` | registry dist-tag | `:dist(latest)` |
|
|
72
|
+
| `:has(sel)` | has matching descendant | `:has(.peer[name=react])` |
|
|
73
|
+
| `:host(name)` | switch graph context to another project | `:host(local) :malware` |
|
|
74
|
+
| `:is(a, b)` | any of (forgiving list) | `:is([name=a], [name=b])` |
|
|
75
|
+
| `:not(sel)` | negation | `:not([license=MIT])` |
|
|
76
|
+
| `:outdated(kind?)` | newer version exists | `:outdated(major)` |
|
|
77
|
+
| `:published(range)` | by publish date | `:published(">2024")` |
|
|
78
|
+
| `:semver(range)` | semver comparison on installed version | `:semver(^1.0.0)` |
|
|
79
|
+
| `:spec(spec)` | by declared specifier (edge) | `:spec(^1.0.0)` |
|
|
80
|
+
| `:path(glob)` | workspace/file packages by path | `:path("packages/**")` |
|
|
81
|
+
| `:type(kind)` | package type | `:type(git)`, `:type(registry)`, `:type(file)` |
|
|
82
|
+
| `:diff(ref)` | files changed vs git ref | `:diff(main)` |
|
|
83
|
+
| `:hostname(host)` | upstream hostname | `:hostname(github.com)` |
|
|
84
|
+
| `:registry(name)` | configured registry name | `:registry(npm)` |
|
|
85
|
+
|
|
86
|
+
## Security insights (Socket-powered, network call)
|
|
87
|
+
|
|
88
|
+
Severity args accept names or numbers (`critical`/`0`, `high`/`1`,
|
|
89
|
+
`medium`/`2`, `low`/`3`) and comparators: `:severity(">=medium")`.
|
|
90
|
+
|
|
91
|
+
Threats: `:malware` (binary, no params), `:squat(sev?)`,
|
|
92
|
+
`:suspicious`, `:confused`.
|
|
93
|
+
|
|
94
|
+
Vulnerabilities: `:vuln(sev?)` (alias `:vulnerable`),
|
|
95
|
+
`:cve(CVE-2023-1234)`, `:cve(*)`, `:cwe(CWE-79)`, `:severity(level)`.
|
|
96
|
+
`:vuln` without params matches severity ≥ medium; `:vuln(critical)`
|
|
97
|
+
exact-matches; `:vuln(">=high")` uses comparators. Also matches alerts
|
|
98
|
+
carrying a `cveId` prop.
|
|
99
|
+
|
|
100
|
+
Licensing: `:license(type)` — types: `unlicensed`, `misc`,
|
|
101
|
+
`restricted`, `ambiguous`, `copyleft`, `unknown`, `none`, `exception`.
|
|
102
|
+
|
|
103
|
+
Code behavior: `:eval`, `:network`, `:fs`, `:env`, `:shell`,
|
|
104
|
+
`:scripts` (install scripts), `:debug`, `:dynamic`.
|
|
105
|
+
|
|
106
|
+
Obfuscation: `:obfuscated`, `:minified`, `:entropic`, `:native`,
|
|
107
|
+
`:shrinkwrap`.
|
|
108
|
+
|
|
109
|
+
Health: `:deprecated`, `:unmaintained` (5+ years stale), `:unpopular`,
|
|
110
|
+
`:trivial` (<10 LOC), `:abandoned`, `:unknown`, `:unstable`.
|
|
111
|
+
|
|
112
|
+
Other: `:tracker` (telemetry), `:undesirable`, `:score(rate, kind?)` —
|
|
113
|
+
kinds: `overall` (default), `license`, `maintenance`, `quality`,
|
|
114
|
+
`supplyChain`, `vulnerability`; e.g. `:score("<=0.5", "maintenance")`.
|
|
115
|
+
|
|
116
|
+
## Audit query starters
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
vlt query ':malware, :vuln(critical), :cve(*), :obfuscated' # critical issues
|
|
120
|
+
vlt query ':abandoned, :unmaintained, :unknown' # supply chain risk
|
|
121
|
+
vlt query ':license(copyleft), :license(unlicensed)' # license compliance
|
|
122
|
+
vlt query ':eval, :shell, :network, :fs' # behavior audit
|
|
123
|
+
```
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dss-query
|
|
3
|
+
description:
|
|
4
|
+
Explain and compose vlt Dependency Selector Syntax (DSS) queries —
|
|
5
|
+
CSS-selector-like strings for filtering packages in a dependency
|
|
6
|
+
graph, including Socket-powered security auditing. Use when the user
|
|
7
|
+
asks about DSS, `vlt query`, dependency selectors, wants to
|
|
8
|
+
find/filter packages (e.g. "find outdated deps", "select all
|
|
9
|
+
workspaces"), or wants to security-audit dependencies ("which
|
|
10
|
+
packages have CVEs", "check for malware/typosquats", "what can run
|
|
11
|
+
shell commands or hit the network").
|
|
12
|
+
allowed-tools: [Read, Grep]
|
|
13
|
+
context: fork
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# DSS Query Helper
|
|
17
|
+
|
|
18
|
+
Run DSS queries via `vlt query '<selector>'`.
|
|
19
|
+
|
|
20
|
+
## Response style
|
|
21
|
+
|
|
22
|
+
**Be concise, but teach one thing.** Give the query first, then a
|
|
23
|
+
one-line explanation. No long preambles, no exhaustive alternatives —
|
|
24
|
+
but don't dead-end either: close with a short **Examples** tail of 1–2
|
|
25
|
+
adjacent queries (one step broader, narrower, or a sibling concept).
|
|
26
|
+
Users learn DSS through adjacent examples, and each answer is a chance
|
|
27
|
+
to build that intuition cheaply. Keep the tail bare — a query plus a
|
|
28
|
+
few-word label, no surrounding prose; the whole answer should still
|
|
29
|
+
read in seconds.
|
|
30
|
+
|
|
31
|
+
Two more rules:
|
|
32
|
+
|
|
33
|
+
- **Gloss jargon in place.** Readers may not know DSS terms — on first
|
|
34
|
+
use, give a 2–4 word parenthetical instead of assuming: "`:root`
|
|
35
|
+
anchors the match (starts it) at your project root", "`>` (direct
|
|
36
|
+
deps only)". Never a terminology lecture, just the aside.
|
|
37
|
+
- **End with a docs deep link** so the answer has a "learn more" exit.
|
|
38
|
+
Use the verified map in [Full reference](#full-reference) below —
|
|
39
|
+
link the section relevant to the query, not the docs homepage.
|
|
40
|
+
|
|
41
|
+
Example answer shape:
|
|
42
|
+
|
|
43
|
+
> ```
|
|
44
|
+
> vlt query ':root > :outdated(major)'
|
|
45
|
+
> ```
|
|
46
|
+
>
|
|
47
|
+
> Direct dependencies with a newer major version available.
|
|
48
|
+
>
|
|
49
|
+
> Examples:
|
|
50
|
+
>
|
|
51
|
+
> - `vlt query ':root > :outdated'` — any newer version, not just
|
|
52
|
+
> major
|
|
53
|
+
> - `vlt query ':outdated(major)'` — whole graph, not just direct
|
|
54
|
+
>
|
|
55
|
+
> Add `--view=json` for machine-readable output. More:
|
|
56
|
+
> <https://docs.vlt.io/cli/selectors/>
|
|
57
|
+
|
|
58
|
+
## Workflow
|
|
59
|
+
|
|
60
|
+
1. **Clarify intent first** if the goal is ambiguous — ask 1–2 short
|
|
61
|
+
questions, never a survey. Pin down:
|
|
62
|
+
- **What to match**: which packages? Whole graph or just direct
|
|
63
|
+
deps? Everywhere, or only under a specific workspace/package?
|
|
64
|
+
- **Expected outcome**: what does the result set look like if the
|
|
65
|
+
query works — a handful of known offenders, every workspace, one
|
|
66
|
+
package? What will they do with it (audit, remove, report)? Skip
|
|
67
|
+
this when the request is already specific — don't interrogate
|
|
68
|
+
someone who said "direct deps of root with an MIT license".
|
|
69
|
+
2. **Compose the query** with the steps below. Then:
|
|
70
|
+
- Show the query.
|
|
71
|
+
- Explain each piece in one short sentence.
|
|
72
|
+
- State what the results should look like, so the user can tell
|
|
73
|
+
whether it worked.
|
|
74
|
+
- Close with the **Examples** tail (1–2 adjacent queries).
|
|
75
|
+
3. **"What does this query do?"**: decompose left to right, one line
|
|
76
|
+
per segment. Offer 1–2 example queries the user could try next.
|
|
77
|
+
4. **Correcting a mistaken query?** Add one line on _why_ it was
|
|
78
|
+
wrong, not just the fix — e.g. combinators point from dependent to
|
|
79
|
+
dependency (parent `>` child), so `#x > *` selects x's
|
|
80
|
+
dependencies, not its dependents. The rule transfers; the fix alone
|
|
81
|
+
doesn't.
|
|
82
|
+
5. **Uncertain match?** Offer to run it: `vlt query '<selector>'`
|
|
83
|
+
(always single-quote the selector in the shell). Output format:
|
|
84
|
+
`--view=human|json|mermaid|svg|png|count` — defaults to human (json
|
|
85
|
+
when piped).
|
|
86
|
+
6. **Iterate**: compare results against the expected outcome from step
|
|
87
|
+
1 — too broad/narrow means refine one piece at a time (add a
|
|
88
|
+
combinator, a pseudo-state, or `:not()`).
|
|
89
|
+
|
|
90
|
+
## Composing a query from a goal
|
|
91
|
+
|
|
92
|
+
Build left to right, in this order — each step is optional:
|
|
93
|
+
|
|
94
|
+
1. **Anchor** — where in the graph? `:root` (top level), `:workspace`,
|
|
95
|
+
`:project`, `#pkg-name`, or nothing (whole graph).
|
|
96
|
+
2. **Traverse** — what relationship? `>` direct deps, ` ` (space)
|
|
97
|
+
anything beneath, `~` siblings. Skip to filter the anchor itself.
|
|
98
|
+
3. **Filter** — chain conditions with no space = AND: attribute
|
|
99
|
+
(`[license=MIT]`), state (`:dev`), functional (`:outdated(major)`),
|
|
100
|
+
negation (`:not(...)`).
|
|
101
|
+
4. **Union** — need OR? Join complete selectors with commas.
|
|
102
|
+
5. **Invert direction** — "what depends on X?" flips traversal: use
|
|
103
|
+
`:has(> #x)` (dependents of x), not `#x > *` (dependencies of x).
|
|
104
|
+
|
|
105
|
+
Worked example — "prod deps of my workspaces with a copyleft license":
|
|
106
|
+
`:workspace` (anchor) + `>` (direct) + `:prod:license(copyleft)`
|
|
107
|
+
(filters) → `vlt query ':workspace > :prod:license(copyleft)'`
|
|
108
|
+
|
|
109
|
+
## Core syntax (mental model: CSS, but nodes are packages)
|
|
110
|
+
|
|
111
|
+
| Piece | Meaning | Example |
|
|
112
|
+
| ----------------------------------- | ------------------------------------------- | ------------------------ |
|
|
113
|
+
| `[name=foo]` / `#foo` | match by package.json field / name shortcut | `[version^=2]`, `#react` |
|
|
114
|
+
| `>` | direct dependency | `:root > *` |
|
|
115
|
+
| ` ` (space) | any transitive dependency | `:root [name=js-tokens]` |
|
|
116
|
+
| `~` | sibling (shares a parent) | `[name=react] ~ *` |
|
|
117
|
+
| `:root` `:project` `:workspace` | graph anchors | `:workspace > :dev` |
|
|
118
|
+
| `:prod` `:dev` `:optional` `:peer` | dependency type | `:dev:outdated` |
|
|
119
|
+
| `:has()` `:not()` `:is()` | structural filters | `:has(> :cve(*))` |
|
|
120
|
+
| `:outdated()` `:semver()` `:type()` | functional filters | `:outdated(major)` |
|
|
121
|
+
| `:malware` `:cve()` `:license()` | security (Socket data, network call) | `:license(copyleft)` |
|
|
122
|
+
| `,` | OR — union of selectors | `:dev, :optional` |
|
|
123
|
+
|
|
124
|
+
Chaining without spaces is AND: `:workspace:private` = workspace AND
|
|
125
|
+
private.
|
|
126
|
+
|
|
127
|
+
## Common recipes
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
vlt query ':root > *' # direct dependencies
|
|
131
|
+
vlt query ':workspace' # select all workspaces
|
|
132
|
+
vlt query ':root > :outdated' # outdated direct deps
|
|
133
|
+
vlt query '[name=react] *' # everything react pulls in
|
|
134
|
+
vlt query ':has(> #react)' # packages that directly depend on react
|
|
135
|
+
vlt query ':dev:eval' # dev deps using eval()
|
|
136
|
+
vlt query ':malware, :cve(*)' # malware or any CVE
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Security auditing (Socket-powered)
|
|
140
|
+
|
|
141
|
+
DSS's sharpest feature: nodes are enriched with Socket insight data,
|
|
142
|
+
so the dependency graph doubles as a security scanner. Selectors group
|
|
143
|
+
into four families — compose them with anchors and combinators like
|
|
144
|
+
any other filter:
|
|
145
|
+
|
|
146
|
+
| Family | Selectors | Ask |
|
|
147
|
+
| --------------- | -------------------------------------------------------------------------------- | -------------------------------------- |
|
|
148
|
+
| Threats | `:malware` `:squat` `:obfuscated` `:suspicious` | is anything actively hostile? |
|
|
149
|
+
| Vulnerabilities | `:vuln(critical)` `:cve(CVE-…)` `:cve(*)` `:cwe(CWE-79)` `:severity(">=medium")` | known CVEs / vulns, filter by severity |
|
|
150
|
+
| Capabilities | `:eval` `:network` `:fs` `:shell` `:env` | what _can_ this code do? |
|
|
151
|
+
| Hygiene | `:abandoned` `:unmaintained` `:deprecated` `:score("<=0.5", "maintenance")` | will this rot on us? |
|
|
152
|
+
|
|
153
|
+
Audit recipes:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
vlt query ':malware, :vuln(critical), :squat, :obfuscated' # supply-chain sweep
|
|
157
|
+
vlt query ':workspace > :prod:severity(">=high")' # release blockers
|
|
158
|
+
vlt query ':dev:shell, :dev:network' # dev deps that spawn/phone home
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
All of these fetch Socket data over the network — expect latency on
|
|
162
|
+
first run.
|
|
163
|
+
|
|
164
|
+
## Gotchas
|
|
165
|
+
|
|
166
|
+
- `:workspace` matches workspaces declared in `vlt.json` — yarn/pnpm/
|
|
167
|
+
bun-style workspace configs aren't read unless mirrored there.
|
|
168
|
+
- `:license(x)` takes a category (`copyleft`, `unlicensed`, `none`,
|
|
169
|
+
…), never a license ID — for a specific license use the attribute
|
|
170
|
+
form `[license=MIT]`.
|
|
171
|
+
- `:missing` matches edges (declarations), not nodes — no package
|
|
172
|
+
output.
|
|
173
|
+
- Quote values with special chars: `[name^="@vltpkg"]`.
|
|
174
|
+
|
|
175
|
+
## Full reference
|
|
176
|
+
|
|
177
|
+
Selector-by-selector detail (all pseudo-classes, security insights,
|
|
178
|
+
operators): see [REFERENCE.md](REFERENCE.md).
|
|
179
|
+
|
|
180
|
+
Canonical docs — deep-link the section that matches the query
|
|
181
|
+
(verified anchors; don't invent others):
|
|
182
|
+
|
|
183
|
+
| Query topic | Link |
|
|
184
|
+
| ----------------------------------------- | ------------------------------------------------------------ |
|
|
185
|
+
| syntax, composition, anything structural | <https://docs.vlt.io/cli/selectors/> |
|
|
186
|
+
| malware / typosquats / obfuscation | <https://docs.vlt.io/cli/security#malware-detection> |
|
|
187
|
+
| CVEs / CWEs / severity | <https://docs.vlt.io/cli/security#vulnerability-detection> |
|
|
188
|
+
| capabilities (`:eval` `:network` `:fs` …) | <https://docs.vlt.io/cli/security#behavioral-security-risks> |
|
|
189
|
+
| license compliance | <https://docs.vlt.io/cli/security#license-compliance> |
|
|
190
|
+
| security scores | <https://docs.vlt.io/cli/security#security-scoring> |
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# dss-query skill evals
|
|
2
|
+
|
|
3
|
+
How we evaluate the [dss-query](../SKILL.md) agent skill:
|
|
4
|
+
|
|
5
|
+
Claude's skill-creator plugin "Evaluate a skill" decomposes into three
|
|
6
|
+
different measurements with different levels of rigor
|
|
7
|
+
|
|
8
|
+
| Layer | Question | Method | LLM involved? | CI-gateable? |
|
|
9
|
+
| ---------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------- | ------------------------------------------- |
|
|
10
|
+
| 1. Content correctness | Are the skill's documented selectors valid and current? | Extract selectors from SKILL.md/REFERENCE.md, parse + execute against the real query engine | No | Yes — deterministic |
|
|
11
|
+
| 2. Content efficacy | Does the skill make model output measurably better? | With-skill vs baseline differential, graded deterministically | As subject, not judge | Not as a hard gate (single-sample variance) |
|
|
12
|
+
| 3. Trigger efficacy | Does the skill activate when it should? | Repeated trigger-rate sampling on the production model | Yes, unavoidably | No — probabilistic, monitor only |
|
|
13
|
+
|
|
14
|
+
Two principles behind this split, learned the hard way:
|
|
15
|
+
|
|
16
|
+
- **Never use an LLM as the judge of a skill written for that LLM** —
|
|
17
|
+
grade with deterministic checks (parse, execute, regex). The LLM may
|
|
18
|
+
be the _subject_ of an eval, never its grader.
|
|
19
|
+
- **A skill's value is its lift over baseline.** A strong model may
|
|
20
|
+
already know the domain (correctness lift ≈ 0) while the skill still
|
|
21
|
+
earns its keep on response style, concision, and latency. Only a
|
|
22
|
+
with/without differential reveals which.
|
|
23
|
+
|
|
24
|
+
## Layer 2: the efficacy differential (primary loop)
|
|
25
|
+
|
|
26
|
+
Lives in [`../../dss-query-workspace/`](../../dss-query-workspace/)
|
|
27
|
+
(gitignored). Test prompts + deterministic assertions are defined in
|
|
28
|
+
[evals.json](evals.json). Each iteration:
|
|
29
|
+
|
|
30
|
+
1. For every eval, spawn two subagents in the same turn: one told to
|
|
31
|
+
read and follow the live SKILL.md (**force-loaded** — this removes
|
|
32
|
+
the trigger confound, see below), one baseline (no skill, or a
|
|
33
|
+
snapshot of the pre-edit skill when iterating).
|
|
34
|
+
2. Grade every answer with [grade.mjs](grade.mjs) (run from
|
|
35
|
+
`src/query`:
|
|
36
|
+
`node skills/dss-query/evals/grade.mjs <iteration-dir>`) — no LLM:
|
|
37
|
+
- extract selectors from the answer (`vlt query '…'` and bare
|
|
38
|
+
code-block selectors);
|
|
39
|
+
- every selector must **parse** via `@vltpkg/dss-parser`;
|
|
40
|
+
- structural selectors must **execute** via `Query.search()`
|
|
41
|
+
against the in-memory fixture graph
|
|
42
|
+
(`src/query/test/fixtures/graph.ts`). Selectors using `:outdated`
|
|
43
|
+
(registry fetch) or security pseudo-selectors (need the Socket
|
|
44
|
+
archive) are parse-checked only, so grading stays offline.
|
|
45
|
+
Comma-separated selectors are split at the top level first —
|
|
46
|
+
multi-selector lists enable the engine's loose mode, which
|
|
47
|
+
silently swallows invalid segments;
|
|
48
|
+
- per-eval regex assertions (expected shape, style contract,
|
|
49
|
+
required caveats).
|
|
50
|
+
3. Aggregate with skill-creator's `aggregate_benchmark` and review
|
|
51
|
+
outputs in its eval viewer; human feedback drives the next skill
|
|
52
|
+
edit, then re-run with the pre-edit snapshot as baseline.
|
|
53
|
+
|
|
54
|
+
Read the benchmark honestly: pass-rate delta is the skill's
|
|
55
|
+
correctness lift; time/token deltas are its efficiency cost/benefit;
|
|
56
|
+
assertions that pass in **both** configs are non-discriminating — they
|
|
57
|
+
can't detect skill regressions on that model (but may on weaker ones).
|
|
58
|
+
|
|
59
|
+
## Layer 1: doc-selector validation
|
|
60
|
+
|
|
61
|
+
Machinery exists in [grade.mjs](grade.mjs) (parse + offline execute);
|
|
62
|
+
a standalone sweep that extracts every selector from
|
|
63
|
+
SKILL.md/REFERENCE.md and validates it the same way is the natural CI
|
|
64
|
+
gate — it catches the regression that actually bites: the query engine
|
|
65
|
+
changes and the skill's documented examples silently go stale.
|
|
66
|
+
|
|
67
|
+
## Adding cases
|
|
68
|
+
|
|
69
|
+
Add to [evals.json](evals.json). Prefer deterministic assertions
|
|
70
|
+
(selector parses, executes, matches shape) over prose matching; make
|
|
71
|
+
prompts realistic (casual phrasing, a wrong attempt to correct,
|
|
72
|
+
project context) rather than textbook questions; and verify any
|
|
73
|
+
factual claim an assertion encodes against the engine source first —
|
|
74
|
+
e.g. `:license()` takes only category kinds, so an eval expecting
|
|
75
|
+
`:license(mit)` would grade correct answers as failures.
|
|
76
|
+
|
|
77
|
+
This directory is excluded from the published `@vltpkg/query` package
|
|
78
|
+
(see the `files` field in `package.json`) — it's repo tooling, not
|
|
79
|
+
part of the skill consumers receive.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "dss-query",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 0,
|
|
6
|
+
"prompt": "How do I find outdated direct dependencies of my project root with vlt?",
|
|
7
|
+
"expected_output": "A vlt query using ':root > :outdated' (optionally with a specifier like major), with a one-line explanation. Concise — query first, no long preamble.",
|
|
8
|
+
"files": [],
|
|
9
|
+
"assertions": [
|
|
10
|
+
"proposes-root-outdated-selector: at least one extracted selector matches /:root\\s*>\\s*:outdated/",
|
|
11
|
+
"all-selectors-parse: every `vlt query '<sel>'` selector in the answer parses via @vltpkg/dss-parser",
|
|
12
|
+
"selector-executes-on-fixture-graph: the primary (structural) selector runs through Query.search() against the in-memory fixture graph without throwing",
|
|
13
|
+
"query-first-style: a fenced code block containing the vlt query appears before any multi-sentence explanation"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": 1,
|
|
18
|
+
"prompt": "Write a DSS query for prod dependencies of my workspaces that have a MIT license.",
|
|
19
|
+
"expected_output": "A vlt query like ':workspace > :prod[license=MIT]' — workspace anchor, direct-dep combinator, prod filter chained with the [license=MIT] attribute. Must NOT suggest ':license(mit)': the :license() pseudo only accepts category kinds (copyleft, unlicensed, none, ...), so specific license IDs require the attribute form.",
|
|
20
|
+
"files": [],
|
|
21
|
+
"assertions": [
|
|
22
|
+
"uses-license-attribute-form: a selector matches /\\[license\\^?=\\s*['\"]?MIT/i (attribute form for a specific license ID)",
|
|
23
|
+
"avoids-invalid-license-pseudo: the answer does NOT propose :license(mit) — :license() only accepts category kinds, so this would throw 'Expected a valid license kind'",
|
|
24
|
+
"workspace-prod-anchored: a selector matches /:workspace\\s*>\\s*:prod/",
|
|
25
|
+
"all-selectors-parse: every extracted selector parses via @vltpkg/dss-parser"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": 2,
|
|
30
|
+
"prompt": "What vlt query shows me which packages directly depend on react? I keep writing '#react > *' and getting the wrong thing.",
|
|
31
|
+
"expected_output": "Inverted-direction query using ':has(> #react)' (dependents), correcting the user's '#react > *' (which selects react's dependencies, not its dependents).",
|
|
32
|
+
"files": [],
|
|
33
|
+
"assertions": [
|
|
34
|
+
"uses-has-inversion: a selector matches /:has\\(\\s*>\\s*(#react|\\[name=react\\])\\s*\\)/",
|
|
35
|
+
"corrects-direction-mistake: states that '#react > *' selects react's DEPENDENCIES (children), i.e. wrong direction for finding dependents (grader quotes evidence)",
|
|
36
|
+
"does-not-present-wrong-selector-as-answer: '#react > *' is not offered as the solution",
|
|
37
|
+
"all-selectors-parse: every extracted selector parses via @vltpkg/dss-parser"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 3,
|
|
42
|
+
"prompt": "What does the vlt query ':workspace > :prod:cve(*)' do?",
|
|
43
|
+
"expected_output": "Left-to-right decomposition: workspaces anchor, direct dependencies, production type, has any CVE. Should mention security selectors hit the network (Socket data).",
|
|
44
|
+
"files": [],
|
|
45
|
+
"assertions": [
|
|
46
|
+
"covers-workspace-anchor: explanation mentions workspaces as the starting set (/workspace/i)",
|
|
47
|
+
"covers-direct-prod-segment: explanation mentions direct AND production dependencies (/direct/i and /prod/i)",
|
|
48
|
+
"covers-cve-segment: explanation says it matches packages with any known CVE (/cve/i)",
|
|
49
|
+
"mentions-security-data-source: notes that :cve() uses Socket security data / a network call (/socket|network/i)"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": 4,
|
|
54
|
+
"prompt": "We just got a supply-chain security alert at work. What vlt queries should I run to audit our dependency graph for malware, typosquats, and obfuscated code?",
|
|
55
|
+
"expected_output": "A supply-chain sweep using threat selectors — e.g. ':malware(critical), :squat, :obfuscated' (union or separate queries). Notes Socket data / network latency. Offers scoping or follow-up queries.",
|
|
56
|
+
"files": [],
|
|
57
|
+
"assertions": [
|
|
58
|
+
"uses-threat-selectors: selectors include :malware AND at least one of :squat / :obfuscated / :suspicious",
|
|
59
|
+
"all-selectors-parse: every extracted selector parses via @vltpkg/dss-parser",
|
|
60
|
+
"mentions-security-data-source: notes Socket data / network fetch (/socket|network/i)",
|
|
61
|
+
"offers-related-queries: at least 2 distinct selectors offered"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": 5,
|
|
66
|
+
"prompt": "Which of my dev dependencies can run shell commands or hit the network? We're locking down CI.",
|
|
67
|
+
"expected_output": "Capability query composing :dev with :shell and :network — e.g. ':dev:shell, :dev:network' (chained AND, comma OR). Explains capabilities = what the code can do (Socket static analysis).",
|
|
68
|
+
"files": [],
|
|
69
|
+
"assertions": [
|
|
70
|
+
"uses-capability-selectors: a selector chains :dev with :shell or :network (e.g. :dev:shell)",
|
|
71
|
+
"covers-both-capabilities: both shell and network are queried (union or two queries)",
|
|
72
|
+
"all-selectors-parse: every extracted selector parses via @vltpkg/dss-parser",
|
|
73
|
+
"explains-capability-meaning: explains these match what code CAN do / Socket analysis (/socket|static|capab|can /i)"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": 6,
|
|
78
|
+
"prompt": "Before our release I want to check whether any prod deps of our workspaces have high or critical severity vulnerabilities. What's the vlt query?",
|
|
79
|
+
"expected_output": "Severity-filtered composition anchored at workspaces — e.g. ':workspace > :prod:severity(\">=high\")' (or union of severity(high), severity(critical)). Explains the comparator and mentions Socket/network.",
|
|
80
|
+
"files": [],
|
|
81
|
+
"assertions": [
|
|
82
|
+
"uses-severity-filter: a selector uses :severity(...) or :sev(...)",
|
|
83
|
+
"anchors-workspace-prod: a selector matches /:workspace\\s*>\\s*:prod/",
|
|
84
|
+
"all-selectors-parse: every extracted selector parses via @vltpkg/dss-parser",
|
|
85
|
+
"mentions-security-data-source: notes Socket data / network fetch (/socket|network/i)"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|