@skill-map/spec 0.61.0 → 0.62.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 +16 -0
- package/architecture.md +1 -0
- package/cli-contract.md +9 -3
- package/index.json +6 -6
- package/package.json +1 -1
- package/plugin-author-guide.md +2 -0
- package/schemas/extensions/provider.schema.json +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Spec changelog
|
|
2
2
|
|
|
3
|
+
## 0.62.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- New normative import-trust boundary for project-local plugins: a drop-in plugin under `<cwd>/.skill-map/plugins/` is discovered but its extension code is NOT imported or executed by the runtime verbs until the operator grants local trust via `sm plugins enable <id>`. The committed `settings.json` baseline cannot grant it, so cloning and scanning a repo no longer auto-executes its plugins; built-ins and `--plugin-dir` stay ungated. Defined in architecture.md §Locality.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Reconciled the exit-codes table in `cli-contract.md`: code `2` no longer claims a missing DB (it covers a present-but-unreadable or corrupt DB), and code `5` now documents an absent project DB file, so a read verb with nothing to open exits `5` (run `sm scan` first). This matches the reference CLI, which ~20 read verbs already honour, and the existing server boot-resilience clause; no behaviour changed.
|
|
12
|
+
|
|
13
|
+
- The `sm tutorial` book now adapts to the active provider lens via two tracks: a rich track (Claude / Codex, with agents, commands, slash and mentions) and a basic track (the open-standard Agent Skills / Antigravity family, skills and markdown wired by markdown references). Scaffolding for the open standard now lays a complete references-based campaign instead of a Claude-shaped book with gaps, and the provider/lens narration was corrected to the current model.
|
|
14
|
+
|
|
15
|
+
## User-facing
|
|
16
|
+
|
|
17
|
+
`sm tutorial` now runs end to end beyond Claude: a basic skills-and-references book on the open Agent Skills standard (agent-skills / Antigravity) and a rich book for OpenAI Codex, each matching how scans resolve your project.
|
|
18
|
+
|
|
3
19
|
## 0.61.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/architecture.md
CHANGED
|
@@ -558,6 +558,7 @@ Hooks introduce no new persisted state and do NOT participate in the determinist
|
|
|
558
558
|
### Locality
|
|
559
559
|
|
|
560
560
|
- **Drop-in**: extensions live inside plugins, discovered at boot from `<cwd>/.skill-map/plugins/<id>/` only. The `--plugin-dir <path>` escape hatch on the `sm plugins …` verb family loads a custom directory per invocation when the user explicitly opts in.
|
|
561
|
+
- **Import trust (security boundary).** A drop-in plugin discovered under the project-local `<cwd>/.skill-map/plugins/` is parsed (manifest read + surfaced in `sm plugins list`) but its extension CODE is NOT imported or executed until the operator grants LOCAL trust: a `config_plugins` (DB) override enabling the plugin (`<id>`) or any of its extensions (`<id>/<ext>`), as written by `sm plugins enable <id>` or the Settings toggle. The committed `settings.json` baseline does NOT grant import trust: a cloned repo controls its own `.skill-map/settings.json`, so honouring it would let a hostile repo auto-execute its plugins on the victim's first `sm scan`. A fresh clone therefore ships its project-local plugins discovered-but-unexecuted; the runtime emits a one-time notice naming how many were found and pointing at `sm plugins enable`. Built-in extensions (compiled into the CLI) and an explicit `--plugin-dir <path>` (the operator pointed the loader at the code on purpose) are NOT gated; `--no-plugins` skips discovery entirely. The `sm plugins` management family (`list` / `show` / `enable` / `disable` / `doctor`) still imports discovered plugin code to enumerate extensions, running those verbs is itself the operator's explicit choice to work with the project's plugins.
|
|
561
562
|
- **Built-in**: the reference impl bundles a default extension set (one Provider, four extractors, five analyzers, one formatter, one hook). The fifth analyzer, `core/schema-violation`, replays every scanned node and link through the authoritative spec schemas via AJV, the kernel-side guard against persisting non-conforming graph rows. The first built-in Hook is `core/update-check`, subscribing to `shutdown` to run the once-per-day "update available" probe + banner that lived on the CLI entry path before the Hook kind had concrete consumers. Loaded from `src/extensions/`, these are indistinguishable from plugin-supplied extensions to the kernel.
|
|
562
563
|
|
|
563
564
|
---
|
package/cli-contract.md
CHANGED
|
@@ -50,6 +50,12 @@ privacy gate (`sm config set --yes` or the Settings UI confirm dialog).
|
|
|
50
50
|
Plugins load from `<cwd>/.skill-map/plugins/` by default; an arbitrary
|
|
51
51
|
external location MAY be loaded via the `--plugin-dir <path>` escape
|
|
52
52
|
hatch on the `sm plugins …` verb family, user-explicit per invocation.
|
|
53
|
+
Project-local plugins are discovered but their code is NOT executed by
|
|
54
|
+
`sm scan` / `sm serve` (and the other runtime verbs) until the operator
|
|
55
|
+
grants local trust via `sm plugins enable <id>`; the committed
|
|
56
|
+
`settings.json` does not grant it. `--plugin-dir` and built-ins are not
|
|
57
|
+
gated. See [`architecture.md` §Locality](./architecture.md) (import
|
|
58
|
+
trust) for the normative model.
|
|
53
59
|
|
|
54
60
|
### User-settings file (narrow, documented exception)
|
|
55
61
|
|
|
@@ -141,10 +147,10 @@ All verbs use this shared table. Additional codes MAY be defined per-verb (docum
|
|
|
141
147
|
|---|---|---|
|
|
142
148
|
| `0` | OK | Command completed, no issues at or above the configured severity threshold. |
|
|
143
149
|
| `1` | Issues found | Command completed, but deterministic issues at `error` severity exist. Applies to `sm scan`, `sm check`, `sm doctor`. |
|
|
144
|
-
| `2` | Operational error | Bad flags,
|
|
150
|
+
| `2` | Operational error | Bad flags, a present-but-unreadable / corrupt DB, unreadable file, corrupt config, runtime / environment mismatch (e.g. wrong Node version, missing native dependency), unhandled exception. Accompanied by an error message on stderr. (An *absent* project DB file is `5`, see below.) |
|
|
145
151
|
| `3` | Duplicate conflict | Job submission refused because an active duplicate exists (same `action + version + node + contentHash`). Returned by `sm job submit`. |
|
|
146
152
|
| `4` | Nonce mismatch | `sm record` called with an `id`/`nonce` pair that does not match. |
|
|
147
|
-
| `5` | Not found | A named resource does not exist (node id, job id, plugin id, config key). |
|
|
153
|
+
| `5` | Not found | A named resource does not exist (node id, job id, plugin id, config key), or the project DB file is absent so a read verb (`sm check`, `list`, `show`, `graph`, `export`, `history`, `orphans`, `db dump` / `reset` / `backup` / `shell`, `job prune`) has nothing to open, run `sm scan` first. An explicit `--db <path>` that does not exist is the same case (see §Server boot resilience). |
|
|
148
154
|
|
|
149
155
|
Codes 6–15 are reserved. Codes ≥ 16 are free for verb-specific use.
|
|
150
156
|
|
|
@@ -191,7 +197,7 @@ The destination is the selected Provider's `scaffold.skillDir` (e.g. `.claude/sk
|
|
|
191
197
|
- Without `--for`, the default is the first scaffold-capable Provider in catalog order (Claude). The verb requires an empty cwd (see below), so there is no marker to detect: provider auto-detection does not apply.
|
|
192
198
|
- Without `--for`, on interactive stdin the verb prompts with a numbered list of Providers declaring `scaffold.skillDir`, marking the default (Claude); an empty answer accepts it. Each option shows the Provider label plus any `scaffold.aka` agents in parentheses (e.g. the open standard lists Antigravity and OpenAI Codex). The `aka` strings are display-only, NOT accepted by `--for`.
|
|
193
199
|
- Without `--for`, on non-interactive stdin (pipes, CI) the verb selects the default without prompting, staying scriptable.
|
|
194
|
-
- `--experimental` includes Providers flagged `stability: 'experimental'`
|
|
200
|
+
- `--experimental` includes Providers flagged `stability: 'experimental'` as scaffold destinations and enables them in the seeded fixture so the demo scan classifies their nodes. Without it, experimental Providers are omitted from the prompt and `--for <experimental-id>` is a usage error (they ship disabled by default). Default behaviour offers the stable, ready destinations (today Claude, the rich-track anchor, and the open-standard `agent-skills`, the basic-track anchor).
|
|
195
201
|
|
|
196
202
|
Behaviour:
|
|
197
203
|
|
package/index.json
CHANGED
|
@@ -174,14 +174,14 @@
|
|
|
174
174
|
}
|
|
175
175
|
]
|
|
176
176
|
},
|
|
177
|
-
"specPackageVersion": "0.
|
|
177
|
+
"specPackageVersion": "0.62.0",
|
|
178
178
|
"integrity": {
|
|
179
179
|
"algorithm": "sha256",
|
|
180
180
|
"files": {
|
|
181
|
-
"CHANGELOG.md": "
|
|
181
|
+
"CHANGELOG.md": "db921746ca85beb0aaa13f6ae79892a980d256238015ebc4ac711dbd2fb13714",
|
|
182
182
|
"README.md": "a790cd010b46d47883d1f37e3893cea9d7aa69ec4750c0202e6a0c99991e7980",
|
|
183
|
-
"architecture.md": "
|
|
184
|
-
"cli-contract.md": "
|
|
183
|
+
"architecture.md": "434954b096c0f34752002996356d2d8e7cf578b345f62525fe80a50a72ccb6ba",
|
|
184
|
+
"cli-contract.md": "691813e1eb847316304d5f90cebd6e6b9210f83dd4ee801fce0b69946ef130a6",
|
|
185
185
|
"conformance/README.md": "dcbef7249f161acf597552a05dcadc813cd0ced430dcd3f813fcf5e1c876335d",
|
|
186
186
|
"conformance/cases/backtick-path-extraction.json": "4620e7f8bc161fc57cb44001e9d99879c7e22b4865a0c27a20dc28969cd936d9",
|
|
187
187
|
"conformance/cases/extractor-collision-detection.json": "179a02c61892f0d26492de0c4e2c327fa6b4986d1265a8f119e871df6afe4658",
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
"interfaces/security-scanner.md": "0996dd782e2d39d4791f2e290da4bb1a68a5b30c1f79187977188ec8e3fe6ef2",
|
|
235
235
|
"job-events.md": "2c7017f5f0003b19653424111a07043487173cbe88b51e961598bb1693987059",
|
|
236
236
|
"job-lifecycle.md": "ce33bc8bb5090ea183f860e495bfccc2a4a0ac2e23f6ebad83b9c28aad59124e",
|
|
237
|
-
"plugin-author-guide.md": "
|
|
237
|
+
"plugin-author-guide.md": "9244ee6aef49100867d46b324e13b3c3413a071813e34889563d4bfcef78c7f0",
|
|
238
238
|
"plugin-kv-api.md": "5e095581020043af73ff028e272f56d42ca9eb6e506dd777d45703f9db796a5b",
|
|
239
239
|
"plugin-quickstart.md": "19092b278d80df357ea623dc3bd9f833d059582ee1356f317621913d91e50512",
|
|
240
240
|
"prompt-preamble.md": "5d0f836688aa23eafc32104c3174132340b268361f6060326eec84da17c6ad6d",
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
"schemas/extensions/formatter.schema.json": "880dc379ad545a62404403533a01eda5171edba0390561fc46ec6e986e0b9bd3",
|
|
252
252
|
"schemas/extensions/hook.schema.json": "f56aef59e9986ffdf7d86aa2e048dccccf217000a358b8c64737cbd911c48dad",
|
|
253
253
|
"schemas/extensions/provider-kind.schema.json": "499b2418bbe6d8a84a1608e26c56b52c2652a30ce314bc2989094418797dc1e6",
|
|
254
|
-
"schemas/extensions/provider.schema.json": "
|
|
254
|
+
"schemas/extensions/provider.schema.json": "33f189cb6d6e987d7af1d5a8968834f92ba674f5621953aaa1f84d3a079a53e3",
|
|
255
255
|
"schemas/frontmatter/base.schema.json": "47f05ffa2a51f465f1b8df70cc7a1e7afe2c40f8d37826cd8a569977e9036b8d",
|
|
256
256
|
"schemas/history-stats.schema.json": "436aa0ffe744bdb699000447e86b45724fbd2cc4642781074eb1527522b9058c",
|
|
257
257
|
"schemas/input-types.schema.json": "93b27a1cbd1f131d42730eb9a89cf3af6889e9f17b20a48ce36133885503e01b",
|
package/package.json
CHANGED
package/plugin-author-guide.md
CHANGED
|
@@ -60,6 +60,8 @@ The kernel scans one root: `<cwd>/.skill-map/plugins/`, committed-with-the-repo
|
|
|
60
60
|
|
|
61
61
|
A plugin is any direct child directory of that root containing a `plugin.json`. Nested directories are not searched recursively. Pass `--plugin-dir <path>` to replace the default root with a custom directory (mostly for testing, or a plugin set the operator opts into).
|
|
62
62
|
|
|
63
|
+
**Import trust.** A project-local plugin is discovered (manifest parsed, listed by `sm plugins list`) but its code is NOT imported by the runtime verbs (`sm scan`, `sm serve`, ...) until the operator trusts it locally with `sm plugins enable <id>` (or the Settings toggle), which writes a `config_plugins` override. This is a security boundary: cloning a repo and scanning it must not auto-execute the repo's plugins, so the committed `settings.json` baseline cannot grant import trust, only the local DB override can. Authors developing a plugin enable it once locally; `--plugin-dir` is not gated. See [`architecture.md` §Locality](./architecture.md).
|
|
64
|
+
|
|
63
65
|
After every change to `plugins/`, run `sm plugins list` to see each plugin's load status. The seven statuses are documented under [Diagnostics](#diagnostics).
|
|
64
66
|
|
|
65
67
|
### Plugin id uniqueness
|
|
@@ -97,18 +97,24 @@
|
|
|
97
97
|
"type": "object",
|
|
98
98
|
"required": ["skillDir"],
|
|
99
99
|
"additionalProperties": false,
|
|
100
|
-
"description": "Authoring targets for verbs that MATERIALISE files into this Provider's on-disk territory (today only `sm tutorial`, which drops a skill folder where the Provider's runtime will discover it). Distinct from `detect` (which READS markers to suggest a lens) and from `classify` (which READS paths during a scan): `scaffold` is the WRITE side, the directory a generator drops new content into so the target runtime picks it up. Optional: a Provider with no `scaffold` block is never offered as a destination by a materialising verb (e.g. `
|
|
100
|
+
"description": "Authoring targets for verbs that MATERIALISE files into this Provider's on-disk territory (today only `sm tutorial`, which drops a skill folder where the Provider's runtime will discover it). Distinct from `detect` (which READS markers to suggest a lens) and from `classify` (which READS paths during a scan): `scaffold` is the WRITE side, the directory a generator drops new content into so the target runtime picks it up. Optional: a Provider with no `scaffold` block is never offered as a destination by a materialising verb (e.g. `antigravity`, whose skills and basic-track book are already covered by the open-standard `agent-skills` row, and `core/markdown`, which owns no authoring convention). The skill-folder convention is uniform across hosts (`<skillDir>/<name>/SKILL.md`), so a single `skillDir` is enough today; a future verb that scaffolds agents or commands adds a sibling field (`agentDir`, `commandDir`) without breaking this one.",
|
|
101
101
|
"properties": {
|
|
102
102
|
"skillDir": {
|
|
103
103
|
"type": "string",
|
|
104
104
|
"minLength": 1,
|
|
105
105
|
"pattern": "^\\.?[A-Za-z0-9][A-Za-z0-9._/-]*$",
|
|
106
|
-
"description": "Directory (relative to the scope root) under which a materialising verb writes a skill folder, e.g. `.claude/skills` for Claude, `.agents/skills` for the open standard. The verb appends `/<skillName>/SKILL.md`. Relative, no leading slash and no `..` traversal (the pattern forbids both); the consuming verb joins it onto the cwd."
|
|
106
|
+
"description": "Directory (relative to the scope root) under which a materialising verb writes a skill folder, e.g. `.claude/skills` for Claude, `.agents/skills` for the open standard (also Codex, whose skills adopt that layout). The verb appends `/<skillName>/SKILL.md`. Relative, no leading slash and no `..` traversal (the pattern forbids both); the consuming verb joins it onto the cwd."
|
|
107
|
+
},
|
|
108
|
+
"marker": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"minLength": 1,
|
|
111
|
+
"pattern": "^\\.?[A-Za-z0-9][A-Za-z0-9._/-]*$",
|
|
112
|
+
"description": "Optional directory the materialising verb creates so the active-lens resolver picks THIS Provider when its `skillDir` is shared with another lens. The open `.agents/skills` territory is read by several lenses (`agent-skills`, `antigravity`, `codex`), so a Provider whose skillDir is that shared territory but whose lens needs a distinct marker (e.g. Codex's `.codex`) declares it here, and `sm tutorial --for <id>` drops the marker alongside the skill so the project resolves the intended lens. Omitted when the skillDir's own parent IS the marker (`.claude/skills` → the `.claude` marker)."
|
|
107
113
|
},
|
|
108
114
|
"aka": {
|
|
109
115
|
"type": "array",
|
|
110
116
|
"minItems": 1,
|
|
111
|
-
"description": "Display-only hints naming the agents that consume this Provider's scaffold territory, shown in parentheses next to the Provider label in the `sm tutorial` destination prompt (e.g. the open-standard `.agents/skills`
|
|
117
|
+
"description": "Display-only hints naming the agents that consume this Provider's scaffold territory AND share its tutorial track, shown in parentheses next to the Provider label in the `sm tutorial` destination prompt (e.g. the open-standard `.agents/skills` `agent-skills` Provider lists Google's Antigravity, which shares both the territory and the basic track; OpenAI's Codex also reads that territory but is a rich-track lens, so it is NOT listed here, advertising it under the basic row would hand it the wrong book). Purely presentational: these strings are NOT matched by `--for` (only registered Provider ids are) and have no runtime effect. Optional; absent means the prompt shows the bare Provider label.",
|
|
112
118
|
"items": { "type": "string", "minLength": 1 }
|
|
113
119
|
}
|
|
114
120
|
}
|