@skill-map/cli 0.29.0 → 0.31.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.
@@ -0,0 +1,206 @@
1
+ # Fixture templates
2
+
3
+ Read this file during pre-flight steps 3 and 4 of `SKILL.md`. It
4
+ holds the verbatim content of every file the skill writes to the
5
+ cwd at boot, plus the initial `master-state.yml` template.
6
+
7
+ ## Fixture layout (per provider)
8
+
9
+ Per §Provider detection in `SKILL.md`, the `<provider_dir>`
10
+ placeholder resolves to `.claude/`, `.gemini/`, or
11
+ `.agents/skills/` depending on the detected runtime. Drop any
12
+ file whose kind is not in the provider's supported set: on
13
+ `gemini` the agent + skill + note are valid; on `agent-skills`
14
+ only the skill + note are valid; on `claude` (default) all
15
+ three apply.
16
+
17
+ Canonical layout (substitute `<provider_dir>` per detection):
18
+
19
+ ```
20
+ <cwd>/
21
+ ├── <provider_dir>/
22
+ │ ├── agents/ (claude, gemini)
23
+ │ │ └── master-agent.md
24
+ │ └── skills/ (all three)
25
+ │ └── master-skill/
26
+ │ └── SKILL.md
27
+ ├── notes/
28
+ │ └── ideas.md
29
+ ├── master-state.yml
30
+ └── findings.md
31
+ ```
32
+
33
+ On `agent-skills` the `agents/` subtree is omitted (the provider
34
+ does not claim that kind); the skill lives at
35
+ `.agents/skills/master-skill/SKILL.md`.
36
+
37
+ Translate the natural-language prose (descriptions, body text,
38
+ list items) to the tester's language. Keep paths, frontmatter
39
+ keys, identifiers, and link targets in English.
40
+
41
+ ## File: `.claude/agents/master-agent.md` (kind: agent)
42
+
43
+ ```markdown
44
+ ---
45
+ name: master-agent
46
+ description: |
47
+ Example agent used by the advanced tutorial. Has a couple of
48
+ tools so the `core/tools-count` extractor emits a count.
49
+ tools: [Read, Bash, Edit]
50
+ model: sonnet
51
+ metadata:
52
+ version: "1.0.0"
53
+ ---
54
+
55
+ # master-agent
56
+
57
+ Walks the master-skill outputs and reports findings. Used as the
58
+ target node when we exercise extractors, analyzers, and the
59
+ plugin-authoring flow.
60
+ ```
61
+
62
+ ## File: `.claude/skills/master-skill/SKILL.md` (kind: skill)
63
+
64
+ ```markdown
65
+ ---
66
+ name: master-skill
67
+ description: |
68
+ Example skill paired with the master-agent for the advanced
69
+ tutorial. Links to the agent so extractors and analyzers have
70
+ something to chew on.
71
+ inputs:
72
+ - name: target
73
+ type: path
74
+ description: File to process.
75
+ required: true
76
+ outputs:
77
+ - name: report
78
+ type: string
79
+ description: Markdown summary.
80
+ metadata:
81
+ version: "1.0.0"
82
+ ---
83
+
84
+ # master-skill
85
+
86
+ Hands heavy work over to the
87
+ [master-agent](../../agents/master-agent.md) and emits a Markdown
88
+ report.
89
+
90
+ ## Steps
91
+ 1. Read the `target`.
92
+ 2. Validate the frontmatter.
93
+ 3. Delegate to the agent.
94
+ ```
95
+
96
+ ## File: `notes/ideas.md` (kind: markdown)
97
+
98
+ ```markdown
99
+ ---
100
+ name: Ideas backlog
101
+ description: |
102
+ Free-form notes for the advanced tutorial. Demonstrates the
103
+ catch-all markdown kind alongside the agent and skill.
104
+ tags: [notes, master]
105
+ metadata:
106
+ version: "1.0.0"
107
+ ---
108
+
109
+ # Ideas
110
+
111
+ - [ ] Compare extractor outputs side by side.
112
+ - [ ] Sketch a tiny plugin that surfaces a counter on the agent.
113
+ ```
114
+
115
+ ## File: `findings.md`
116
+
117
+ ```markdown
118
+ # Findings, sm-master
119
+
120
+ If you spot anything weird during the tutorial, log it here.
121
+
122
+ Per finding:
123
+ - **Tour**: <id>
124
+ - **Command**: `sm ...`
125
+ - **Expected**: ...
126
+ - **Got**: ...
127
+ - **Notes**: ...
128
+ ```
129
+
130
+ ## State YAML
131
+
132
+ Write to `<cwd>/master-state.yml`. Substitute the timestamps and
133
+ the captured `sm version` output.
134
+
135
+ ```yaml
136
+ master:
137
+ version: 1
138
+ started_at: "<ISO-8601 now>"
139
+ cwd: "<output of pwd>"
140
+ sm_version: "<output of sm version>"
141
+ provider: "<claude | gemini | agent-skills>" # filled from §Provider detection
142
+ tours:
143
+ # Add a new tour by appending another entry here, mirroring the
144
+ # shape below: status, estimated_min, and a steps[] array whose
145
+ # ids match the prefix of the reference file that owns the body
146
+ # (e.g. tour-foo.md → steps prefixed `foo-*`). The orchestrator
147
+ # in SKILL.md walks this list and dispatches each step id to its
148
+ # reference file.
149
+ plugins-tour:
150
+ status: "not_started" # not_started | in_progress | done | declined
151
+ estimated_min: 13
152
+ # All step bodies live in tour-plugins.md (tour-* ids).
153
+ steps:
154
+ - id: "tour-1-intro"
155
+ title: "How plugins work"
156
+ status: "pending"
157
+ - id: "tour-2-kinds"
158
+ title: "The six extension kinds"
159
+ status: "pending"
160
+ - id: "tour-3-explore"
161
+ title: "Explore one extension up close"
162
+ status: "pending"
163
+ settings-and-consent:
164
+ status: "not_started"
165
+ estimated_min: 5
166
+ # Settings + the `.sm` consent gate. Step bodies live in
167
+ # tour-settings.md (settings-* ids).
168
+ steps:
169
+ - id: "settings-1-project"
170
+ title: "Project settings: `.skill-map/settings.json`"
171
+ status: "pending"
172
+ - id: "settings-2-local"
173
+ title: "Per-user overrides: `settings.local.json`"
174
+ status: "pending"
175
+ build-and-configure:
176
+ status: "not_started"
177
+ estimated_min: 17
178
+ # Author a plugin end-to-end, then watch its contribution land
179
+ # and validate the manifest. Step bodies live in the two
180
+ # existing reference files (settings-* → tour-settings.md,
181
+ # authoring-* → tour-authoring.md); this list is the
182
+ # authoritative order.
183
+ steps:
184
+ - id: "authoring-1-scaffold"
185
+ title: "`sm plugins create demo-highlight`"
186
+ status: "pending"
187
+ - id: "authoring-2-anatomy"
188
+ title: "Tour the scaffold (plugin.json + stubs + README)"
189
+ status: "pending"
190
+ - id: "authoring-3-edit-setting"
191
+ title: "Edit a setting (string-list) and observe it in the UI"
192
+ status: "pending"
193
+ - id: "authoring-4-edit-slot"
194
+ title: "Change the view-slot the contribution targets"
195
+ status: "pending"
196
+ - id: "settings-6-contributions"
197
+ title: "Watch contributions land in the inspector"
198
+ status: "pending"
199
+ - id: "authoring-5-doctor-author"
200
+ title: "Catch a manifest mistake with `sm plugins doctor`"
201
+ status: "pending"
202
+ - id: "authoring-6-upgrade"
203
+ title: "Try `sm plugins upgrade` (no-op today, structure tour)"
204
+ status: "pending"
205
+ findings_file: "./findings.md"
206
+ ```
@@ -0,0 +1,296 @@
1
+ # Tour: plugin authoring (step library, `authoring-*` ids)
2
+
3
+ Step bodies used by the menu's option 3 (`build-and-configure`).
4
+ The SKILL.md orchestrator walks `master-state.yml.tours.build-and-configure.steps`
5
+ and dispatches each `authoring-*` id here; `settings-*` ids it
6
+ dispatches to `tour-settings.md`.
7
+
8
+ The tester writes their first plugin. We use `sm plugins create` to
9
+ scaffold an extractor that counts configurable keywords (TODO,
10
+ FIXME, etc.) per node, edit the manifest to change a setting and the
11
+ view-slot, and confirm the contribution lands in the UI.
12
+
13
+ ## Precondition check
14
+
15
+ Verify that `.skill-map/` exists in the cwd (pre-flight step 4 of
16
+ the `SKILL.md` orchestrator ran `sm init --no-scan` and appended
17
+ the master-tutorial's internal entries to `.skillmapignore`, so
18
+ this is the expected state regardless of whether the tester ran
19
+ `plugins-tour` first). If `.skill-map/` is missing, the fixture
20
+ is corrupted: surface the mismatch ("the project bootstrap is
21
+ gone, re-invoke `sm-master` from an empty dir") and stop.
22
+
23
+ ## Step `authoring-1-scaffold` — `sm plugins create demo-highlight` (~2 min)
24
+
25
+ **Context**: We're building `demo-highlight`: a tiny extractor
26
+ that scans each node's body for the keywords `TODO` and `FIXME`
27
+ and shows the count as a chip on the node card. The scaffolder
28
+ emits a working version of it; over the next steps we'll tweak
29
+ its setting, move the chip to a different slot, and break the
30
+ manifest on purpose to see the diagnostic catch it.
31
+
32
+ > Let's scaffold it with `sm plugins create`:
33
+
34
+ ```bash
35
+ sm plugins create demo-highlight
36
+ ```
37
+
38
+ Expected output:
39
+
40
+ ```
41
+ Created /<cwd>/.skill-map/plugins/demo-highlight
42
+ Next:
43
+ - Edit demo-highlight/extractors/demo-highlight-extractor/index.js (the extract() body)
44
+ - Run sm scan to see the contribution surface
45
+ - sm plugins slots list: browse other slots
46
+ ```
47
+
48
+ **Heads up on the id**: it must be **kebab-case lowercase**, no
49
+ slashes, no uppercase. `demo-highlight` is fine, `demo/highlight`
50
+ or `Demo-Highlight` are rejected.
51
+
52
+ Mark `authoring-1-scaffold: done`.
53
+
54
+ ## Step `authoring-2-anatomy` — tour the scaffold (~3 min)
55
+
56
+ Ask the tester to open the three files and walk through each one
57
+ with you. They DO NOT edit anything yet.
58
+
59
+ > Open the three files in your editor of choice:
60
+ >
61
+ > - `.skill-map/plugins/demo-highlight/plugin.json`
62
+ > - `.skill-map/plugins/demo-highlight/extractors/demo-highlight-extractor/index.js`
63
+ > - `.skill-map/plugins/demo-highlight/README.md`
64
+ >
65
+ > Take a minute to skim them. I'll narrate what each is for.
66
+
67
+ Then narrate, one file at a time:
68
+
69
+ > **`plugin.json`**: the manifest
70
+ >
71
+ > The contract the CLI validates at load.
72
+ >
73
+ > **Key fields:**
74
+ >
75
+ > - `id`: the kebab-case id you typed. Must match the bundle folder
76
+ > name.
77
+ >
78
+ > - `version`: starts at `0.1.0`; you bump it yourself, the CLI
79
+ > does not touch it.
80
+ >
81
+ > - `specCompat` / `catalogCompat`: which `sm` and plugin catalog
82
+ > version your plugin targets.
83
+ >
84
+ > - `granularity`: `'bundle'` (whole plugin enables/disables as one)
85
+ > or `'extension'` (each extension toggles independently). The
86
+ > scaffold picks `'bundle'`, the right default for 95% of plugins.
87
+ >
88
+ > - `settings`: user-configurable knobs. The scaffold ships
89
+ > `keywords`, a `string-list` defaulting to `["TODO", "FIXME"]`.
90
+ > Browse other input types with `sm plugins slots list`.
91
+ >
92
+ > There is no `extensions` field. The kernel discovers each
93
+ > extension by walking `<plugin-dir>/<kind>s/<name>/index.js`;
94
+ > the folder layout IS the contract.
95
+
96
+ > **`extractors/demo-highlight-extractor/index.js`**: the code
97
+ >
98
+ > Plain JavaScript with a default export. **Structure-as-truth**:
99
+ > the loader derives `id`, `kind`, and `pluginId` from the folder
100
+ > path; the manifest itself never declares them.
101
+ >
102
+ > **What the loader reads:**
103
+ >
104
+ > - The folder layout tells the loader this is an extractor named
105
+ > `demo-highlight-extractor` (`extractors/<id>/index.js`).
106
+ >
107
+ > - `ui`: which slots the extension emits to (renamed from
108
+ > `viewContributions` with the structure-as-truth refactor). The
109
+ > scaffold declares `count`, targeting `card.footer.left` (the
110
+ > chip in the bottom-left of every node card). The slot pins
111
+ > both the renderer (`NodeCounter`) and the payload shape.
112
+ >
113
+ > - `settings`: per-extension user-configurable knobs (moved here
114
+ > from `plugin.json` with the same refactor). Exposed at runtime
115
+ > via `ctx.settings.<settingId>`.
116
+ >
117
+ > - `extract(ctx)`: the function the kernel runs per node.
118
+ > `ctx.body` is the markdown body, `ctx.settings` carries what
119
+ > the user set on this extension, and `ctx.emitContribution(id,
120
+ > payload)` sends data to the slot.
121
+ >
122
+ > Heads up: the body has `|| ['TODO', 'FIXME']` as a defensive
123
+ > fallback in case `ctx.settings` is missing. In normal
124
+ > operation the kernel always passes the manifest's default (or
125
+ > the user's override), so the hardcoded list is never used,
126
+ > the manifest is the real source of truth.
127
+
128
+ > **`README.md`**: the docs
129
+ >
130
+ > Plain documentation; the CLI does not parse it.
131
+ >
132
+ > **Why it's here:** if your plugin lands in a registry one day,
133
+ > this is what shows up.
134
+
135
+ If the tester asks where the spec lives: `spec/plugin-author-guide.md`
136
+ and `spec/view-slots.md`.
137
+
138
+ Mark `authoring-2-anatomy: done`.
139
+
140
+ ## Step `authoring-3-edit-setting` — edit a setting and observe it (~3 min)
141
+
142
+ > Now we'll touch the settings. The scaffold tracks `TODO` and
143
+ > `FIXME`. Add a third keyword: `XXX`. The change goes in the
144
+ > extension manifest's `settings.keywords.default` array
145
+ > (structure-as-truth: settings live per-extension, not at the
146
+ > plugin root).
147
+
148
+ The tester edits the extension's `index.js` (per Inviolable rule
149
+ #2; configuration is a teach moment, you do NOT edit it for them):
150
+
151
+ > Open `.skill-map/plugins/demo-highlight/extractors/demo-highlight-extractor/index.js`.
152
+ > Find the `settings.keywords.default` array. Add `"XXX"` to it.
153
+ > Save.
154
+
155
+ Then have them seed the fixture with something to count. Plant one
156
+ line in `notes/ideas.md` (you `Edit` this one because it is fixture
157
+ content, not configuration). Append at the end:
158
+
159
+ ```markdown
160
+ - [ ] TODO write more demos.
161
+ - [ ] FIXME the broken connector.
162
+ - [ ] XXX revisit naming.
163
+ ```
164
+
165
+ Now re-scan and confirm the extractor picks them up:
166
+
167
+ ```bash
168
+ sm scan
169
+ sm show notes/ideas.md
170
+ ```
171
+
172
+ `sm show` prints the node's persisted contributions. Look for a
173
+ `count` contribution with `value: 3` (one match per keyword). The
174
+ exact JSON shape is in the body of the `show` output under a
175
+ `contributions` key.
176
+
177
+ > Three matches. The setting flowed from `plugin.json` through
178
+ > `ctx.settings.keywords` into the extractor, the extractor
179
+ > counted them, the kernel persisted the contribution, `sm show`
180
+ > reads it back. That's the whole loop.
181
+
182
+ If the tester wants to see it in the UI: ask them to run `sm` in
183
+ the second terminal, open the browser, click `notes/ideas`, and
184
+ spot the new chip in the **left footer** of the card (or the
185
+ bottom-left badge in the inspector). The chip says `🔍 kw 3` (icon
186
+ and label from the manifest's `ui.count`).
187
+
188
+ Mark `authoring-3-edit-setting: done`.
189
+
190
+ ## Step `authoring-4-edit-slot` — change the view-slot (~2 min)
191
+
192
+ > Same contribution, different home. We'll move it from the
193
+ > footer to the top-right corner of the card.
194
+
195
+ The tester edits the extractor source:
196
+
197
+ > Open `.skill-map/plugins/demo-highlight/extractors/demo-highlight-extractor/index.js`.
198
+ > Find the `ui.count.slot` line. Change
199
+ > `'card.footer.left'` to `'card.title.right'`. Save.
200
+
201
+ Re-scan:
202
+
203
+ ```bash
204
+ sm scan
205
+ ```
206
+
207
+ If `sm` is still running, the watcher picks up the file change
208
+ and re-emits contributions live. If not, run the scan manually.
209
+
210
+ Refresh the UI, the chip should now appear next to the **title**
211
+ on the node card instead of the footer.
212
+
213
+ > Notice we did not write any UI code. The slot decides the
214
+ > renderer (`NodeCounter` here, same widget reused across four
215
+ > slots) and the position. You picked a position, the UI did the
216
+ > rest.
217
+
218
+ **Side trip if the tester asks**: `sm plugins slots list` shows
219
+ all 14 slots with one-line descriptions. They are the closed
220
+ catalogue, picking an unknown slot id is rejected at load.
221
+
222
+ Mark `authoring-4-edit-slot: done`.
223
+
224
+ ## Step `authoring-5-doctor-author` — catch a manifest mistake (~2 min)
225
+
226
+ > Last lesson on the manifest. We'll break it on purpose to see
227
+ > how `doctor` reports it.
228
+
229
+ Have the tester change the slot to a value that does not exist:
230
+
231
+ > In the same file, change `'card.title.right'` to
232
+ > `'card.footer.bottom'` (made up). Save.
233
+
234
+ ```bash
235
+ sm plugins doctor
236
+ ```
237
+
238
+ Expected: `doctor` reports a load error or invalid manifest entry
239
+ on `demo-highlight`, pointing at the unknown slot name.
240
+
241
+ > Read the error. The CLI tells you exactly which slot id is not
242
+ > in the catalogue. This is the value of the closed catalogue,
243
+ > the loader catches the typo before any scan happens.
244
+
245
+ Restore the slot to a real value (back to `'card.footer.left'` or
246
+ `'card.title.right'`, the tester's choice) and re-run doctor:
247
+
248
+ ```bash
249
+ sm plugins doctor
250
+ ```
251
+
252
+ Back to clean.
253
+
254
+ Mark `authoring-5-doctor-author: done`.
255
+
256
+ ## Step `authoring-6-upgrade` — `sm plugins upgrade` (~2 min)
257
+
258
+ > One last verb. `sm plugins upgrade` applies catalog migrations
259
+ > to plugin manifests. Today the catalog is at `1.0.0` with zero
260
+ > migrations registered, so the verb is a **no-op**. The point of
261
+ > the step is to know the verb exists and what it does.
262
+
263
+ ```bash
264
+ sm plugins upgrade
265
+ sm plugins upgrade demo-highlight
266
+ ```
267
+
268
+ Expected: both report no migrations to apply.
269
+
270
+ > When the catalog evolves (slot renames, deprecations, setting
271
+ > shape changes), `sm plugins upgrade` is the verb that walks
272
+ > your manifests and rewrites them to the new shape. Without
273
+ > that, every catalog change would force every plugin author to
274
+ > re-author by hand. The structure is in place so future bumps
275
+ > land smoothly.
276
+
277
+ Mark `authoring-6-upgrade: done`.
278
+
279
+ ## Tour wrap-up (fires at the end of `build-and-configure`)
280
+
281
+ > You wrote a plugin. From here:
282
+ >
283
+ > - The manifest (`plugin.json`) is the source of truth, the
284
+ > loader validates it.
285
+ > - Extensions are plain JS with a default export.
286
+ > - Slots pick the renderer and the payload shape, you cannot
287
+ > misalign them.
288
+ > - `sm plugins doctor` is the diagnostic verb, run it after any
289
+ > manifest edit.
290
+ > - `sm plugins upgrade` is the migration verb (no-op today, the
291
+ > structure is ready for future catalog changes).
292
+ >
293
+ > Anything weird worth logging? If not, back to the menu.
294
+
295
+ Mark tour `build-and-configure: done` in `master-state.yml`, update
296
+ the matching harness task, return to the menu in `SKILL.md`.