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.
- package/README.md +72 -241
- package/README.zh-CN.md +89 -0
- package/dist/src/cli.js +11 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/dsh-compatibility-ir.d.ts +99 -0
- package/dist/src/dsh-compatibility-ir.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-ir.js +408 -0
- package/dist/src/dsh-compatibility-ir.js.map +1 -0
- package/dist/src/dsh-compatibility-issues.d.ts +46 -0
- package/dist/src/dsh-compatibility-issues.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-issues.js +223 -0
- package/dist/src/dsh-compatibility-issues.js.map +1 -0
- package/dist/src/dsh-compatibility-ledger.d.ts +152 -0
- package/dist/src/dsh-compatibility-ledger.d.ts.map +1 -0
- package/dist/src/dsh-compatibility-ledger.js +678 -0
- package/dist/src/dsh-compatibility-ledger.js.map +1 -0
- package/dist/src/dsh-directory-feed.d.ts +108 -0
- package/dist/src/dsh-directory-feed.d.ts.map +1 -0
- package/dist/src/dsh-directory-feed.js +267 -0
- package/dist/src/dsh-directory-feed.js.map +1 -0
- package/dist/src/dsh-install-observation.d.ts +89 -1
- package/dist/src/dsh-install-observation.d.ts.map +1 -1
- package/dist/src/dsh-install-observation.js +658 -19
- package/dist/src/dsh-install-observation.js.map +1 -1
- package/dist/src/dsh-install-plan.d.ts +16 -6
- package/dist/src/dsh-install-plan.d.ts.map +1 -1
- package/dist/src/dsh-install-plan.js +273 -47
- package/dist/src/dsh-install-plan.js.map +1 -1
- package/dist/src/dsh-plugin.d.ts.map +1 -1
- package/dist/src/dsh-plugin.js +6 -2
- package/dist/src/dsh-plugin.js.map +1 -1
- package/dist/src/dsh-runtime.d.ts +6 -0
- package/dist/src/dsh-runtime.d.ts.map +1 -1
- package/dist/src/dsh-runtime.js +38 -0
- package/dist/src/dsh-runtime.js.map +1 -1
- package/dist/src/index.d.ts +8 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/installed-graph.d.ts.map +1 -1
- package/dist/src/installed-graph.js +105 -26
- package/dist/src/installed-graph.js.map +1 -1
- package/dist/src/radar-types.d.ts +15 -0
- package/dist/src/radar-types.d.ts.map +1 -1
- package/dist/src/semver.d.ts.map +1 -1
- package/dist/src/semver.js +7 -1
- package/dist/src/semver.js.map +1 -1
- package/dist/src/tar.d.ts.map +1 -1
- package/dist/src/tar.js +28 -13
- package/dist/src/tar.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/docs/README.zh-CN.md +25 -23
- package/package.json +3 -1
- package/schemas/dsh-compatibility-ir.schema.json +96 -0
- package/schemas/dsh-install-observation.schema.json +141 -2
package/README.md
CHANGED
|
@@ -1,266 +1,97 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Upstream Radar</h1>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://www.npmjs.com/package/upstream-radar)
|
|
5
|
-
[](LICENSE)
|
|
3
|
+
<p align="center"><strong>Know which DeepSeek Harness plugins break after every release—before users do.</strong></p>
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
English · <a href="README.zh-CN.md">简体中文</a>
|
|
7
|
+
</p>
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
22
|
+
**100 maintained install/load targets · 100 catalog entries across all 21 categories · 4 upstream reports closed**
|
|
19
23
|
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
38
|
+
## The loop
|
|
79
39
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
+
## Upstream reports now closed
|
|
226
68
|
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
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>
|
package/README.zh-CN.md
ADDED
|
@@ -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,
|