dsh-plugin-guide 0.4.3 → 0.4.5
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.en.md +370 -0
- package/README.es.md +370 -0
- package/README.hi.md +370 -0
- package/README.md +334 -52
- package/README.pt.md +370 -0
- package/docs/assets/dsh-plugin-guide-flow-dark.svg +35 -0
- package/docs/assets/dsh-plugin-guide-flow-light.svg +35 -0
- package/docs/boost.md +59 -29
- package/docs/entry.md +195 -0
- package/docs/flow.md +149 -9
- package/docs/levels.md +23 -3
- package/docs/recipes.md +251 -0
- package/docs/rules.md +99 -0
- package/package.json +1 -1
- package/README-zh.md +0 -82
package/docs/recipes.md
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Recipes: copy these, then re-run the checker
|
|
2
|
+
|
|
3
|
+
<a id="before-you-copy"></a>
|
|
4
|
+
## Before you copy
|
|
5
|
+
|
|
6
|
+
Every block below was run against `dsh-standards` `40-checker` (`0.1.0`,
|
|
7
|
+
anchor `ce7073d51254`, default runtime `0.2.2-alpha.2`). The package name
|
|
8
|
+
`@acme/dsh-hello` is a placeholder — replace it everywhere, including the patch
|
|
9
|
+
row. The numbers in the verify sections are what the checker printed here; if
|
|
10
|
+
your output differs, the diff line is your fix.
|
|
11
|
+
|
|
12
|
+
<a id="minimal-packagejson"></a>
|
|
13
|
+
## Minimal `package.json`
|
|
14
|
+
|
|
15
|
+
A plugin that exports `apply`, registers one tool, and can also be composed as
|
|
16
|
+
a bundle row.
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"name": "@acme/dsh-hello",
|
|
21
|
+
"version": "0.1.0",
|
|
22
|
+
"description": "Minimal DSH plugin that registers one tool.",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./index.js",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./index.js"
|
|
28
|
+
},
|
|
29
|
+
"files": ["index.js", "cordis.patch.yml"],
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=24.9.0",
|
|
32
|
+
"dsh": ">=0.2.2-0 <0.3.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@deepseek-ai/dsh": ">=0.2.2-0 <0.3.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependenciesMeta": {
|
|
38
|
+
"@deepseek-ai/dsh": { "optional": true }
|
|
39
|
+
},
|
|
40
|
+
"dsh": {
|
|
41
|
+
"manifestVersion": 1,
|
|
42
|
+
"kind": "plugin",
|
|
43
|
+
"bundle": { "patch": "./cordis.patch.yml" },
|
|
44
|
+
"capabilities": ["tools:register"],
|
|
45
|
+
"labels": []
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Field | What it buys | Check |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `name` + exact `version` | a resolvable identity; a range or tag here is a FAIL | `C-1.1` |
|
|
53
|
+
| `exports["."]` (or `main`) | the entry must resolve to a file inside the package | `C-1.2` |
|
|
54
|
+
| `files` including the entry and patch | not checked, but `npm pack` can otherwise ship a manifest whose entry is absent | — |
|
|
55
|
+
| `engines.dsh` | the only declaration that decides compatibility alone; `workspace:` is a FAIL | `C-2.1`/`C-2.3` |
|
|
56
|
+
| `license` | avoids the `C-1.5` WARN; SPDX string | `C-1.5` |
|
|
57
|
+
| `dsh.bundle.patch` | the file a bundle layer composes; in-package relative path | `C-1.4` |
|
|
58
|
+
| `dsh.capabilities` | declares the host surfaces you touch; closed set of 15 | `C-11.1` |
|
|
59
|
+
| `dsh.labels` | declares high-risk categories; closed set of 5; `[]` is allowed | `C-13.1` |
|
|
60
|
+
| `dsh.kind` | `plugin` gets L1; `bundle` gets G0–G3; a client is static-only | `DSC-14` |
|
|
61
|
+
|
|
62
|
+
Notes that come from the checker, not taste:
|
|
63
|
+
|
|
64
|
+
- `dsh.capabilities` and `dsh.labels` are **standard extensions**: this host
|
|
65
|
+
does not read them. They are declarations, not enforcement. Declaring them
|
|
66
|
+
does not make the plugin safe, and omitting them is a WARN today.
|
|
67
|
+
- `dsh.manifestVersion`, `dsh.bundle`, `dsh.client` are host fields; keep
|
|
68
|
+
`manifestVersion: 1`.
|
|
69
|
+
- `engines.node` is **not** checked by the checker. Keep it for humans, but do
|
|
70
|
+
not expect a check to fail without it.
|
|
71
|
+
|
|
72
|
+
<a id="entry-module"></a>
|
|
73
|
+
## The entry module
|
|
74
|
+
|
|
75
|
+
`C-1.2` resolves the entry, so the file must exist. `DSC-10` and `DSC-06` both
|
|
76
|
+
look at what runs when and how it is cleaned up.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
export const name = 'dsh-hello'
|
|
80
|
+
export const inject = []
|
|
81
|
+
|
|
82
|
+
export function apply(ctx) {
|
|
83
|
+
ctx.effect(() => {
|
|
84
|
+
const timer = setInterval(() => {}, 60_000)
|
|
85
|
+
return () => clearInterval(timer)
|
|
86
|
+
}, 'dsh-hello.timer')
|
|
87
|
+
|
|
88
|
+
ctx.tools.register({
|
|
89
|
+
name: 'hello',
|
|
90
|
+
description: 'Say hello.',
|
|
91
|
+
async run() {
|
|
92
|
+
return 'hello'
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- `inject` lists only services you read; the runner stubs them for L1.
|
|
99
|
+
- `ctx.effect(fn, 'label')` gives the disposer a label, so `dispose()` can go
|
|
100
|
+
back to zero (`C-6.2`, `C-7.1`).
|
|
101
|
+
- `ctx.tools.register(...)` is the static trigger that requires
|
|
102
|
+
`capabilities: ["tools:register"]`.
|
|
103
|
+
|
|
104
|
+
<a id="cordispatchyml-insert"></a>
|
|
105
|
+
## `cordis.patch.yml`: the insert row
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
- insert:
|
|
109
|
+
- id: dsh-hello
|
|
110
|
+
name: '@acme/dsh-hello'
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Rules the checker and the host care about:
|
|
114
|
+
|
|
115
|
+
- `id` is the stable row identifier later layers use to override this row. Keep
|
|
116
|
+
it short and unique.
|
|
117
|
+
- `name` is the module the loader imports. For the **package-root row** it must
|
|
118
|
+
be the package name exactly (`@acme/dsh-hello`), because G4 looks for a
|
|
119
|
+
composed row whose `name` equals `manifest.name`. An `id` alone is not a row.
|
|
120
|
+
- An insert is required. An `override`-only patch adds nothing to the profile;
|
|
121
|
+
the plugin is never loaded (G1 reports no target rows, G3 reports no active
|
|
122
|
+
rows).
|
|
123
|
+
- The patch file stays inside the package and uses a relative path; `..`,
|
|
124
|
+
absolute paths, `~`, and `$VAR` are rejected (`C-1.4`).
|
|
125
|
+
- Do not enable `@deepseek-ai/dsh-plugin-manager/tools` in a patch unless you
|
|
126
|
+
mean to hand every session the ability to install code (`C-11.3`).
|
|
127
|
+
- G0 parses, G1 composes rows, G2 runs the compatibility gate, G3 boots the
|
|
128
|
+
target rows. Only G3 `verified` is a start; a `partial` result is
|
|
129
|
+
`ERROR`/`not-run`, not a pass.
|
|
130
|
+
|
|
131
|
+
<a id="client-entry-and-root-row"></a>
|
|
132
|
+
## Client entry and the package-root row
|
|
133
|
+
|
|
134
|
+
A client is a dual-face package: a server/`dsh` half that is loaded as a row,
|
|
135
|
+
and a prebuilt browser bundle at `exports["./client"]`.
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"name": "@acme/dsh-panel",
|
|
140
|
+
"version": "0.1.0",
|
|
141
|
+
"license": "MIT",
|
|
142
|
+
"type": "module",
|
|
143
|
+
"exports": {
|
|
144
|
+
".": "./index.js",
|
|
145
|
+
"./client": "./lib/client.js"
|
|
146
|
+
},
|
|
147
|
+
"files": ["index.js", "lib", "cordis.patch.yml"],
|
|
148
|
+
"engines": { "dsh": ">=0.2.2-0 <0.3.0" },
|
|
149
|
+
"dsh": {
|
|
150
|
+
"manifestVersion": 1,
|
|
151
|
+
"kind": "client",
|
|
152
|
+
"client": { "platform": "web" },
|
|
153
|
+
"bundle": { "patch": "./cordis.patch.yml" },
|
|
154
|
+
"capabilities": [],
|
|
155
|
+
"labels": []
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
# cordis.patch.yml — the same package name as the manifest
|
|
162
|
+
- insert:
|
|
163
|
+
- id: dsh-panel
|
|
164
|
+
name: '@acme/dsh-panel'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The server half only has to load as a row; the browser half is the built file:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
// index.js — the server half; lib/client.js is the browser half
|
|
171
|
+
export const name = 'dsh-panel'
|
|
172
|
+
export const inject = []
|
|
173
|
+
|
|
174
|
+
export function apply() {}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
What each piece is for:
|
|
178
|
+
|
|
179
|
+
| Piece | Why it is required | Where it shows up |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `dsh.client` (non-empty) | marks the package as having a browser face | `G4`, `C-1` |
|
|
182
|
+
| `dsh.client.platform` | the host selects the Web consumer with `"web"`; the checker only requires `dsh.client` to be non-empty | host manifest type |
|
|
183
|
+
| `exports["./client"]` | a string path, or an object with a string `default`; must point at a **built** file (the checker only fails when it is absent) | `G4` → `DSC-01` FAIL if missing |
|
|
184
|
+
| root row (`name` = package name) | the client scanner reads the loader's rows; no active row means the bundle is never discovered | `G4` in the bundle smoke |
|
|
185
|
+
| `dsh.client.inject` | informational package names, not Cordis injection | host only |
|
|
186
|
+
| `dsh.client.external` | extra module-table requests; omit unless you need them | host build |
|
|
187
|
+
|
|
188
|
+
`"capabilities": []` says the server half touches no host surface. The checker
|
|
189
|
+
still WARNs (`C-11.1: dsh.capabilities is empty`) and the report's reason line
|
|
190
|
+
says `advisory: DSC-11`; in ENTRY that WARN is advisory, so the status stays
|
|
191
|
+
`pass`. If the server half does touch something, fill the array from the trigger
|
|
192
|
+
table in [entry.md](entry.md#capability-triggers) — an empty array is not a
|
|
193
|
+
substitute for the capabilities you actually use.
|
|
194
|
+
|
|
195
|
+
Two failure shapes you will see, and how to tell them apart:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
G4: FAIL dsh.client exists but exports["./client"] is missing; a package-root row cannot resolve it
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The message names both causes. Add `exports["./client"]` first; if the export
|
|
202
|
+
already exists, the bundle smoke is telling you the composed root row is
|
|
203
|
+
missing — check that the patch `name` equals `manifest.name` and that the row is
|
|
204
|
+
`insert`ed.
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
DSC-14 FAIL C-14 L1 G4 failed: dsh.client has no package-root row or missing client export
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
That is the same condition on a runtime claim. Without `--host`, a client is
|
|
211
|
+
`DSH-ENTRY recognized` at best, and `DSC-14` is `NA`: build-only is not runtime.
|
|
212
|
+
|
|
213
|
+
<a id="verify"></a>
|
|
214
|
+
## Verify what you copied
|
|
215
|
+
|
|
216
|
+
```sh
|
|
217
|
+
# recognition only (no runtime claim): expect status=pass, exit=0
|
|
218
|
+
npx dsh-standards . --scope entry --entry-claim static
|
|
219
|
+
|
|
220
|
+
# plugin runtime: expect DSC-14 PASS and level "DSH-ENTRY runtime"
|
|
221
|
+
npx dsh-standards . --scope entry \
|
|
222
|
+
--runtime /path/to/cordis/lib/index.js
|
|
223
|
+
|
|
224
|
+
# bundle: expect "G0-G3 verified; rows=1/1"
|
|
225
|
+
npx dsh-standards . --scope entry \
|
|
226
|
+
--host /path/to/@deepseek-ai/dsh-app-boot/lib/index.js
|
|
227
|
+
|
|
228
|
+
# machine-readable: read .conclusion.level and .g4
|
|
229
|
+
npx dsh-standards . --format json
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
For the plugin recipe above, the static run prints:
|
|
233
|
+
|
|
234
|
+
```text
|
|
235
|
+
DSC-01 PASS C-1 L0
|
|
236
|
+
DSC-02 PASS C-2 L0
|
|
237
|
+
DSC-11 PASS C-11 L0
|
|
238
|
+
DSC-12 PASS C-12 L0
|
|
239
|
+
DSC-13 PASS C-13 L0
|
|
240
|
+
level: DSH-ENTRY recognized
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
For the client recipe, the same run ends `status=pass`, prints
|
|
244
|
+
`level: DSH-ENTRY recognized`, and still shows
|
|
245
|
+
`C-11.1: dsh.capabilities is empty` with `reason: advisory: DSC-11`. That is the
|
|
246
|
+
transitional empty-array WARN, not a G4 failure. A `kind: client` package is
|
|
247
|
+
static-only: `DSC-14` is `NA`, so `--host` cannot turn it into
|
|
248
|
+
`DSH-ENTRY runtime`. Only a package installed as a bundle (`kind: bundle`)
|
|
249
|
+
reaches runtime through G0–G3, and its G4 needs both the client export and the
|
|
250
|
+
root row. If `G4` fails you get `exit=1` and no level — add the missing export
|
|
251
|
+
or row, do not reword the report.
|
package/docs/rules.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Rules: decode a check report in one table
|
|
2
|
+
|
|
3
|
+
<a id="how-to-read"></a>
|
|
4
|
+
## How to read one report line
|
|
5
|
+
|
|
6
|
+
A DS-C report has one line per check: `id`, `result`, `clause`, `layer`,
|
|
7
|
+
`reason`. The detail lines under it (`C-1.2`, `C-11.5`, `G4`) are what you
|
|
8
|
+
actually fix.
|
|
9
|
+
|
|
10
|
+
| Result | Meaning | What it does to the verdict |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `PASS` | the check ran and found nothing | counts as pass |
|
|
13
|
+
| `WARN` | ran, found something worth fixing | does not fail the run; `status` becomes `warn` (advisory checks excepted) |
|
|
14
|
+
| `FAIL` | ran, found an attributable defect | `status=fail`, exit `1` |
|
|
15
|
+
| `NA` | the check does not apply (wrong `dsh.kind`, no field, package profile) | allowed; not a pass |
|
|
16
|
+
| `ERROR` | the check could not run (`coverage: not-run`, e.g. no `--runtime`/`--host`) | `status=incomplete`, exit `2` |
|
|
17
|
+
|
|
18
|
+
Exit codes: `0` completed (pass or warn), `1` attributable FAIL, `2`
|
|
19
|
+
incomplete/not-run, `3` usage error. `WARN` is not a clean pass and
|
|
20
|
+
`incomplete` is not a pass — both are printed as such on purpose.
|
|
21
|
+
|
|
22
|
+
The JSON report also carries a sibling `advice[]` array: one entry per live
|
|
23
|
+
detail, with `title`, `why`, `fix`, `docsUrl`, `severity`, and `evidence`. It is
|
|
24
|
+
additive and never changes the verdict (turn it off with `--no-advice`). The
|
|
25
|
+
`docsUrl` follows the checker's `DOCS_BASE` (currently `v0.4.4`); if it points
|
|
26
|
+
at an older page, this table is the current mapping.
|
|
27
|
+
|
|
28
|
+
<a id="scope-matrix"></a>
|
|
29
|
+
## Which checks run in which scope
|
|
30
|
+
|
|
31
|
+
| Scope / profile | Mandatory checks | Notes |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `--scope ds-c` (default), `package` | 01, 02, 04–09, 11, 12, 13 | 03 is `NA`, 10 is advisory, 14 is not run |
|
|
34
|
+
| `--scope ds-c`, `listing` | + 03 | install spec / market index are now judged |
|
|
35
|
+
| `--scope entry --entry-claim static` | 01, 02, 11, 12, 13 (+ 03 for listing) | 04–09 are attempted and printed (usually `ERROR`/`NA`), 14 is `NA`; a `DSC-11`/`DSC-12`/`DSC-13` FAIL is downgraded to `WARN` |
|
|
36
|
+
| `--scope entry --entry-claim runtime` | + 14 | 14 carries the runtime verdict, not 04–09 |
|
|
37
|
+
| `--scope mvp` | 01, 02, 04–09 | the MVP subset, labelled `MVP-13` |
|
|
38
|
+
|
|
39
|
+
<a id="table"></a>
|
|
40
|
+
## The check table
|
|
41
|
+
|
|
42
|
+
| Check | Clause | Blocking or advice | One-line fix | Guide |
|
|
43
|
+
|---|---|---|---|---|
|
|
44
|
+
| **DSC-01** | C-1 manifest + entry | Blocking (ds-c, entry). C-1.3/C-1.5/C-1.6 are WARN/NA. A `G4` detail is reported here. | Exact `name`/`version`, `exports["."]` or `main` resolving to a file inside the package, in-package `dsh.bundle.patch` paths, and a `license`. | [entry.md § package shape](entry.md#package-shape) · [recipes](recipes.md#minimal-packagejson) |
|
|
45
|
+
| **DSC-02** | C-2 version range | Blocking (ds-c). In ENTRY, a static claim downgrades the whole check to WARN; a runtime claim keeps `C-2.2`/`C-2.3` blocking. | Declare `engines.dsh` as a range that contains the host you target (`>=0.2.2-0 <0.3.0`); never publish `workspace:`. | [entry.md § package shape](entry.md#package-shape) |
|
|
46
|
+
| **DSC-03** | C-3 install source | Blocking (listing only); `NA` in package profile. | Pin the source: exact version or verifiable tag, `#<40-hex>` for git, an in-package path, and a `format:1` market entry with pinned versions. | [entry.md § package shape](entry.md#package-shape) |
|
|
47
|
+
| **DSC-04** | C-4 load to ACTIVE | Blocking (ds-c, when a runtime runs). | Make the entry import cleanly and reach `ACTIVE`: no throw at import, no module-scope work, declare `inject` or read `ctx.get()`, move work into `apply()`. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
48
|
+
| **DSC-05** | C-5 declared provide | Blocking (ds-c). | Every name in `export const provide` must be registered by this plugin's own fiber via `ctx.provide(name, impl)`. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
49
|
+
| **DSC-06** | C-6 effects | Blocking (ds-c); anonymous effects are WARN. | Wrap timers, watchers, sockets, and subprocesses in `ctx.effect(fn, 'label')`; never write `ctx.reflect.store` or `ctx.events._hooks`. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
50
|
+
| **DSC-07** | C-7 unload residue | Blocking (ds-c). | Return a disposer from every effect so `dispose()` leaves `getEffects()===0`, the service store at baseline, and `registry.size` unchanged. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
51
|
+
| **DSC-08** | C-8 restart idempotence | Blocking (ds-c). | Make `restart()` re-enter `ACTIVE`, keep the effect count, advance revision/epoch, and succeed from a fresh `Context`. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
52
|
+
| **DSC-09** | C-9 declared vs measured | Blocking (ds-c) for `C-9.1`; `C-9.2`/`C-9.3` are WARN. | Keep declarations equal to reality: provided ⊆ measured, measured ⊆ declared, and each declared `inject` is really read as `ctx.<service>`. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
53
|
+
| **DSC-10** | C-10 import-time work | Advice only; never changes the verdict. | Move module-scope `await`, timers, `process.on`, fs writes, and spawns into `apply()` and clean up with `ctx.effect()`. | [entry.md § import-time side effects](entry.md#import-time-side-effects) |
|
|
54
|
+
| **DSC-11** | C-11 capabilities | Blocking (ds-c); `WARN` in ENTRY, and a `WARN` here is advisory even in ds-c. | Declare `dsh.capabilities` from the closed set, add one entry per static trigger, and never enable `@deepseek-ai/dsh-plugin-manager/tools` in a patch. | [entry.md § capability triggers](entry.md#capability-triggers) |
|
|
55
|
+
| **DSC-12** | C-12 credentials + seams | Blocking (ds-c); `WARN` in ENTRY. | Read credentials through `ctx.credentials`, declare `credentials:list` for `listRecords()` and `credentials:provider` for a provider, and never read the backing file. | [entry.md § credentials and seams](entry.md#credentials-and-seams) |
|
|
56
|
+
| **DSC-13** | C-13 labels + mirror | Blocking (ds-c); `WARN` in ENTRY, advisory as a WARN. | Use only the five labels, add the label each capability requires, point `dsh.upstream` at an https URL that is not this package **and** add `mirror`, and drop endorsement words. | [entry.md § labels and mirror](entry.md#labels-and-mirror) |
|
|
57
|
+
| **DSC-14** | C-14 entry run | Blocking only for a runtime claim (`--scope entry`). | Supply the real host: `--host` for a bundle (G0–G3) or `--runtime` for a plugin (L1); a client or preset cannot claim runtime. | [entry.md § runtime surface](entry.md#runtime-surface) |
|
|
58
|
+
|
|
59
|
+
`DSC-14` has no `C-14` in the clause text; it is the ENTRY run-set gate
|
|
60
|
+
(`ENT-14` in 31-DSH-ENTRY). Treat it as "did the thing actually start".
|
|
61
|
+
|
|
62
|
+
<a id="warn"></a>
|
|
63
|
+
## Two things that look like passes but are not
|
|
64
|
+
|
|
65
|
+
**Advisory WARN.** `DSC-10` is always advisory. `DSC-11` and `DSC-13` become
|
|
66
|
+
advisory whenever the check itself returns `WARN`, because the host does not
|
|
67
|
+
read those fields yet. The effect is visible: this guide's own report prints
|
|
68
|
+
`DSC-11 WARN`, `DSC-13 WARN`, yet `coverage.warn=0` and
|
|
69
|
+
`reason: advisory: DSC-11, DSC-13`. Read the reason line, not only the coverage
|
|
70
|
+
counts. A `FAIL` that ENTRY downgrades to `WARN` is a plain WARN and does stay
|
|
71
|
+
in the counts.
|
|
72
|
+
|
|
73
|
+
**`incomplete`.** If a mandatory check has `coverage: not-run` (no runtime, no
|
|
74
|
+
host, a killed child, a partial AST parse), the status is `incomplete` and the
|
|
75
|
+
exit code is `2`. The report prints `NOT A DS-C PASS`. Do not paste a
|
|
76
|
+
`not-run` row into a README as a pass; write `not-run` or run the check.
|
|
77
|
+
|
|
78
|
+
<a id="not-checked"></a>
|
|
79
|
+
## What the checker does not check
|
|
80
|
+
|
|
81
|
+
These are good practice but **not** evidence of a pass, because no check reads
|
|
82
|
+
them:
|
|
83
|
+
|
|
84
|
+
- `engines.node` (the 24.9 line is a guide recommendation; `DSC-02` looks at
|
|
85
|
+
`engines.dsh` and `@deepseek-ai/dsh*` peers only)
|
|
86
|
+
- README install instructions, display metadata, keywords, `icon`
|
|
87
|
+
- endorsement words in prose, `description`, or README — `C-13.4` scans only
|
|
88
|
+
the `dsh.labels` array
|
|
89
|
+
- whether a `red-team` label was actually used for red-team work (`C-13.5`
|
|
90
|
+
only asks for `dsh.usageScope`)
|
|
91
|
+
- browser rendering of a client bundle (`G4` is a static shape check)
|
|
92
|
+
|
|
93
|
+
The checker's default `--runtime-version` is `0.2.2-alpha.2`. Pass
|
|
94
|
+
`--runtime-version <the host you target>` when that differs, or `DSC-02` will
|
|
95
|
+
judge your range against the wrong version.
|
|
96
|
+
|
|
97
|
+
If a report FAILs and you cannot find the ID here, open
|
|
98
|
+
[`docs/recipes.md`](recipes.md) for the copy-paste shape, then re-run the same
|
|
99
|
+
command and compare the detail lines.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-guide",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "A practical guide to DSH plugin quality: ENTRY checks, FLOW checks, and BOOST guidance. Community guide; not official, not a certification, not a ranking.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
package/README-zh.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
# dsh-plugin-guide
|
|
4
|
-
|
|
5
|
-
**DSH 插件质量指南:ENTRY、FLOW、BOOST。**
|
|
6
|
-
|
|
7
|
-
社区指南,不是官方标准、不是认证、不是排名。
|
|
8
|
-
|
|
9
|
-
[](https://www.npmjs.com/package/dsh-plugin-guide)
|
|
10
|
-
[](https://github.com/PerryLink/dsh-plugin-guide/actions/workflows/verify.yml)
|
|
11
|
-
[](LICENSE)
|
|
12
|
-
|
|
13
|
-
[English](README.md) · [简体中文](README-zh.md)
|
|
14
|
-
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 这是什么
|
|
20
|
-
|
|
21
|
-
`dsh-plugin-guide` 是 DSH 插件的**指南层**:解释要检查什么、为什么重要,以及
|
|
22
|
-
判定应该由哪个工具负责。它不做认证、不打分、不排名。
|
|
23
|
-
|
|
24
|
-
| 包 | 角色 |
|
|
25
|
-
|---|---|
|
|
26
|
-
| **`dsh-plugin-guide`** | 本包:文字指南、三层地图、agent skill |
|
|
27
|
-
| **`dsh-standards`** | 执行总包:ENTRY/FLOW 检查、三层审计、规范文件 |
|
|
28
|
-
| **`dsh-plugin-spec`** | 底层规则文本与条款来源 |
|
|
29
|
-
| **`dsh-primer`** | 旧的构建/脚手架技能和 CLI(原 `dsh-plugin-guide` 0.3.x) |
|
|
30
|
-
|
|
31
|
-
## 三层
|
|
32
|
-
|
|
33
|
-
| 层 | 回答 | 能否判定 |
|
|
34
|
-
|---|---|---|
|
|
35
|
-
| **ENTRY** | 能不能被识别、安装、启动 | 能:recognized / runtime / failed / incomplete / unavailable |
|
|
36
|
-
| **FLOW** | 用户能不能装、配、用、升级、卸载 | 有 runtime 证据时能;否则 `not-run` |
|
|
37
|
-
| **BOOST** | 有没有用好 Cordis | 不给插件级判定;按实践登记证据 |
|
|
38
|
-
|
|
39
|
-
三条轨道,不是三个等级;它们相加不等于分数或证书。
|
|
40
|
-
|
|
41
|
-
先读一页地图:[docs/levels.md](docs/levels.md)。
|
|
42
|
-
|
|
43
|
-
## 安装
|
|
44
|
-
|
|
45
|
-
```sh
|
|
46
|
-
dsh plugin --profile web add dsh-plugin-guide
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
然后在审查插件时让 agent 使用 `dsh-plugin-guide` 技能。它会将检查交给
|
|
50
|
-
`dsh-standards`,将构建/脚手架工作指向 `dsh-primer`。
|
|
51
|
-
|
|
52
|
-
## 检查插件
|
|
53
|
-
|
|
54
|
-
```sh
|
|
55
|
-
# 只做 ENTRY 识别(不声明 runtime)
|
|
56
|
-
npx dsh-standards ./my-plugin --scope entry --entry-claim static
|
|
57
|
-
|
|
58
|
-
# 三层审计;没跑的层保持 not-run / not-measured
|
|
59
|
-
npx -p dsh-standards dsh-levels ./my-plugin --format json
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
`recognized` 不是通过,`static` 不是通过,`not-run` 也不是通过。
|
|
63
|
-
|
|
64
|
-
## 0.4.0 改了什么
|
|
65
|
-
|
|
66
|
-
- 旧的 agent skill 和 `dsh-plugin-dev` CLI 已迁到
|
|
67
|
-
[`dsh-primer`](https://github.com/PerryLink/dsh-primer)。
|
|
68
|
-
- 本包现在是**指南层**:三层地图、检查路由、证据规则。
|
|
69
|
-
- 旧 0.3.x npm 版本已标记 deprecated,已有安装仍可用;0.4.0 是产品切换,
|
|
70
|
-
锁在 `^0.3` 的用户不会自动升级。
|
|
71
|
-
- 检查在 [`dsh-standards`](https://github.com/PerryLink/dsh-standards),不在本包。
|
|
72
|
-
|
|
73
|
-
## 边界
|
|
74
|
-
|
|
75
|
-
- 不做官方背书、认证、认可或安全审计。
|
|
76
|
-
- 不做评分、排名或市场门禁。
|
|
77
|
-
- 不伪造 runtime 证据:`static` ≠ `runtime`,`not-run` ≠ `pass`。
|
|
78
|
-
- BOOST 是建议和证据,不是插件等级。
|
|
79
|
-
|
|
80
|
-
## 许可
|
|
81
|
-
|
|
82
|
-
Apache-2.0。见 [LICENSE](LICENSE) 与 [NOTICE.md](NOTICE.md)。
|