upstream-radar 0.40.0 → 0.42.0

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.
Files changed (56) hide show
  1. package/README.md +72 -241
  2. package/README.zh-CN.md +89 -0
  3. package/dist/src/cli.js +11 -2
  4. package/dist/src/cli.js.map +1 -1
  5. package/dist/src/dsh-compatibility-ir.d.ts +99 -0
  6. package/dist/src/dsh-compatibility-ir.d.ts.map +1 -0
  7. package/dist/src/dsh-compatibility-ir.js +408 -0
  8. package/dist/src/dsh-compatibility-ir.js.map +1 -0
  9. package/dist/src/dsh-compatibility-issues.d.ts +46 -0
  10. package/dist/src/dsh-compatibility-issues.d.ts.map +1 -0
  11. package/dist/src/dsh-compatibility-issues.js +223 -0
  12. package/dist/src/dsh-compatibility-issues.js.map +1 -0
  13. package/dist/src/dsh-compatibility-ledger.d.ts +152 -0
  14. package/dist/src/dsh-compatibility-ledger.d.ts.map +1 -0
  15. package/dist/src/dsh-compatibility-ledger.js +678 -0
  16. package/dist/src/dsh-compatibility-ledger.js.map +1 -0
  17. package/dist/src/dsh-directory-feed.d.ts +108 -0
  18. package/dist/src/dsh-directory-feed.d.ts.map +1 -0
  19. package/dist/src/dsh-directory-feed.js +267 -0
  20. package/dist/src/dsh-directory-feed.js.map +1 -0
  21. package/dist/src/dsh-install-observation.d.ts +89 -1
  22. package/dist/src/dsh-install-observation.d.ts.map +1 -1
  23. package/dist/src/dsh-install-observation.js +658 -19
  24. package/dist/src/dsh-install-observation.js.map +1 -1
  25. package/dist/src/dsh-install-plan.d.ts +16 -6
  26. package/dist/src/dsh-install-plan.d.ts.map +1 -1
  27. package/dist/src/dsh-install-plan.js +273 -47
  28. package/dist/src/dsh-install-plan.js.map +1 -1
  29. package/dist/src/dsh-plugin.d.ts.map +1 -1
  30. package/dist/src/dsh-plugin.js +6 -2
  31. package/dist/src/dsh-plugin.js.map +1 -1
  32. package/dist/src/dsh-runtime.d.ts +6 -0
  33. package/dist/src/dsh-runtime.d.ts.map +1 -1
  34. package/dist/src/dsh-runtime.js +38 -0
  35. package/dist/src/dsh-runtime.js.map +1 -1
  36. package/dist/src/index.d.ts +8 -4
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.js +5 -1
  39. package/dist/src/index.js.map +1 -1
  40. package/dist/src/installed-graph.d.ts.map +1 -1
  41. package/dist/src/installed-graph.js +105 -26
  42. package/dist/src/installed-graph.js.map +1 -1
  43. package/dist/src/radar-types.d.ts +15 -0
  44. package/dist/src/radar-types.d.ts.map +1 -1
  45. package/dist/src/semver.d.ts.map +1 -1
  46. package/dist/src/semver.js +7 -1
  47. package/dist/src/semver.js.map +1 -1
  48. package/dist/src/tar.d.ts.map +1 -1
  49. package/dist/src/tar.js +28 -13
  50. package/dist/src/tar.js.map +1 -1
  51. package/dist/src/version.d.ts +1 -1
  52. package/dist/src/version.js +1 -1
  53. package/docs/README.zh-CN.md +25 -23
  54. package/package.json +3 -1
  55. package/schemas/dsh-compatibility-ir.schema.json +96 -0
  56. package/schemas/dsh-install-observation.schema.json +141 -2
package/README.md CHANGED
@@ -1,266 +1,97 @@
1
- # Upstream Radar
1
+ <h1 align="center">Upstream Radar</h1>
2
2
 
3
- [![CI](https://github.com/MicroMilo/upstream-radar/actions/workflows/ci.yml/badge.svg)](https://github.com/MicroMilo/upstream-radar/actions)
4
- [![npm](https://img.shields.io/npm/v/upstream-radar)](https://www.npmjs.com/package/upstream-radar)
5
- [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
3
+ <p align="center"><strong>Know which DeepSeek Harness plugins break after every release—before users do.</strong></p>
6
4
 
7
- **The upstream dependency radar built into [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) plugins.**
5
+ <p align="center">
6
+ English · <a href="README.zh-CN.md">简体中文</a>
7
+ </p>
8
8
 
9
- Upstream Radar is not another package-name vulnerability scanner. It follows one DSH plugin from admission to maintenance:
9
+ <p align="center">
10
+ <a href="https://github.com/MicroMilo/upstream-radar/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/MicroMilo/upstream-radar/actions/workflows/ci.yml/badge.svg"></a>
11
+ <a href="https://www.npmjs.com/package/upstream-radar"><img alt="npm" src="https://img.shields.io/npm/v/upstream-radar"></a>
12
+ <a href="https://github.com/MicroMilo/upstream-radar/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/MicroMilo/upstream-radar"></a>
13
+ <a href="LICENSE"><img alt="Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
14
+ </p>
10
15
 
11
- | Product job | What Radar establishes |
12
- | --- | --- |
13
- | **DSH compatibility / admission** | Whether the exact published bundle can be installed, registered, and loaded by the DSH releases you care about, with an isolated execution lane for behavior evidence. |
14
- | **Real dependency graph** | Which exact package versions and physical paths the plugin brings into the DSH profile, including unresolved edges. |
15
- | **Continuous upstream monitoring** | Whether an advisory, npm release, DSH/Cordis change, or breaking signal changes the old → new situation. |
16
- | **Author-facing repair** | Which plugin, dependency path, version, lockfile, or DSH declaration gives the author a concrete next fix. |
16
+ Upstream Radar continuously retests a maintained fleet of exact published
17
+ plugins against changing
18
+ [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness)
19
+ releases in disposable runners. When a pair breaks, it produces a reproducible
20
+ issue; when the author ships a fix, it retests and closes the loop.
17
21
 
18
- The deterministic scanner establishes package, graph, advisory, and compatibility facts. Only a meaningful affected change is handed to the DSH Agent for read-only, project-specific analysis; the model does not guess version matches or replace the evidence.
22
+ **100 maintained install/load targets · 100 catalog entries across all 21 categories · 4 upstream reports closed**
19
23
 
20
- ## The product loop
24
+ [Latest full fleet run](https://github.com/MicroMilo/upstream-radar/actions/runs/32637649422):
25
+ **96 executable catalog cells observed · 67 compatible · 29 need review · 0 reproduced incompatibilities · 4 source-only**.
26
+ Review signals are never advertised as plugin failures.
21
27
 
22
- ```mermaid
23
- flowchart TD
24
- A["DSH plugin source or exact npm artifact"] --> B["Static review + DSH compatibility check"]
25
- B --> C["Build the real plugin → dependency graph"]
26
- C --> D["Monitor advisories, npm, DSH and Cordis changes"]
27
- D --> E{"Meaningful affected change?"}
28
- E -- "No" --> F["Update observation point and stay quiet"]
29
- E -- "Yes" --> G["Calculate exact old → new impact paths"]
30
- G --> H["Send bounded evidence to the DSH Agent"]
31
- H --> I["Return a repairable action to the plugin author"]
32
- ```
33
-
34
- This is the boundary: Radar decides **what changed and which exact path is involved**; DSH decides **what that means for the project**. A later website can visualize the saved graph, but the evidence and impact index are already useful without one.
35
-
36
- ## The upstream/downstream alignment IR
28
+ ## Why it exists
37
29
 
38
- Every observer snapshot now carries a small, machine-readable alignment record:
30
+ A healthy repository does not prove that its published plugin still works.
31
+ The artifact users install must resolve against a specific DSH host, Node
32
+ runtime, profile, and dependency set—and any of them can change overnight.
39
33
 
40
- ```text
41
- upstream: Git commit + package.json coordinate
42
- downstream: npm coordinate + lockfile graph root + graph coverage
43
- result: aligned | mismatch | unknown
44
- ```
45
-
46
- This catches a class of problems that a vulnerability scanner cannot: the source
47
- package, published package, and dependency graph may no longer describe the
48
- same thing. For example, the public DSH/Feishu target currently reports:
49
-
50
- ```text
51
- source: dsh-lark-bot@0.15.8
52
- published: dsh-feishu-bot@0.15.8
53
- graph root: dsh-lark-bot@0.15.8
54
- result: mismatch
55
- ```
56
-
57
- That is not a claim of malware or runtime incompatibility. It is an evidence
58
- gap: Radar cannot safely say that the source it watched produced the artifact
59
- users install. The IR is stored in `observations.json`, rendered in the first
60
- baseline report, and defined in [`schemas/upstream-downstream-ir.schema.json`](schemas/upstream-downstream-ir.schema.json).
61
-
62
- ## Try it in 60 seconds
63
-
64
- ```bash
65
- # No DSH profile, API key, or network state required
66
- npx --yes upstream-radar@0.40.0 demo
67
-
68
- # Scan a public DSH plugin repository without installing it
69
- npx --yes upstream-radar@0.40.0 scan \
70
- https://github.com/PlutoKeating/dsh-lark-bot \
71
- --fail-on never
72
-
73
- # Review a real browser plugin users would install, then check two DSH releases
74
- npx --yes upstream-radar@0.40.0 review dsh-plugin dsh-cloudflare-browser-run@0.1.1 \
75
- --dsh-version 0.1.0-rc.6,0.1.0-rc.7
76
- ```
34
+ Upstream Radar checks the relationship, not just the two repositories. A local
35
+ pre-publish check asks, “does this plugin pass today?” Radar asks, “which
36
+ maintained plugins stopped passing after the ecosystem changed?”
77
37
 
78
- The important output is evidence, not a green badge: exact package identity, dependency paths, unresolved edges, install-time scripts, npm integrity/signature/provenance, advisory matches, and DSH load results.
38
+ ## The loop
79
39
 
80
- ## The isolated execution lane
81
-
82
- Static metadata tells us that a lifecycle script exists; it cannot tell us what
83
- actually ran. The new [`dsh-install` workflow](.github/workflows/observe-dsh-plugin-install.yml)
84
- therefore uses a separate, deliberately untrusted lane:
85
-
86
- ```text
87
- fresh GitHub-hosted VM (no secrets, read-only repository token)
88
- restricted container (no host workspace or Docker socket)
89
- npm pack exact package@version with scripts disabled
90
- enforce the artifact's declared Node range before plugin code can run
91
- → record the exact Node and pnpm runtime used by the check
92
- → DSH installs that same tarball with only the declared dependency-build approvals
93
- → strace records child processes, network destinations and file writes
94
- → DSH loads the registered bundle under the same exact release
95
- → bounded JSON report survives and a non-compatible pair fails the check
96
- → the container and VM are discarded
97
- ```
98
-
99
- Use **Actions → Observe one DSH plugin install** and supply one exact plugin and
100
- one exact DSH version. The CLI also exposes `probe dsh-install`, but it refuses
101
- to run unless both `--execute` and `UPSTREAM_RADAR_ISOLATED_RUNNER=1` are present;
102
- it is not intended as a normal laptop command.
103
-
104
- This lane is wired into the always-on observer. Radar now watches the official
105
- `@deepseek-ai/dsh` `next` release channel (current DSH releases are prereleases
106
- rather than npm `latest`). A new exact DSH publication fans out the
107
- [nine-plugin maintained corpus](examples/dsh/install-observer/targets.json), one
108
- fresh VM per plugin. Six of those targets come from an identity-checked,
109
- [commit-pinned `awesome-dsh-plugin` cohort](examples/dsh/awesome-observer/README.md);
110
- two additional catalog targets are source-only because their real distribution
111
- is GitHub rather than npm. A mapped plugin publication retests only that plugin. Unchanged
112
- evidence keeps `observations.json` byte-stable, persistent source/publish drift
113
- does not wake the Agent again, and the DSH Agent/API key never enters the execution job.
114
- Build-script approvals are exact package names stored in the maintained target
115
- and copied into every report; an absent list approves nothing.
116
-
117
- The first implementation is intentionally honest about its limit: a container
118
- shares the hosted VM's kernel, and same-container `strace` evidence is not
119
- tamper-proof against determined malicious code. The outer VM is disposable and
120
- secret-free; a Firecracker collector is the later high-assurance backend, not a
121
- claim made by this report. See the [execution boundary and result semantics](examples/dsh/install-observer/README.md)
122
- and [`dsh-install-observation.schema.json`](schemas/dsh-install-observation.schema.json).
123
-
124
- ## What we have already found
125
-
126
- These are real, reproducible cases in this repository—not synthetic “vulnerable package” demos.
127
-
128
- | Case | Finding | Why it matters |
129
- | --- | --- | --- |
130
- | [Live DSH `0.1.1-rc.1` isolated matrix](examples/dsh/install-observer/reports/2026-08-21-dsh-0.1.1-rc.1.md) | Eight exact artifacts install/register/load under their recorded contracts; OpenPencil is stopped before execution because it requires Node ≥24.11 while the isolated runner is Node 22.23; Better Sidebar passes only with its documented `node-pty` build approval and a real native toolchain | The imported awesome cohort found both a genuine runtime-pair incompatibility and a test-environment defect, while preserving the evidence that distinguishes them. |
131
- | [`dsh-cloudflare-browser-run@0.1.1`](examples/reports/dsh-cloudflare-browser-run-0.1.1.txt) | 18 resolved packages, 2 unresolved optional Cordis edges, 0 known vulnerabilities, and DSH rc.6/rc.7 both loaded the bundle | A real browser plugin demonstrates the DSH admission boundary and why incomplete edges stay visible. |
132
- | [50-plugin batch](examples/dsh/reports/dsh-batch-50-2026-08-17.md) / [real graph corpus](examples/dsh/first-batch/README.md) | 50 source scans, 30 exact npm reviews, 37 real plugin graphs indexed; 13 targets kept as missing evidence | The reverse index is now built from real DSH plugins, and missing graphs are not treated as clean. |
133
- | [`dsh-feishu-bot@0.15.8`](examples/dsh/reports/dsh-feishu-bot-0.15.8-review-2026-08-18.md) | 89-package graph, 12 unresolved optional edges, reachable `protobufjs` `postinstall`, DSH rc.6/rc.7 compatible | “No known CVE” is not the same as “no installation trust boundary.” |
134
- | [DSH-TUI source vs npm](examples/dsh/reports/dsh-tui-source-vs-npm-2026-08-18.md) | Source has `prepare`; published artifact does not | Source-only and artifact-only reviews answer different questions. |
135
- | [dsh-composer-expand](examples/dsh/reports/dsh-composer-expand-lockfile-feedback.md) | Committed lockfile root says `0.1.0` while source says `0.1.2` | A small author-fix can restore the identity of the monitored graph. |
136
-
137
- We report a confirmed vulnerability only when the affected exact version and runtime path are supported by the available evidence. Development-only hits, missing data, and advisory-source outages remain visibly different states.
138
-
139
- ## Monitor the findings we already found
140
-
141
- The repository now has a focused watch for seven real DSH plugins from the first
142
- batch. It re-runs the source scan and the exact npm artifact review, then stores
143
- only trusted observations in [`state.json`](examples/dsh/finding-watch/state.json)
144
- and writes the current author-facing result to
145
- [`report.md`](examples/dsh/finding-watch/report.md).
146
-
147
- ```bash
148
- pnpm run monitor:dsh-findings
149
- ```
150
-
151
- The watch distinguishes `persisting`, `added`, `resolved`, `changed`, and
152
- `unknown`. A failed registry request never becomes “resolved”; a source fix also
153
- does not erase a finding that remains in the published npm artifact. The same
154
- loop runs daily in [the dedicated GitHub Actions workflow](.github/workflows/dsh-finding-watch.yml)
155
- and commits the state only when a trusted observation changes. It does not install
156
- plugins, execute lifecycle scripts, load DSH, or call an LLM.
157
-
158
- The current run is already useful: `dsh-msg-hub@0.1.8` has removed the old source
159
- lockfile findings, but its npm artifact still reaches `protobufjs@7.6.5` with a
160
- `postinstall`; `dsh-wsl-workspace` now resolves `koffi@3.1.6`, while the native
161
- install step remains. The other reviewed install/lifecycle findings persist.
162
-
163
- ## The dependency graph behind every alert
164
-
165
- ```text
166
- plugin@1.0.0
167
- ├── framework@2.4.7
168
- │ ├── parser@3.2.1
169
- │ └── archive@1.8.0
170
- └── logger@4.0.2
171
- └── parser@2.9.0 ← the affected physical node
172
- ```
173
-
174
- Two copies of `parser` are different nodes. An alert names the exact version and path that entered the DSH profile; it does not page every plugin that happens to use the same package name.
175
-
176
- For a collection of saved reports, build the reverse index that turns an upstream package update into affected plugins:
177
-
178
- ```bash
179
- npx --yes upstream-radar@0.40.0 graph reverse ./reports \
180
- --output reverse-dependency-index.json
181
-
182
- # Ask: which plugins currently depend on this exact package?
183
- npx --yes upstream-radar@0.40.0 graph reverse ./reports \
184
- --package parser@2.9.0
185
-
186
- # Rebuild the checked-in index from the real first 50 DSH plugin reports
187
- pnpm run refresh:dsh-batch
188
- ```
189
-
190
- The generated JSON preserves exact paths such as:
191
-
192
- ```text
193
- plugin@1.0.0 → logger@4.0.2 → parser@2.9.0
194
- ```
195
-
196
- It also preserves whether the graph is complete or has unresolved optional/peer edges. A later website can visualize this index; the index and evidence remain the product foundation.
197
-
198
- To route an upstream old → new change to that index, pass it to the always-on
199
- observer:
200
-
201
- ```bash
202
- npx --yes upstream-radar@0.40.0 observe ./targets.yml \
203
- --reverse-index ./reverse-dependency-index.json \
204
- --state ./observations.json \
205
- --report ./upstream-radar-observer.md
40
+ ```mermaid
41
+ flowchart TB
42
+ Schedule["Scheduled GitHub Action"] --> Watch["Watch DSH + plugin releases"]
43
+ Watch --> Matrix["Exact plugin × DSH matrix"]
44
+ Matrix --> Static["Static contract checks"]
45
+ Matrix --> Runtime["Disposable runner: install → register → load"]
46
+ Static --> Evidence["Reproducible compatibility evidence"]
47
+ Runtime --> Evidence
48
+ Evidence --> Issue["One fixable issue"]
49
+ Issue --> Fix["Author publishes a fix"]
50
+ Fix --> Watch
206
51
  ```
207
52
 
208
- The observer matches by package name, not only by the new exact version. If
209
- `parser@1.0.0` becomes `parser@2.0.0` upstream while a downstream plugin still
210
- uses `parser@1.0.0`, the report names that plugin and its path as a possible
211
- impact. `complete` or `incomplete` coverage stays attached to the result; this
212
- is an evidence-based routing signal, not a claim that the plugin is already
213
- broken. See the persisted index definition in
214
- [`schemas/reverse-dependency-index.schema.json`](schemas/reverse-dependency-index.schema.json).
53
+ Radar establishes the result with deterministic evidence. An optional DSH
54
+ Agent can explain impact and suggest the next action, but a model never turns
55
+ missing evidence into a pass.
215
56
 
216
- The checked-in real-corpus replay makes this concrete: an observed
217
- `@deepseek-ai/cordis@4.0.1 → 4.0.2` change routes to 17 DSH plugins from the
218
- first 50-plugin batch. The route is marked `incomplete` because 26 of the 37
219
- reconstructed graphs contain unresolved edges; the other 13 targets are kept
220
- outside the index as missing evidence. Run `pnpm run showcase:observer` to
221
- replay baseline → one Agent task → quiet run without network access.
57
+ ## What you get
222
58
 
223
- ## GitHub Action
59
+ - An exact result for `plugin version × DSH version × Node/profile`, not a
60
+ timeless “compatible” badge.
61
+ - Static dependency and peer-contract checks joined with real
62
+ install/register/load evidence from the published artifact.
63
+ - A maintained result that is retested when DSH or the plugin changes.
64
+ - One managed issue that is updated on repeat failures, reopened on regression,
65
+ and closed after a clean retest.
224
66
 
225
- The repository already contains a reusable, composite Action in [`action.yml`](action.yml). It runs the same frozen Radar check in CI and writes a short Job Summary.
67
+ ## Upstream reports now closed
226
68
 
227
- ```yaml
228
- - uses: MicroMilo/upstream-radar@v0.40.0
229
- with:
230
- config: upstream-radar.config.json
231
- fail-on: high
232
- ```
233
-
234
- See the [consumer workflow](examples/github-actions/consumer/README.md) for config and lockfile examples. The GitHub Marketplace prompt is a distribution opportunity, not a separate scanning engine: the Action listing should follow a reviewed stable release, while exact tags remain copyable and auditable.
69
+ We opened the following reports; their upstream maintainers have now closed
70
+ them:
235
71
 
236
- ## What it does—and does not do
72
+ - [Sanqi-normal/dsh-webui-market-plugin#5](https://github.com/Sanqi-normal/dsh-webui-market-plugin/issues/5)
73
+ - [1na-ko/dsh-hdc-bridge#3](https://github.com/1na-ko/dsh-hdc-bridge/issues/3)
74
+ - [6Mikao9/dsh-wsl-workspace#6](https://github.com/6Mikao9/dsh-wsl-workspace/issues/6)
75
+ - [3274375092/dsh-voice#2](https://github.com/3274375092/dsh-voice/issues/2)
237
76
 
238
- | It does | It does not claim |
239
- | --- | --- |
240
- | Reconstruct exact npm/pnpm dependency paths | An empty finding list is a safety certificate |
241
- | Query OSV and GitHub Advisory evidence for exact versions | A missing provenance statement proves maliciousness |
242
- | Compare source and published artifact evidence | Static review replaces runtime evidence |
243
- | Observe exact install/load behavior in a disposable VM and restricted container | One observed run proves adversarial code is safe |
244
- | Check DSH bundle/profile compatibility without business actions | “Compatible” means the plugin is secure |
245
- | Monitor old → new upstream observations | An LLM can repair evidence that was never collected |
246
-
247
- ## Install and connect to DSH
77
+ ## Run one check
248
78
 
249
79
  ```bash
250
- pnpm add upstream-radar
251
-
252
- # Generate a reviewable DSH profile inventory from the installed profile
253
- npx --yes upstream-radar@0.40.0 setup
80
+ npx --yes upstream-radar@0.42.0 review dsh-plugin \
81
+ <package>@<version> \
82
+ --dsh-version <dsh-version>
254
83
  ```
255
84
 
256
- For Feishu/webhook routing, DSH Agent handoff, observer state, report schemas, and troubleshooting, use the [full Chinese guide](docs/README.zh-CN.md). The [architecture notes](docs/architecture.md) explain the boundaries and evidence model.
85
+ For code-executing checks, use the maintained
86
+ [isolated observer workflow](.github/workflows/observe-dsh-plugin-install.yml):
87
+ each pair receives a fresh, secret-free GitHub-hosted VM and restricted
88
+ container.
257
89
 
258
- ## Development
259
-
260
- ```bash
261
- pnpm install
262
- pnpm test
263
- pnpm run release:check
264
- ```
90
+ Inspect the [live compatibility matrix](examples/dsh/install-observer/README.md),
91
+ the [directory-consumable evidence feed](feeds/dsh-plugin-compatibility.md),
92
+ the [first 50-plugin corpus](examples/dsh/first-batch/README.md), or the
93
+ [architecture notes](docs/architecture.md).
265
94
 
266
- The project is Apache-2.0 licensed. Contributions that improve a real DSH plugin report, dependency resolution, advisory matching, or reproducible author feedback are especially welcome.
95
+ <p align="center">
96
+ <strong>If Upstream Radar helps the DSH ecosystem stay compatible, <a href="https://github.com/MicroMilo/upstream-radar">please give it a Star</a> ⭐</strong>
97
+ </p>
@@ -0,0 +1,89 @@
1
+ <h1 align="center">Upstream Radar</h1>
2
+
3
+ <p align="center"><strong>每次 DeepSeek Harness 发布后,在用户踩坑前找出哪些插件坏了。</strong></p>
4
+
5
+ <p align="center">
6
+ <a href="README.md">English</a> · 简体中文
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://github.com/MicroMilo/upstream-radar/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/MicroMilo/upstream-radar/actions/workflows/ci.yml/badge.svg"></a>
11
+ <a href="https://www.npmjs.com/package/upstream-radar"><img alt="npm" src="https://img.shields.io/npm/v/upstream-radar"></a>
12
+ <a href="https://github.com/MicroMilo/upstream-radar/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/MicroMilo/upstream-radar"></a>
13
+ <a href="LICENSE"><img alt="Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>
14
+ </p>
15
+
16
+ Upstream Radar 持续把一批真实插件发布物放到一次性隔离环境中,与不断变化的
17
+ [DeepSeek Harness(DSH)](https://github.com/deepseek-ai/deepseek-harness)
18
+ 版本重新配对测试。某个组合坏了,就生成一条可复现的 Issue;作者发布修复后,
19
+ Radar 会再次检查并关闭闭环。
20
+
21
+ **维护 100 个安装/加载目标 · 覆盖目录全部 21 个类别 · 4 条上游报告已关闭**
22
+
23
+ [最近一次全量运行](https://github.com/MicroMilo/upstream-radar/actions/runs/32637649422):
24
+ **观测 96 个可执行目录插件 · 67 个兼容 · 29 个需要复核 · 0 个复现不兼容 · 4 个仅源码目标**。
25
+ 需要复核的信号不会被宣传成插件故障。
26
+
27
+ ## 为什么需要它
28
+
29
+ 仓库看起来正常,不代表用户实际安装的插件仍然可用。真实发布物必须同时适配某个
30
+ DSH 版本、Node 运行时、profile 和依赖组合;其中任何一项更新,都可能让插件一夜
31
+ 之间失效。
32
+
33
+ Upstream Radar 检查的是这层真实关系,而不只是分别看两个仓库。本地发布前检查
34
+ 回答“这个插件今天能不能过”;Radar 回答“生态变化后,维护中的哪些插件不再能过”。
35
+
36
+ ## 完整闭环
37
+
38
+ ```mermaid
39
+ flowchart TB
40
+ Schedule["定时 GitHub Action"] --> Watch["观察 DSH 与插件发布"]
41
+ Watch --> Matrix["精确的插件 × DSH 测试矩阵"]
42
+ Matrix --> Static["静态契约检查"]
43
+ Matrix --> Runtime["一次性环境:安装 → 注册 → 加载"]
44
+ Static --> Evidence["可复现的兼容性证据"]
45
+ Runtime --> Evidence
46
+ Evidence --> Issue["一条可修复的 Issue"]
47
+ Issue --> Fix["作者发布修复"]
48
+ Fix --> Watch
49
+ ```
50
+
51
+ Radar 用确定性证据得出结果。DSH Agent 可以补充影响解释和下一步建议,但模型不能
52
+ 把缺失的证据说成通过。
53
+
54
+ ## 你会得到什么
55
+
56
+ - `插件版本 × DSH 版本 × Node/profile` 的精确结果,而不是永不过期的“兼容”标签。
57
+ - 把静态依赖和 peer 契约,与真实发布物的安装、注册、加载结果放在一起判断。
58
+ - DSH 或插件变化后自动重新检查,而不是只生成一次报告。
59
+ - 同一问题持续更新;回归时重新打开;干净复测通过后自动关闭。
60
+
61
+ ## 已关闭的上游报告
62
+
63
+ 以下报告由我们提出,目前均已被对应上游维护者关闭:
64
+
65
+ - [Sanqi-normal/dsh-webui-market-plugin#5](https://github.com/Sanqi-normal/dsh-webui-market-plugin/issues/5)
66
+ - [1na-ko/dsh-hdc-bridge#3](https://github.com/1na-ko/dsh-hdc-bridge/issues/3)
67
+ - [6Mikao9/dsh-wsl-workspace#6](https://github.com/6Mikao9/dsh-wsl-workspace/issues/6)
68
+ - [3274375092/dsh-voice#2](https://github.com/3274375092/dsh-voice/issues/2)
69
+
70
+ ## 检查一个插件
71
+
72
+ ```bash
73
+ npx --yes upstream-radar@0.42.0 review dsh-plugin \
74
+ <包名>@<版本> \
75
+ --dsh-version <DSH版本>
76
+ ```
77
+
78
+ 需要执行插件代码时,请使用仓库维护的
79
+ [隔离观察工作流](.github/workflows/observe-dsh-plugin-install.yml):每个组合都会获得
80
+ 一台全新的、无密钥的 GitHub 托管虚拟机和受限容器。
81
+
82
+ 你还可以查看[实时兼容性矩阵](examples/dsh/install-observer/README.md)、
83
+ [可供目录消费的兼容性结果](feeds/dsh-plugin-compatibility.md)、
84
+ [第一批 50 个插件](examples/dsh/first-batch/README.md)和
85
+ [架构说明](docs/architecture.md)。
86
+
87
+ <p align="center">
88
+ <strong>如果 Upstream Radar 对 DSH 生态有帮助,欢迎<a href="https://github.com/MicroMilo/upstream-radar">点一个 Star</a> ⭐</strong>
89
+ </p>
package/dist/src/cli.js CHANGED
@@ -477,7 +477,7 @@ Usage:
477
477
  upstream-radar profile-check [profile-directory] [--patch <path>] [--report <path>] [--summary] [--json]
478
478
  upstream-radar probe dsh-load <package.tgz> [--dsh-version <exact-version>] [--timeout <seconds>] [--keep-profile] [--json]
479
479
  upstream-radar probe dsh-matrix <package.tgz> --dsh-version <v1>[,<v2>,...] [--timeout <seconds>] [--keep-profile] [--json]
480
- upstream-radar probe dsh-install [npm:]<package>@<exact-version> --dsh-version <exact-version> --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
480
+ upstream-radar probe dsh-install [npm:]<package>@<exact-version> --dsh-version <exact-version> [--case-id <stable-label>] --isolation-provider <github-actions-hosted-runner|firecracker|other> --execute [--allow-build <package>]... [--timeout <seconds>] [--report <report.json>] [--json]
481
481
  upstream-radar review dsh-plugin [npm:]<package>@<exact-version> --dsh-version <v1>,<v2>,... [--json]
482
482
  upstream-radar demo [--json]
483
483
  upstream-radar case dsh-web-ui [--json]
@@ -1284,6 +1284,7 @@ async function runDshInstallObservation(args) {
1284
1284
  throw new Error('probe dsh-install requires an exact npm package');
1285
1285
  }
1286
1286
  let dshVersion;
1287
+ let caseId;
1287
1288
  let isolationProvider;
1288
1289
  let timeoutSeconds = 180;
1289
1290
  let reportPath;
@@ -1298,7 +1299,7 @@ async function runDshInstallObservation(args) {
1298
1299
  else if (argument === '--json') {
1299
1300
  json = true;
1300
1301
  }
1301
- else if (argument === '--dsh-version' || argument === '--isolation-provider' || argument === '--allow-build' || argument === '--timeout' || argument === '--report') {
1302
+ else if (argument === '--dsh-version' || argument === '--case-id' || argument === '--isolation-provider' || argument === '--allow-build' || argument === '--timeout' || argument === '--report') {
1302
1303
  const value = args[index + 1];
1303
1304
  if (value === undefined || value.startsWith('-'))
1304
1305
  throw new Error(`${argument} requires a value`);
@@ -1307,6 +1308,13 @@ async function runDshInstallObservation(args) {
1307
1308
  throw new Error('probe dsh-install accepts only one --dsh-version');
1308
1309
  dshVersion = value;
1309
1310
  }
1311
+ else if (argument === '--case-id') {
1312
+ if (caseId !== undefined)
1313
+ throw new Error('probe dsh-install accepts only one --case-id');
1314
+ if (!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(value))
1315
+ throw new Error('--case-id must be a short lowercase label');
1316
+ caseId = value;
1317
+ }
1310
1318
  else if (argument === '--isolation-provider') {
1311
1319
  if (value !== 'github-actions-hosted-runner' && value !== 'firecracker' && value !== 'other') {
1312
1320
  throw new Error('--isolation-provider must be github-actions-hosted-runner, firecracker or other');
@@ -1344,6 +1352,7 @@ async function runDshInstallObservation(args) {
1344
1352
  const report = await observeDshPluginInstall({
1345
1353
  packageSpec,
1346
1354
  dshVersion,
1355
+ ...(caseId === undefined ? {} : { caseId }),
1347
1356
  allowExecution: true,
1348
1357
  isolationProvider,
1349
1358
  allowedBuilds,