@skill-map/testkit 0.2.0 → 0.3.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 (2) hide show
  1. package/README.md +121 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # `@skill-map/testkit`
2
+
3
+ Kernel mocks and builders for plugin authors. Unit-test detectors, rules, and formatters without spinning up a real kernel or DB.
4
+
5
+ The full plugin contract lives in [`spec/plugin-author-guide.md`](../spec/plugin-author-guide.md). This README is a fast on-ramp: how to ship the smallest viable plugin and validate it with the testkit.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install --save-dev @skill-map/testkit @skill-map/cli
11
+ ```
12
+
13
+ Pin both at exact versions — no `^` or `~`.
14
+
15
+ ## Minimum plugin shape
16
+
17
+ A plugin is a directory with one manifest and one extension file:
18
+
19
+ ```text
20
+ my-plugin/
21
+ ├── plugin.json
22
+ └── extensions/
23
+ └── my-detector.mjs
24
+ ```
25
+
26
+ `plugin.json`:
27
+
28
+ ```jsonc
29
+ {
30
+ "id": "my-plugin",
31
+ "version": "1.0.0",
32
+ "specCompat": "^1.0.0",
33
+ "extensions": ["./extensions/my-detector.mjs"]
34
+ }
35
+ ```
36
+
37
+ The directory name MUST equal `id`. Cross-root id collisions block both plugins.
38
+
39
+ `extensions/my-detector.mjs` — a detector that emits one `references` link per `[[ref:<name>]]` token in the body:
40
+
41
+ ```javascript
42
+ export default {
43
+ id: 'my-detector',
44
+ kind: 'detector',
45
+ version: '1.0.0',
46
+ emitsLinkKinds: ['references'],
47
+ defaultConfidence: 'medium',
48
+ scope: 'body',
49
+ detect(ctx) {
50
+ const out = [];
51
+ for (const m of ctx.body.matchAll(/\[\[ref:([a-z0-9-]+)\]\]/gi)) {
52
+ out.push({
53
+ source: ctx.node.path,
54
+ target: m[1].toLowerCase(),
55
+ kind: 'references',
56
+ confidence: 'medium',
57
+ sources: ['my-detector'],
58
+ trigger: { originalTrigger: m[0], normalizedTrigger: m[0].toLowerCase() },
59
+ });
60
+ }
61
+ return out;
62
+ },
63
+ };
64
+ ```
65
+
66
+ The extension's `id` is short (`my-detector`); the kernel composes the qualified id `my-plugin/my-detector` from the manifest. Pick a token syntax that does not collide with the built-in `@<token>` and `/<token>` detectors.
67
+
68
+ The four other extension kinds (`provider`, `rule`, `formatter`, `action`) follow the same shape — see [`spec/plugin-author-guide.md`](../spec/plugin-author-guide.md#the-five-extension-kinds).
69
+
70
+ ## Test it
71
+
72
+ ```javascript
73
+ // test/my-detector.test.mjs
74
+ import { test } from 'node:test';
75
+ import { strictEqual } from 'node:assert';
76
+ import { node, runDetectorOnFixture } from '@skill-map/testkit';
77
+ import detector from '../extensions/my-detector.mjs';
78
+
79
+ test('emits one link per [[ref:<name>]]', async () => {
80
+ const links = await runDetectorOnFixture(detector, {
81
+ body: 'See [[ref:architect]] and [[ref:sre]].',
82
+ context: { node: node({ path: 'sample.md' }) },
83
+ });
84
+ strictEqual(links.length, 2);
85
+ strictEqual(links[0].target, 'architect');
86
+ });
87
+ ```
88
+
89
+ ```bash
90
+ node --test test/my-detector.test.mjs
91
+ ```
92
+
93
+ The testkit also ships `runRuleOnGraph` (rules), `runFormatterOnGraph` (formatters), `makeFakeStorage` (KV storage), and `makeFakeRunner` (probabilistic mode). Full surface in [`index.ts`](./index.ts).
94
+
95
+ ## Run it under the real CLI
96
+
97
+ ```bash
98
+ mkdir -p .skill-map/plugins
99
+ cp -r my-plugin .skill-map/plugins/
100
+ sm plugins list # status should be: loaded
101
+ sm scan
102
+ ```
103
+
104
+ Discovery roots (in order): `<project>/.skill-map/plugins/`, then `~/.skill-map/plugins/`. Override with `--plugin-dir <path>`.
105
+
106
+ If `sm plugins list` shows anything other than `loaded` / `disabled`, run `sm plugins doctor` for the diagnostic and check the [Diagnostics table](../spec/plugin-author-guide.md#diagnostics).
107
+
108
+ ## A complete worked example
109
+
110
+ [`examples/hello-world/`](../examples/hello-world/) is the smallest plugin that compiles, loads, scans, and tests. Copy it as a template.
111
+
112
+ ## See also
113
+
114
+ - [`spec/plugin-author-guide.md`](../spec/plugin-author-guide.md) — full contract, all six extension kinds, storage modes, dual-mode posture.
115
+ - [`spec/architecture.md`](../spec/architecture.md) — extension contract, ports, execution modes.
116
+ - [`spec/plugin-kv-api.md`](../spec/plugin-kv-api.md) — KV storage API for stateful plugins.
117
+ - [`spec/schemas/plugins-registry.schema.json`](../spec/schemas/plugins-registry.schema.json) — normative manifest shape.
118
+
119
+ ## Stability
120
+
121
+ `experimental` while Step 9 is in flight. The detector / rule / formatter helpers and builders are intended to stay stable through v1.0; `makeFakeRunner` may change to track the Step 10 job subsystem contract.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@skill-map/testkit",
3
- "version": "0.2.0",
4
- "description": "Kernel mocks + builders for plugin authors. Test detectors, rules, renderers, and audits without spinning up the full skill-map runtime.",
3
+ "version": "0.3.0",
4
+ "description": "Kernel mocks + builders for plugin authors. Test detectors, rules, and formatters without spinning up the full skill-map runtime.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "homepage": "https://skill-map.dev",