@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.
- package/README.md +121 -0
- 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.
|
|
4
|
-
"description": "Kernel mocks + builders for plugin authors. Test detectors, rules,
|
|
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",
|