@skill-map/spec 0.8.0 → 0.10.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/CHANGELOG.md +230 -79
- package/conformance/README.md +1 -1
- package/conformance/cases/kernel-empty-boot.json +2 -2
- package/conformance/coverage.md +1 -1
- package/db-schema.md +2 -2
- package/index.json +11 -11
- package/interfaces/security-scanner.md +1 -1
- package/package.json +1 -1
- package/plugin-author-guide.md +6 -6
- package/schemas/conformance-case.schema.json +12 -3
- package/schemas/extensions/action.schema.json +2 -2
- package/schemas/node.schema.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,160 @@
|
|
|
1
1
|
# Spec changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f8a7125: Open `Node.kind` to any Provider-declared string (Phase A — spec only).
|
|
8
|
+
|
|
9
|
+
The kernel always documented `IProvider.kinds` as "open by design" so future Cursor / Obsidian / Roo Providers can declare their own kinds. The spec, however, had three layers underneath that closed it back to the original five-value Claude Provider catalog (`skill` / `agent` / `command` / `hook` / `note`):
|
|
10
|
+
|
|
11
|
+
- `node.schema.json#/properties/kind` carried `enum: [<5 values>]` — AJV-rejected anything else.
|
|
12
|
+
- `db-schema.md` § `scan_nodes` and § `state_summaries` mandated `CHECK in (<5 values>)` SQL constraints.
|
|
13
|
+
- `extensions/action.schema.json#/.../filter/kind` had the same closed list for the per-action applicability filter.
|
|
14
|
+
|
|
15
|
+
This phase opens the spec end:
|
|
16
|
+
|
|
17
|
+
- `node.schema.json#/properties/kind` → `{ "type": "string", "minLength": 1 }` with a description naming the built-in Claude catalog so consumers know the default contract.
|
|
18
|
+
- `db-schema.md` drops both `CHECK in (...)` constraint rows. Both columns stay `TEXT NOT NULL`.
|
|
19
|
+
- `extensions/action.schema.json#/.../filter/kind` widens to `{ items: { "type": "string", "minLength": 1 } }`.
|
|
20
|
+
|
|
21
|
+
The TS side (`Node.kind: string`, `IProvider.classify(...): { kind: string; ... }`, Kysely `TNodeKind = string`) and the SQL `002_open_node_kinds` migration that drops the live CHECK constraints land in follow-up phases under `@skill-map/cli`. Phase A is a safe checkpoint: shipping the spec change alone changes nothing at runtime (the kernel still emits closed kinds, the live DB still enforces the existing CHECK), but it unblocks the rest of the refactor and aligns the source-of-truth artifact with the design intent.
|
|
22
|
+
|
|
23
|
+
Migration for consumers:
|
|
24
|
+
|
|
25
|
+
- Anyone validating an exported `Node` JSON against `node.schema.json` now accepts external-Provider kinds.
|
|
26
|
+
- Any UI / dashboard / script that hard-coded the closed enum elsewhere (filter chips, assertion sets) needs to widen to `string` and accept whatever an enabled Provider declares.
|
|
27
|
+
|
|
28
|
+
Pre-1.0 minor bump per `spec/versioning.md` § Pre-1.0 (this is breaking for consumers that relied on the enum, but pre-1.0 breakings ship as minor).
|
|
29
|
+
|
|
30
|
+
## 0.9.0
|
|
31
|
+
|
|
32
|
+
### Minor Changes
|
|
33
|
+
|
|
34
|
+
- 88afe24: Cleanup pass post-v0.8.0 — finishing the renames and wiring the
|
|
35
|
+
conformance kill-switches.
|
|
36
|
+
|
|
37
|
+
**Pre-1.0 minor bump** per `spec/versioning.md` § Pre-1.0. The schema
|
|
38
|
+
field rename below is technically breaking, but ships as a minor while
|
|
39
|
+
the spec stays `0.Y.Z`.
|
|
40
|
+
|
|
41
|
+
## Spec changes (`@skill-map/spec`)
|
|
42
|
+
|
|
43
|
+
### Breaking — `conformance-case.schema.json`
|
|
44
|
+
|
|
45
|
+
- **Rename `setup.disableAllDetectors` → `setup.disableAllExtractors`.**
|
|
46
|
+
Finishes the kind rename Detector → Extractor introduced in 0.8.0
|
|
47
|
+
(Phase 2 of the plug-in model overhaul). The previous name was the
|
|
48
|
+
last residue and it never reached a release where anything consumed
|
|
49
|
+
it.
|
|
50
|
+
- **`setup.disableAll{Providers,Extractors,Rules}` are now consumed
|
|
51
|
+
end-to-end.** Until this release the three toggles were declared in
|
|
52
|
+
the schema and accepted by the runner, but the runner never threaded
|
|
53
|
+
them anywhere — the `kernel-empty-boot` case happened to pass
|
|
54
|
+
because its fixture is empty. The runner now injects
|
|
55
|
+
`SKILL_MAP_DISABLE_ALL_{PROVIDERS,EXTRACTORS,RULES}=1` into the
|
|
56
|
+
child process environment when the matching toggle is `true`, and
|
|
57
|
+
the CLI's scan composer drops every extension of the disabled kind
|
|
58
|
+
from the in-scan pipeline regardless of granularity gates and
|
|
59
|
+
`--no-built-ins`. Each toggle now has a docstring on the schema
|
|
60
|
+
property pointing at the env-var convention.
|
|
61
|
+
- `kernel-empty-boot` case updated for the rename.
|
|
62
|
+
- `conformance/README.md` example updated.
|
|
63
|
+
|
|
64
|
+
### Non-breaking — copy fixes
|
|
65
|
+
|
|
66
|
+
- Comments and docstrings across `architecture.md` and friends already
|
|
67
|
+
refer to "Extractor" everywhere; only the schema field stayed on the
|
|
68
|
+
old name. No prose changes in this bump.
|
|
69
|
+
|
|
70
|
+
## CLI changes (`@skill-map/cli`)
|
|
71
|
+
|
|
72
|
+
### Breaking — `IDiscoveredPlugin.status` enum
|
|
73
|
+
|
|
74
|
+
- **Rename `'loaded'` → `'enabled'`.** The schema enum
|
|
75
|
+
(`plugins-registry.schema.json`) already used `enabled` since 0.8.0;
|
|
76
|
+
the runtime drifted to `loaded` and has now been pulled back so the
|
|
77
|
+
runtime status matches the spec contract. `'disabled'`, the
|
|
78
|
+
semantic pair, was already aligned. Every consumer (`sm plugins
|
|
79
|
+
list`, `sm plugins doctor`, `sm db prune` plugin filter, runtime
|
|
80
|
+
plugin composer) updated. No published consumers exist.
|
|
81
|
+
|
|
82
|
+
### Non-breaking — sweep cleanup
|
|
83
|
+
|
|
84
|
+
- Old `Detector` / `detector` references (kind name, manifest field
|
|
85
|
+
names, JSDoc, comments, test fixture filenames, test variable
|
|
86
|
+
names) replaced with `Extractor` / `extractor` across the
|
|
87
|
+
production code and test suite. Excludes historical CHANGELOG
|
|
88
|
+
entries, explicit migration notes ("Renamed from Detector"), and
|
|
89
|
+
test data strings whose semantics are independent of the kind
|
|
90
|
+
name (e.g. `'@FooDetector'` in trigger normalization tests).
|
|
91
|
+
- A residual reference to "an audit reading `ScanResult.issues`" in
|
|
92
|
+
`validate-all`'s docstring rewritten without the removed kind name.
|
|
93
|
+
|
|
94
|
+
## Tests
|
|
95
|
+
|
|
96
|
+
- `plugin-runtime-branches.test.ts` — five new unit tests covering
|
|
97
|
+
the env-var kill-switch in `composeScanExtensions` (per kind, all
|
|
98
|
+
three together, and stray-value resilience).
|
|
99
|
+
- `conformance-disable-flags.test.ts` — four new e2e tests pointing
|
|
100
|
+
the runner at a populated fixture with each toggle in turn (and a
|
|
101
|
+
baseline) so a regression in the env-var pipeline shows up
|
|
102
|
+
structurally rather than relying on the empty-fixture coincidence.
|
|
103
|
+
|
|
104
|
+
## [Unreleased]
|
|
105
|
+
|
|
106
|
+
### Minor (breaking, pre-1.0)
|
|
107
|
+
|
|
108
|
+
- **`Node.kind` opens to any non-empty string (was the closed enum
|
|
109
|
+
`skill` / `agent` / `command` / `hook` / `note`).** The kernel always
|
|
110
|
+
permitted external Providers — `IProvider.kinds` is documented as
|
|
111
|
+
"open by design" so a future Cursor / Obsidian / Roo Provider can
|
|
112
|
+
declare its own kinds — but the `node.schema.json` enum + the
|
|
113
|
+
`scan_nodes.kind` SQL CHECK + the closed TS `NodeKind` union closed
|
|
114
|
+
three layers underneath. Effects:
|
|
115
|
+
- `node.schema.json#/properties/kind` switches from `enum: [...5
|
|
116
|
+
values]` to `{ "type": "string", "minLength": 1 }`. The
|
|
117
|
+
description still names the built-in Claude Provider catalog so
|
|
118
|
+
consumers know what to expect from the default install.
|
|
119
|
+
- `db-schema.md` drops the `CHECK in (...)` constraint on
|
|
120
|
+
`scan_nodes.kind` and `state_summaries.kind`. Both columns stay
|
|
121
|
+
`TEXT NOT NULL`.
|
|
122
|
+
- `extensions/action.schema.json#/.../filter/kind` (the per-kind
|
|
123
|
+
filter for action applicability) widens the same way: `items:
|
|
124
|
+
{ type: 'string', minLength: 1 }` instead of the closed enum.
|
|
125
|
+
Migration: consumers who validate exported `Node` JSON against
|
|
126
|
+
`node.schema.json` will now accept external-Provider kinds. Any
|
|
127
|
+
consumer that hard-coded the closed enum elsewhere (UI filter chip
|
|
128
|
+
set, scripted assertions) needs to widen to "string". The TS +
|
|
129
|
+
SQL counterpart lands in `@skill-map/cli` (kernel TS contract +
|
|
130
|
+
migration `002_open_node_kinds`).
|
|
131
|
+
- **`conformance-case.schema.json` — rename `setup.disableAllDetectors`
|
|
132
|
+
→ `setup.disableAllExtractors`.** Finishes the kind rename Detector →
|
|
133
|
+
Extractor introduced in 0.8.0 (Phase 2 of the plug-in model
|
|
134
|
+
overhaul). The previous name was a residue from an unfinished sweep
|
|
135
|
+
and never reached a release that consumed it.
|
|
136
|
+
- **`setup.disableAll{Providers,Extractors,Rules}` are now wired
|
|
137
|
+
end-to-end.** Until this release the toggles were declared in the
|
|
138
|
+
schema but the runner threaded them nowhere; the `kernel-empty-boot`
|
|
139
|
+
case happened to pass because its fixture is empty. The runner now
|
|
140
|
+
injects `SKILL_MAP_DISABLE_ALL_{PROVIDERS,EXTRACTORS,RULES}=1` into
|
|
141
|
+
the child process environment per toggle, and the CLI's scan
|
|
142
|
+
composer drops every extension of the disabled kind from the
|
|
143
|
+
in-scan pipeline (overriding granularity gates and `--no-built-ins`).
|
|
144
|
+
Migration: any case JSON authored against the unwired schema needs
|
|
145
|
+
to swap `disableAllDetectors` for `disableAllExtractors`; behaviour
|
|
146
|
+
changes only when the toggles were already `true` (those cases will
|
|
147
|
+
now actually disable the kind, where previously they relied on
|
|
148
|
+
fixture content for the same outcome).
|
|
149
|
+
|
|
150
|
+
### Patch
|
|
151
|
+
|
|
152
|
+
- Updated `conformance/cases/kernel-empty-boot.json` for the field
|
|
153
|
+
rename above.
|
|
154
|
+
- Updated `conformance/README.md` example for the field rename above.
|
|
155
|
+
- Schema docstrings added to each `disableAll*` property documenting
|
|
156
|
+
the env-var convention the runner uses.
|
|
157
|
+
|
|
3
158
|
## 0.8.0
|
|
4
159
|
|
|
5
160
|
### Minor Changes
|
|
@@ -83,36 +238,32 @@
|
|
|
83
238
|
- **H3 — `--dry-run` semantics unified across `init` / `db reset`
|
|
84
239
|
/ `db restore`.** The new spec §Dry-run codifies the "no
|
|
85
240
|
writes, reads OK" contract; three verbs that did not previously
|
|
86
|
-
expose a preview now do:
|
|
87
|
-
- `
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
whether the target would be created or overwritten, plus the
|
|
105
|
-
WAL / SHM sidecars that would be dropped. Bypasses the
|
|
106
|
-
confirmation prompt.
|
|
107
|
-
Implementation: new helper `previewGitignoreEntries(scopeRoot,
|
|
241
|
+
expose a preview now do: - `sm init --dry-run` — previews the would-create lines for
|
|
242
|
+
`.skill-map/`, `settings.json`, `settings.local.json`,
|
|
243
|
+
`.skill-mapignore`, the `.gitignore` entries that would be
|
|
244
|
+
appended (deduped against the existing file), the DB
|
|
245
|
+
provisioning, and the first-scan trigger. Honours `--force`
|
|
246
|
+
for the would-overwrite preview. Re-init over an existing
|
|
247
|
+
scope without `--force` still exits 2 (same gate as live). - `sm db reset --dry-run` (default + `--state`) — opens the DB
|
|
248
|
+
read-only, computes the row count per `scan_*` (and `state_*`
|
|
249
|
+
when `--state`) table, and prints them. No `DELETE`
|
|
250
|
+
statements issued. Bypasses the `--state` confirmation prompt
|
|
251
|
+
entirely. - `sm db reset --hard --dry-run` — reports the DB file path and
|
|
252
|
+
size that would be unlinked; missing-file case prints a clear
|
|
253
|
+
no-op line instead of an error. - `sm db restore <src> --dry-run` — validates the source exists
|
|
254
|
+
(still exits 5 if missing), reports the source size and
|
|
255
|
+
whether the target would be created or overwritten, plus the
|
|
256
|
+
WAL / SHM sidecars that would be dropped. Bypasses the
|
|
257
|
+
confirmation prompt.
|
|
258
|
+
Implementation: new helper `previewGitignoreEntries(scopeRoot,
|
|
108
259
|
entries)` in `init.ts` mirrors `ensureGitignoreEntries` parsing
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
260
|
+
so the preview tracks the live outcome exactly. Texts moved
|
|
261
|
+
into `cli/i18n/init.texts.ts` and `cli/i18n/db.texts.ts` per
|
|
262
|
+
the N4 pattern. **9 new tests** under `init-cli.test.ts` (5
|
|
263
|
+
cases) and `db-cli.test.ts` (9 cases) cover the previews + the
|
|
264
|
+
spec invariants ("DB file checksum unchanged after dry-run",
|
|
265
|
+
"scope directory absent after dry-run", "source-not-found
|
|
266
|
+
still exits 5", "confirmation prompt skipped under dry-run").
|
|
116
267
|
- **H1 — Centralised exit codes.** New `cli/util/exit-codes.ts`
|
|
117
268
|
exporting `ExitCode` (`Ok` / `Issues` / `Error` / `Duplicate` /
|
|
118
269
|
`NonceMismatch` / `NotFound`) and the type alias `TExitCode`.
|
|
@@ -247,53 +398,53 @@ the`CamelCasePlugin`; raw SQL fragments must use snake_case to
|
|
|
247
398
|
a real i18n library, the strings move as-is. Functions would
|
|
248
399
|
have to be re-shaped first.
|
|
249
400
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
templates including their
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
401
|
+
Helper at `kernel/util/tx.ts`. Contract:
|
|
402
|
+
|
|
403
|
+
- Every `{{name}}` token MUST have a matching key in the vars
|
|
404
|
+
object — missing key throws (silent fallback hides
|
|
405
|
+
forgotten args in production).
|
|
406
|
+
- `null` / `undefined` values throw — caller coerces
|
|
407
|
+
upstream.
|
|
408
|
+
- Whitespace inside the braces tolerated (`{{ name }}`) so
|
|
409
|
+
long templates wrap cleanly across `+`-joined lines.
|
|
410
|
+
- Plural / conditional logic does NOT live in the template;
|
|
411
|
+
the caller picks `*_singular` vs `*_plural` keys.
|
|
412
|
+
|
|
413
|
+
Files created:
|
|
414
|
+
|
|
415
|
+
- `kernel/util/tx.ts` — the helper itself, with 13 tests in
|
|
416
|
+
`test/tx.test.ts` (single / multi token, whitespace,
|
|
417
|
+
missing / null / undefined keys, identifier shapes, error
|
|
418
|
+
truncation).
|
|
419
|
+
- `kernel/i18n/orchestrator.texts.ts` — frontmatter
|
|
420
|
+
malformed/invalid templates, `extension.error` payloads,
|
|
421
|
+
root validation errors.
|
|
422
|
+
- `kernel/i18n/plugin-loader.texts.ts` — every `load-error` /
|
|
423
|
+
`invalid-manifest` / `incompatible-spec` reason, plus the
|
|
424
|
+
import timeout message.
|
|
425
|
+
- `cli/i18n/scan.texts.ts` — `sm scan` flag-clash / scan
|
|
426
|
+
failure / guard / summary templates, plus the `sm scan
|
|
427
|
+
|
|
428
|
+
compare-with`dump-load errors.
|
|
429
|
+
-`cli/i18n/watch.texts.ts`—`sm watch`lifecycle templates.
|
|
430
|
+
-`cli/i18n/init.texts.ts`—`sm init`templates including
|
|
431
|
+
the`--dry-run`previews and the singular/plural pair for
|
|
432
|
+
gitignore updates.
|
|
433
|
+
-`cli/i18n/db.texts.ts`—`sm db reset`/`sm db restore` templates including their`--dry-run`previews.
|
|
434
|
+
-`cli/i18n/cli-progress-emitter.texts.ts`— the
|
|
435
|
+
`extension.error: ...` stderr line.
|
|
436
|
+
|
|
437
|
+
String content moved verbatim — every existing test that
|
|
438
|
+
matches on stderr / stdout content keeps passing. Trivial
|
|
439
|
+
single-token strings (`'No issues.\n'`) and rare per-handler
|
|
440
|
+
bespoke phrases stay inline; the pattern is now established
|
|
441
|
+
for whoever wants to migrate them in a follow-up.
|
|
442
|
+
|
|
443
|
+
Note on `ui/` divergence: today the two workspaces use
|
|
444
|
+
different shapes for their text tables (functions in `ui/`,
|
|
445
|
+
templates in `cli/`). Aligning them is a follow-up — the day a
|
|
446
|
+
real i18n library lands, both converge on its native shape.
|
|
447
|
+
The CLI shape is closer to the eventual destination.
|
|
297
448
|
|
|
298
449
|
- **N6 — `TIssueSeverity` aliased to `Severity`.** SQLite schema
|
|
299
450
|
type now reads `type TIssueSeverity = Severity` instead of
|
|
@@ -941,9 +1092,9 @@ kind, normalizedTrigger)` and prints one row per group with the
|
|
|
941
1092
|
(`Links out (12, 9 unique)`). When N > 1 detector emits the same
|
|
942
1093
|
logical link, the row also gets a `(×N)` suffix.
|
|
943
1094
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1095
|
+
`--json` output is byte-identical to before — raw rows, no merge.
|
|
1096
|
+
Storage is byte-identical to before. The grouping is purely a
|
|
1097
|
+
read-time presentation choice for human eyes.
|
|
947
1098
|
|
|
948
1099
|
**Spec changes (patch)**:
|
|
949
1100
|
|
package/conformance/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://skill-map.dev/spec/v0/conformance-case.schema.json",
|
|
3
3
|
"id": "kernel-empty-boot",
|
|
4
|
-
"description": "With every Provider,
|
|
4
|
+
"description": "With every Provider, extractor, and rule disabled, scanning an empty scope MUST return a valid, zero-filled ScanResult. Enforces the kernel boot invariant from architecture.md.",
|
|
5
5
|
"setup": {
|
|
6
6
|
"disableAllProviders": true,
|
|
7
|
-
"
|
|
7
|
+
"disableAllExtractors": true,
|
|
8
8
|
"disableAllRules": true
|
|
9
9
|
},
|
|
10
10
|
"invoke": {
|
package/conformance/coverage.md
CHANGED
|
@@ -60,4 +60,4 @@ These have their own conformance cases even though they are not JSON Schemas.
|
|
|
60
60
|
|
|
61
61
|
- **spec v0.x**: partial coverage acceptable. Every case added as the reference impl lands the verb that makes it runnable.
|
|
62
62
|
- **spec v1.0.0 release**: all rows above MUST be 🟢 covered or explicitly 🟠 deferred to v1.1 with a linked issue.
|
|
63
|
-
- **CI check**: [`scripts/check-coverage.
|
|
63
|
+
- **CI check**: [`scripts/check-coverage.js`](../../scripts/check-coverage.js) compares `spec/schemas/**/*.schema.json` against the matrix above on every PR. A schema without a row here, or a row pointing at a missing schema, fails CI (exit 1 with a `::error::` annotation). Wired into `ci.yml` §validate and into `npm run spec:check`.
|
package/db-schema.md
CHANGED
|
@@ -72,7 +72,7 @@ One row per detected node, matching [`schemas/node.schema.json`](./schemas/node.
|
|
|
72
72
|
| Column | Type | Constraint | Notes |
|
|
73
73
|
|---|---|---|---|
|
|
74
74
|
| `path` | TEXT | PRIMARY KEY | Relative path from scope root. Canonical node identifier. |
|
|
75
|
-
| `kind` | TEXT | NOT NULL
|
|
75
|
+
| `kind` | TEXT | NOT NULL | Open-by-design (`node.schema.json#/properties/kind`): the value is whatever the classifying Provider declares. Built-in Claude Provider catalog: `skill` / `agent` / `command` / `hook` / `note`. External Providers MAY emit their own. |
|
|
76
76
|
| `provider` | TEXT | NOT NULL | Provider extension id. |
|
|
77
77
|
| `title` | TEXT | NULL | |
|
|
78
78
|
| `description` | TEXT | NULL | |
|
|
@@ -274,7 +274,7 @@ One row per `(node_id, summarizer_action_id)`. See [`schemas/summaries/`](./sche
|
|
|
274
274
|
| Column | Type | Constraint |
|
|
275
275
|
|---|---|---|
|
|
276
276
|
| `node_id` | TEXT | NOT NULL |
|
|
277
|
-
| `kind` | TEXT | NOT NULL
|
|
277
|
+
| `kind` | TEXT | NOT NULL |
|
|
278
278
|
| `summarizer_action_id` | TEXT | NOT NULL |
|
|
279
279
|
| `summarizer_version` | TEXT | NOT NULL |
|
|
280
280
|
| `body_hash_at_generation` | TEXT | NOT NULL |
|
package/index.json
CHANGED
|
@@ -166,28 +166,28 @@
|
|
|
166
166
|
}
|
|
167
167
|
]
|
|
168
168
|
},
|
|
169
|
-
"specPackageVersion": "0.
|
|
169
|
+
"specPackageVersion": "0.10.0",
|
|
170
170
|
"integrity": {
|
|
171
171
|
"algorithm": "sha256",
|
|
172
172
|
"files": {
|
|
173
|
-
"CHANGELOG.md": "
|
|
173
|
+
"CHANGELOG.md": "a7712801b4513c3212cbefb8b1e7540accd40e22c4aa09234b98f6b044bd42c9",
|
|
174
174
|
"README.md": "bd30780525e75379eaeb5f8a903bdc601daf3862f3ec69dffc96c437e8d476fc",
|
|
175
175
|
"architecture.md": "c69a50e3e9b7d091799bd19cd9efe854a924c83bc2c8e79e0fcb727196151f6c",
|
|
176
176
|
"cli-contract.md": "1d09d047e07fd8793968259660012ebf64ab136967afead2d2666a59a40a020a",
|
|
177
|
-
"conformance/README.md": "
|
|
178
|
-
"conformance/cases/kernel-empty-boot.json": "
|
|
179
|
-
"conformance/coverage.md": "
|
|
177
|
+
"conformance/README.md": "07970f06c467e34413f07f6d8bec09ece892d1a903fa039d25b34a77e91187d2",
|
|
178
|
+
"conformance/cases/kernel-empty-boot.json": "ad4bbe9d637537625025c8bdb61285b1433568a2544b1ce0248f304ccff8c350",
|
|
179
|
+
"conformance/coverage.md": "eb57cd979bca59a252e3cd49796e068ac601169f859f32cdf37634486574c44c",
|
|
180
180
|
"conformance/fixtures/preamble-v1.txt": "1e0aeef224b64477bdc13a949c3ad402e68249caf499ecdba1302371677c068b",
|
|
181
|
-
"db-schema.md": "
|
|
182
|
-
"interfaces/security-scanner.md": "
|
|
181
|
+
"db-schema.md": "6542311118d2e74bdb7c7a48c208eccd5e55cf574f7cb38e976d6d7c3c666745",
|
|
182
|
+
"interfaces/security-scanner.md": "4a982667008f233656f44c61ce9948e062432d3debdcbf7a134da03bd4139d7d",
|
|
183
183
|
"job-events.md": "831501bd696a2801e2d160b314eb49794d0ba553da4487e15c7dcc72a1c230f6",
|
|
184
184
|
"job-lifecycle.md": "1fe88b1a2ed204e41bb41ac172fbb3e912dccd0dd8a1f8ea8e21a681b336d6ee",
|
|
185
|
-
"plugin-author-guide.md": "
|
|
185
|
+
"plugin-author-guide.md": "2dcdf8c570342d94c2c8f8d47594715254e3956d7939443023f1d6420e2b30d0",
|
|
186
186
|
"plugin-kv-api.md": "04b2178f46fb88adeae9240df9c9e1761b660396072001dac32cd402e11a2d7d",
|
|
187
187
|
"prompt-preamble.md": "23a8eff0477fbbc46192a27781bc781bda4202bb9c669b7a7a002b0d668146b0",
|
|
188
|
-
"schemas/conformance-case.schema.json": "
|
|
188
|
+
"schemas/conformance-case.schema.json": "7cd0f3aae5124f24be57cddb213d002d0466f79d06fd3da896075c8b28650410",
|
|
189
189
|
"schemas/execution-record.schema.json": "607e939bfcac4e18385ef93e27bbe28987ba35d5a7c67f3d6e4377ca819a9425",
|
|
190
|
-
"schemas/extensions/action.schema.json": "
|
|
190
|
+
"schemas/extensions/action.schema.json": "262272175c06a2e33c08f819a45c3ef8260276c91a9d0542fdffc932aeb32db7",
|
|
191
191
|
"schemas/extensions/base.schema.json": "e5c3406b88b0496a89791890b05083929429319d96b1f8cea0bec3ec9e3de8af",
|
|
192
192
|
"schemas/extensions/extractor.schema.json": "122d3f81ef91edcde9798e7dc8fcbf442a2996deea65aa4b03c9d5cb01ba2519",
|
|
193
193
|
"schemas/extensions/formatter.schema.json": "2ab092aa37ae349c69b93071ed4f0e131affb7bb5799516ca82c721262631b36",
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"schemas/issue.schema.json": "40f6f8abadcce0fd8eac9df27ffcc20b2fc9fda6970142ddb8e7e56b1760b9b1",
|
|
200
200
|
"schemas/job.schema.json": "582999899f8846f70c4d745d2813e53b97a4f5ccd3d8d163eeb68b201e7124e4",
|
|
201
201
|
"schemas/link.schema.json": "0a95a24849a38b9ef5bad5361519a9f9e012b5bc3001289fad29d0851fceff6b",
|
|
202
|
-
"schemas/node.schema.json": "
|
|
202
|
+
"schemas/node.schema.json": "f9a0cc5d5a7f581915719e91ae401e46a82688e0865fd3a2eb64bd42798a6b2b",
|
|
203
203
|
"schemas/plugins-registry.schema.json": "5ca1d4970ae64f064f05c237a649d9f82d5edbeb7c121ec50cb4aaca13f4bc51",
|
|
204
204
|
"schemas/project-config.schema.json": "4f5b1ce01446d78ebf524d11c36e0a3ae101e69008c922a2b3f53fccfd1cb87f",
|
|
205
205
|
"schemas/report-base.schema.json": "a1021e9a59b4df9f99cd92454d797e88469766e7d49f52d231c4645ffdfdad8f",
|
package/package.json
CHANGED
package/plugin-author-guide.md
CHANGED
|
@@ -14,7 +14,7 @@ This guide is **descriptive prose**, not the normative contract. The normative p
|
|
|
14
14
|
my-plugin/
|
|
15
15
|
├── plugin.json ← manifest (required)
|
|
16
16
|
└── extensions/
|
|
17
|
-
└── extractor.
|
|
17
|
+
└── extractor.js ← one file per declared extension
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
```jsonc
|
|
@@ -23,12 +23,12 @@ my-plugin/
|
|
|
23
23
|
"id": "my-plugin",
|
|
24
24
|
"version": "1.0.0",
|
|
25
25
|
"specCompat": "^1.0.0",
|
|
26
|
-
"extensions": ["./extensions/extractor.
|
|
26
|
+
"extensions": ["./extensions/extractor.js"]
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
```javascript
|
|
31
|
-
// my-plugin/extensions/extractor.
|
|
31
|
+
// my-plugin/extensions/extractor.js
|
|
32
32
|
export default {
|
|
33
33
|
id: 'my-extractor',
|
|
34
34
|
kind: 'extractor',
|
|
@@ -150,8 +150,8 @@ In your own plugin's `plugin.json`, set `granularity` only when you opt into the
|
|
|
150
150
|
"specCompat": "^1.0.0",
|
|
151
151
|
"granularity": "extension",
|
|
152
152
|
"extensions": [
|
|
153
|
-
"./extensions/orphan-skill-rule.
|
|
154
|
-
"./extensions/csv-formatter.
|
|
153
|
+
"./extensions/orphan-skill-rule.js",
|
|
154
|
+
"./extensions/csv-formatter.js"
|
|
155
155
|
]
|
|
156
156
|
}
|
|
157
157
|
```
|
|
@@ -625,7 +625,7 @@ import { test } from 'node:test';
|
|
|
625
625
|
import { strictEqual } from 'node:assert';
|
|
626
626
|
import { runExtractorOnFixture, node } from '@skill-map/testkit';
|
|
627
627
|
|
|
628
|
-
import extractor from '../extensions/extractor.
|
|
628
|
+
import extractor from '../extensions/extractor.js';
|
|
629
629
|
|
|
630
630
|
test('emits one reference per [[ref:<name>]] token', async () => {
|
|
631
631
|
const { links } = await runExtractorOnFixture(extractor, {
|
|
@@ -31,9 +31,18 @@
|
|
|
31
31
|
"description": "Pre-invocation toggles and ordered staging steps. All toggles default to `false`. `priorScans`, when present, run BEFORE the main `invoke` so a case can establish a prior snapshot the heuristic-driven verbs (e.g. `sm scan` rename detection) can react to.",
|
|
32
32
|
"additionalProperties": false,
|
|
33
33
|
"properties": {
|
|
34
|
-
"disableAllProviders": {
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
"disableAllProviders": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "When true, the runner injects `SKILL_MAP_DISABLE_ALL_PROVIDERS=1` into the child process environment, dropping every Provider extension (built-in and user-plugin) before scan composition."
|
|
37
|
+
},
|
|
38
|
+
"disableAllExtractors": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"description": "When true, the runner injects `SKILL_MAP_DISABLE_ALL_EXTRACTORS=1` into the child process environment, dropping every Extractor extension before scan composition."
|
|
41
|
+
},
|
|
42
|
+
"disableAllRules": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"description": "When true, the runner injects `SKILL_MAP_DISABLE_ALL_RULES=1` into the child process environment, dropping every Rule extension before scan composition."
|
|
45
|
+
},
|
|
37
46
|
"priorScans": {
|
|
38
47
|
"type": "array",
|
|
39
48
|
"description": "Ordered staging scans, each running before the next. For step N, the runner first replaces the scope's Provider content with `priorScans[N].fixture`, then invokes `sm scan` with the supplied flags. After the last step, the runner copies the top-level `fixture` (overwriting again) and runs the main `invoke`. The DB persists across all steps because `.skill-map/` is preserved between fixture swaps.",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"properties": {
|
|
34
34
|
"kind": {
|
|
35
35
|
"type": "array",
|
|
36
|
-
"items": { "type": "string", "
|
|
37
|
-
"description": "Node kinds this action accepts. Omitted → any kind."
|
|
36
|
+
"items": { "type": "string", "minLength": 1 },
|
|
37
|
+
"description": "Node kinds this action accepts. Open-by-design (matches `node.schema.json#/properties/kind`): an action declared with `kind: ['cursorRule']` is valid as long as some Provider classifies into `cursorRule`. Omitted → any kind."
|
|
38
38
|
},
|
|
39
39
|
"provider": {
|
|
40
40
|
"type": "array",
|
package/schemas/node.schema.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://skill-map.dev/spec/v0/node.schema.json",
|
|
4
4
|
"title": "Node",
|
|
5
|
-
"description": "A single markdown file in the graph
|
|
5
|
+
"description": "A single markdown file in the graph. Identified by its relative path from the scope root. The `kind` is whatever the classifying Provider declares; built-in kinds today are `skill`, `agent`, `command`, `hook`, `note`, but external Providers (Cursor, Obsidian, …) MAY emit their own.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["path", "kind", "provider", "bodyHash", "frontmatterHash", "bytes", "linksOutCount", "linksInCount", "externalRefsCount"],
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"kind": {
|
|
15
15
|
"type": "string",
|
|
16
|
-
"
|
|
17
|
-
"description": "Category assigned by the Provider.
|
|
16
|
+
"minLength": 1,
|
|
17
|
+
"description": "Category assigned by the Provider. Open-by-design — any non-empty string an enabled Provider declares is valid (built-in Claude Provider catalog: `skill` / `agent` / `command` / `hook` / `note`; external Providers MAY declare their own). Per-kind frontmatter schemas live with the Provider that emits the kind. Stability: stable."
|
|
18
18
|
},
|
|
19
19
|
"provider": {
|
|
20
20
|
"type": "string",
|