Files
fkysly 48580f8a5e feat(catalog): scan what each plugin touches, and publish it as facts (#401)
The catalog now carries capability disclosure: `capabilities` and
`capabilityRedLines` per entry, scanned at build time from the artifact a user
would install. dsh-market renders them on the card; nothing here says "safe",
and no surface is asked to decide anything — #209 settled that a badge stops
people reading while the misses are guaranteed to exist.

- **scanSourceFor** picks the artifact in the order a user would install it:
  the npm package when the entry is published there, the author's prebuilt
  release tarball when that is the only distribution, and the repository's own
  codeload archive otherwise (`HEAD`, so no branch name and no API call).
  Subdirectory entries are scanned AT the subdirectory: the monorepo root
  would report every sibling's capabilities as this plugin's.
- **Incremental by release, then by age.** A new npm version invalidates the
  record; a branch tarball, which can change under the same URL, expires after
  PROBE_RECHECK_DAYS. A normal push rescans a handful.
- **A failure writes nothing.** Download errors, scanner crashes, an output
  shape this code does not understand — the previous record stays, and an
  entry with no record stays absent from plugins.json, which the market
  renders as 未扫描 rather than 未检出. The two are different sentences and
  only one of them is about the plugin.
- **`score`, `band` and `verdict` never leave the scanner.** Upstream says the
  band is not a pre-install verdict; dropping them here means no surface can
  render a plugin as green even by accident.
- The scanner is pinned as a devDependency (version in package.json and the
  lockfile, so a bump is a reviewed diff) and invoked through the lockfile's
  binary; `npx` remains the fallback for a checkout without node_modules.

Two things measured while building this, both fixed here:

- `execFileSync` in the worker pool blocked the event loop, so CONCURRENCY was
  a lie: the first full pass ran one entry at a time for fifty minutes and had
  written nothing. Async children later: eight in flight, ~3 entries/second.
- A failure summary that says "957 unreadable" is not actionable; it now
  repeats the scanner's own sentence — `primary entry unreadable or missing:
  lib/index.js` is what showed these were packages whose repository does not
  ship its build product, and that the real cause was a missing
  data/npm-map.json sending every entry down the GitHub branch.

First full pass: 3845 of 4279 entries scanned (90%); 454 carry a red line, the
most common being "reads credentials/secrets AND has network access", then
"runs code at install time (postinstall)". The 434 without a record are mostly
a scanner limitation, not a gap we can close here — its own sentence is
`primary entry unreadable or missing: lib/index.js`, i.e. a package whose
shipped artifact does not contain the built entry it looks for — and the
surfaces print those as 未扫描, which is true.

The data file is committed like stars/downloads, for the same reason: "a failed
probe keeps what is on disk" is worth nothing if nothing is ever on disk.
2026-09-25 01:50:54 +08:00

29 lines
646 B
JSON

{
"name": "awesome-dsh-plugin",
"version": "0.1.0",
"description": "A curated list of DeepSeek Harness (dsh) plugins · DeepSeek Harness 插件精选列表",
"homepage": "https://awesome-dsh-plugin.com",
"repository": {
"type": "git",
"url": "git+https://github.com/awesome-dsh-plugin/awesome-dsh-plugin.git"
},
"license": "CC0-1.0",
"files": [
"README.md",
"README.zh.md"
],
"keywords": [
"awesome",
"awesome-list",
"dsh",
"dsh-plugin",
"deepseek-harness",
"deepseek"
],
"devDependencies": {
"dsh-trust-check": "^0.1.13",
"js-yaml": "^5.3.0",
"marked": "^18.0.9"
}
}