dsh-plugin-toolkit 0.13.2 → 0.13.3

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 CHANGED
@@ -1,3 +1,14 @@
1
+ ## 0.13.3
2
+
3
+ - **`verify` no longer fails a correct plugin.** The check that calls a client
4
+ module's `apply()` before its services exist handed it `{}`, so
5
+ `ctx.inject(...)` — the cordis API every plugin uses — threw
6
+ `ctx.inject is not a function` and the plugin was reported as broken. The
7
+ probe now models a real context: `inject`, `on`, `effect`, `logger`, `get`,
8
+ `set` and `provide` exist; only the services are absent.
9
+ - Found by this repository's own example plugin, whose CI went red on the
10
+ previous release. That is the whole point of the example.
11
+
1
12
  ## 0.13.2
2
13
 
3
14
  - **A table of the four ways a plugin installs and still does nothing** — red
package/lib/verify.mjs CHANGED
@@ -39,8 +39,37 @@ function packTarball(dir, destination) {
39
39
  * What cordis hands a plugin that declares no `inject`: every undeclared
40
40
  * property read throws. A plain `{}` hides the bug this is looking for.
41
41
  */
42
+ // cordis itself is present on every context — `ctx.inject`, `ctx.on`,
43
+ // `ctx.effect` and the logger. What can be absent is the *services*.
44
+ function cordisApi() {
45
+ const noop = () => () => {};
46
+ const base = {
47
+ inject: (list, callback) => {
48
+ // A declared service may still be absent when apply runs: record nothing,
49
+ // call nothing. That is exactly what the host does before a service mounts.
50
+ void list;
51
+ void callback;
52
+ return () => {};
53
+ },
54
+ on: noop,
55
+ effect: noop,
56
+ logger: () => {},
57
+ get: () => undefined,
58
+ set: () => {},
59
+ provide: noop,
60
+ reflect: { get: () => undefined, set: () => {}, provide: noop },
61
+ };
62
+ return base;
63
+ }
64
+
65
+ /** A context whose services have not mounted yet; reading one gives undefined. */
66
+ function absentContext() {
67
+ return cordisApi();
68
+ }
69
+
70
+ /** A context that also enforces cordis's rule: an undeclared read throws. */
42
71
  function undeclaredContext() {
43
- const base = { inject: undefined };
72
+ const base = cordisApi();
44
73
  return new Proxy(base, {
45
74
  get(target, key) {
46
75
  if (key in target) return target[key];
@@ -212,7 +241,7 @@ export async function verify({ dir, mount = true }) {
212
241
  faceProblems.push('the client module declares no inject list, so the loader calls apply() before its services exist');
213
242
  }
214
243
  try {
215
- face.apply({});
244
+ face.apply(absentContext());
216
245
  } catch (error) {
217
246
  faceProblems.push(`apply() throws when the services are absent, which fails the web boot: ${error.message}`);
218
247
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-toolkit",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "Preflight, release and test DeepSeek Harness plugins: check a folder or any GitHub repository, wait for npm to actually serve the version, and keep the market index honest.",
5
5
  "type": "module",
6
6
  "bin": {