dsh-plugin-toolkit 0.9.0 → 0.9.1
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/CHANGELOG.md +10 -0
- package/README.md +4 -0
- package/lib/audit.mjs +27 -5
- package/lib/dev.mjs +3 -1
- package/lib/doctor.mjs +12 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 0.9.1
|
|
2
|
+
|
|
3
|
+
- `audit` separates problems from advisories. Running 0.9.0 on a real profile
|
|
4
|
+
said "17 of 19 installed plugin(s) have problems" — 13 of those load fine and
|
|
5
|
+
only lack `engines.dsh` or a README Requirements section, which the market index
|
|
6
|
+
needs and the loader does not. Those are now counted separately, so the plugins
|
|
7
|
+
that are actually broken stay visible.
|
|
8
|
+
- `client entry` and `dev` resolve a `./client` export written as a conditions
|
|
9
|
+
object (`{ default: './lib/client.cjs' }`), not only as a string.
|
|
10
|
+
|
|
1
11
|
## 0.9.0
|
|
2
12
|
|
|
3
13
|
- `audit`: every plugin installed in a profile, in one pass — version, whether the
|
package/README.md
CHANGED
|
@@ -212,6 +212,10 @@ demo-panel 0.3.0 not loaded 1 problem: root export
|
|
|
212
212
|
1 installed plugin(s) are not in the running app; restart the app once after installing.
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
Advisories (`engines.dsh`, README Requirements) are counted apart from problems:
|
|
216
|
+
the market index needs them, the loader does not, so they should not bury a plugin
|
|
217
|
+
that is actually broken.
|
|
218
|
+
|
|
215
219
|
Without `--host` the loaded column is `?`, because guessing would be worse than
|
|
216
220
|
saying nothing. Only packages that declare a `dsh` field are audited — the rest of
|
|
217
221
|
`node_modules` is ordinary dependencies, and auditing those is noise.
|
package/lib/audit.mjs
CHANGED
|
@@ -48,9 +48,26 @@ export function listInstalled({ home = path.join(os.homedir(), '.dsh') } = {}) {
|
|
|
48
48
|
return found;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
/**
|
|
52
|
+
* `engines.dsh` and the README Requirements section are what the market index
|
|
53
|
+
* needs. The loader does not read either, so a plugin without them still loads —
|
|
54
|
+
* calling that "a problem" would bury the plugins that are actually broken.
|
|
55
|
+
*/
|
|
56
|
+
const ADVISORY = new Set(['engines.dsh', 'readme']);
|
|
57
|
+
|
|
58
|
+
function split(failures) {
|
|
59
|
+
return {
|
|
60
|
+
hard: failures.filter((failure) => ADVISORY.has(failure.check) === false),
|
|
61
|
+
advisory: failures.filter((failure) => ADVISORY.has(failure.check) === true),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function describe({ hard, advisory }) {
|
|
66
|
+
if (hard.length === 0 && advisory.length === 0) return 'ok';
|
|
67
|
+
const parts = [];
|
|
68
|
+
if (hard.length > 0) parts.push(`${hard.length} problem${hard.length === 1 ? '' : 's'}: ${hard[0].check}`);
|
|
69
|
+
if (advisory.length > 0) parts.push(`${advisory.length} advisor${advisory.length === 1 ? 'y' : 'ies'}`);
|
|
70
|
+
return parts.join(', ');
|
|
54
71
|
}
|
|
55
72
|
|
|
56
73
|
export async function audit({ home, host, io = console, fetchImpl, timeoutMs = 3000 } = {}) {
|
|
@@ -74,7 +91,7 @@ export async function audit({ home, host, io = console, fetchImpl, timeoutMs = 3
|
|
|
74
91
|
failures = [{ check: 'manifest', message: error.message }];
|
|
75
92
|
}
|
|
76
93
|
const loaded = graph?.ok === true ? graph.ids.has(manifest.name) : null;
|
|
77
|
-
return { name: manifest.name, version: manifest.version ?? '?', profile, dir, failures, loaded };
|
|
94
|
+
return { name: manifest.name, version: manifest.version ?? '?', profile, dir, failures, ...split(failures), loaded };
|
|
78
95
|
});
|
|
79
96
|
|
|
80
97
|
const width = Math.max(...rows.map((row) => row.name.length), 6);
|
|
@@ -84,12 +101,17 @@ export async function audit({ home, host, io = console, fetchImpl, timeoutMs = 3
|
|
|
84
101
|
for (const failure of row.failures) io.log(`${' '.repeat(width + 22)}${failure.check}: ${failure.message}`);
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
const failed = rows.filter((row) => row.
|
|
104
|
+
const failed = rows.filter((row) => row.hard.length > 0);
|
|
105
|
+
const advised = rows.filter((row) => row.hard.length === 0 && row.advisory.length > 0);
|
|
88
106
|
const notLoaded = rows.filter((row) => row.loaded === false);
|
|
89
107
|
if (notLoaded.length > 0) {
|
|
90
108
|
io.log('');
|
|
91
109
|
io.log(`${notLoaded.length} installed plugin(s) are not in the running app; restart the app once after installing.`);
|
|
92
110
|
}
|
|
111
|
+
if (advised.length > 0) {
|
|
112
|
+
io.log('');
|
|
113
|
+
io.log(`${advised.length} plugin(s) load but are not ready for the market index (engines.dsh, README Requirements).`);
|
|
114
|
+
}
|
|
93
115
|
if (failed.length > 0) {
|
|
94
116
|
io.log('');
|
|
95
117
|
io.log(`${failed.length} of ${rows.length} installed plugin(s) have problems.`);
|
package/lib/dev.mjs
CHANGED
|
@@ -12,12 +12,14 @@ import os from 'node:os';
|
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { spawnSync } from 'node:child_process';
|
|
14
14
|
|
|
15
|
+
import { exportTarget } from './doctor.mjs';
|
|
16
|
+
|
|
15
17
|
const IGNORED = new Set(['node_modules', '.git', 'docs', 'test', 'tests', 'coverage', 'fixtures']);
|
|
16
18
|
|
|
17
19
|
export function resolveEntry(dir, manifest) {
|
|
18
20
|
const declared = manifest?.dsh?.client?.entry;
|
|
19
21
|
const exported = manifest?.exports;
|
|
20
|
-
const subpath = typeof exported === 'string' ? undefined : exported?.['./client'];
|
|
22
|
+
const subpath = typeof exported === 'string' ? undefined : exportTarget(exported?.['./client']);
|
|
21
23
|
const candidates = [declared, subpath, 'client.js', 'lib/client.js', 'dist/client.js'].filter((value) => typeof value === 'string');
|
|
22
24
|
for (const candidate of candidates) {
|
|
23
25
|
const absolute = path.resolve(dir, candidate);
|
package/lib/doctor.mjs
CHANGED
|
@@ -84,6 +84,17 @@ export function checkPatchFile(dir, manifest) {
|
|
|
84
84
|
return `dsh.bundle.patch points at ${bundle.patch}, which does not exist`;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/** `exports['./client']` is a string in some packages and a conditions object in others. */
|
|
88
|
+
export function exportTarget(value) {
|
|
89
|
+
if (typeof value === 'string') return value;
|
|
90
|
+
if (value !== null && typeof value === 'object') {
|
|
91
|
+
for (const key of ['default', 'import', 'require']) {
|
|
92
|
+
if (typeof value[key] === 'string') return value[key];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
87
98
|
export function checkClientEntry(dir, manifest) {
|
|
88
99
|
const client = manifest.dsh?.client;
|
|
89
100
|
if (client === undefined || client === null) return null;
|
|
@@ -91,7 +102,7 @@ export function checkClientEntry(dir, manifest) {
|
|
|
91
102
|
// with a `dsh/` folder names its bundle), then the plain file names. A plugin
|
|
92
103
|
// that ships `dsh/client.js` is not wrong for failing to also ship `client.js`.
|
|
93
104
|
const exported = manifest.exports;
|
|
94
|
-
const subpath = typeof exported === 'string' ? undefined : exported?.['./client'];
|
|
105
|
+
const subpath = typeof exported === 'string' ? undefined : exportTarget(exported?.['./client']);
|
|
95
106
|
const entries = [client.entry, subpath, 'client.js', 'lib/client.js', 'dist/client.js']
|
|
96
107
|
.filter((entry) => typeof entry === 'string' && entry.length > 0)
|
|
97
108
|
.map((entry) => entry.replace(/^\.\//u, ''));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-toolkit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Preflight, release and test DeepSeek Harness plugins: checks what the host needs, waits for npm to actually serve the version, and keeps the market index honest.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|