@skill-map/cli 0.45.0 → 0.46.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 (44) hide show
  1. package/dist/cli/tutorial/sm-master/SKILL.md +29 -29
  2. package/dist/cli/tutorial/sm-master/references/fixture-templates.md +18 -13
  3. package/dist/cli/tutorial/sm-master/references/tour-authoring.md +35 -40
  4. package/dist/cli/tutorial/sm-master/references/tour-plugins.md +32 -32
  5. package/dist/cli/tutorial/sm-master/references/tour-settings.md +156 -75
  6. package/dist/cli/tutorial/sm-tutorial/SKILL.md +3 -3
  7. package/dist/cli.js +757 -452
  8. package/dist/conformance/index.js +4 -1
  9. package/dist/index.js +44 -17
  10. package/dist/kernel/index.d.ts +64 -9
  11. package/dist/kernel/index.js +44 -17
  12. package/dist/migrations/001_initial.sql +7 -0
  13. package/dist/ui/chunk-22CKFAEU.js +1 -0
  14. package/dist/ui/{chunk-I5AX4U2N.js → chunk-3YSNJXGB.js} +1 -1
  15. package/dist/ui/{chunk-MS6B7344.js → chunk-6AP364TB.js} +7 -7
  16. package/dist/ui/{chunk-VGPYYAVI.js → chunk-EPBUSS3I.js} +1 -1
  17. package/dist/ui/{chunk-IYM26L3O.js → chunk-ERUALZOV.js} +1 -1
  18. package/dist/ui/{chunk-5AD5ZV4I.js → chunk-EYBKZOMF.js} +1 -1
  19. package/dist/ui/chunk-F4RIBZ4P.js +1 -0
  20. package/dist/ui/chunk-HAWX5WNM.js +4 -0
  21. package/dist/ui/{chunk-QDUSFOBE.js → chunk-K365TVPA.js} +1 -1
  22. package/dist/ui/{chunk-CBI77N5U.js → chunk-L3JYFPSZ.js} +2 -2
  23. package/dist/ui/chunk-N3RUQDAR.js +1 -0
  24. package/dist/ui/{chunk-A7PRWMQD.js → chunk-P4E74ZOS.js} +1 -1
  25. package/dist/ui/{chunk-X227ITGS.js → chunk-RT7E4S5B.js} +1 -1
  26. package/dist/ui/{chunk-QNTAOR2L.js → chunk-RXQYLVSJ.js} +1 -1
  27. package/dist/ui/{chunk-MFLFIA7C.js → chunk-S32E6ZCZ.js} +1 -1
  28. package/dist/ui/{chunk-T3IVIRRJ.js → chunk-SF4FUT4U.js} +1 -1
  29. package/dist/ui/chunk-VNA3TMIO.js +1 -0
  30. package/dist/ui/{chunk-F7I6KMHX.js → chunk-VW2A6WZ3.js} +1 -1
  31. package/dist/ui/chunk-ZZJ7XWDX.js +1 -0
  32. package/dist/ui/index.html +1 -1
  33. package/dist/ui/main-NF5GO3JR.js +4 -0
  34. package/migrations/001_initial.sql +7 -0
  35. package/package.json +2 -2
  36. package/dist/cli.js.map +0 -1
  37. package/dist/conformance/index.js.map +0 -1
  38. package/dist/index.js.map +0 -1
  39. package/dist/kernel/index.js.map +0 -1
  40. package/dist/ui/chunk-27WQPOXP.js +0 -1
  41. package/dist/ui/chunk-555ST76V.js +0 -1
  42. package/dist/ui/chunk-IUZRAD7S.js +0 -1
  43. package/dist/ui/chunk-PZQHB7GS.js +0 -4
  44. package/dist/ui/main-ERCTR2PR.js +0 -3
@@ -98,13 +98,13 @@ must internalise before talking to the tester:
98
98
  first-mention gloss in addition. The list itself is the gloss.
99
99
 
100
100
  **Emoji preservation**: when the source line is `> <emoji>
101
- **Name**` (e.g. `> 📦 **Built-in bundles**`, `> 🗂️
101
+ **Name**` (e.g. `> 📦 **Built-in plugins**`, `> 🗂️
102
102
  **provider**`), the emoji stands alone as plain text, the name
103
103
  is bold. NEVER wrap the emoji in single asterisks (`*📦*`) or
104
104
  underscores (`_📦_`), NEVER wrap the entire line in italics
105
105
  (`*📦 Name*`), NEVER convert the bold to italic. The emoji
106
106
  must render as a plain emoji glyph, not italicised. Same for
107
- the bundle list (`📦`, `📥`) and the six-kinds list (`🗂️`,
107
+ the plugin list (`📦`, `📥`) and the six-kinds list (`🗂️`,
108
108
  `🔍`, `🩺`, `⚡`, `🎨`, `🎣`).
109
109
  - **The `> ` blockquote prefix on tester messages is
110
110
  host-dependent**, applied only when the host renders blockquotes
@@ -299,9 +299,10 @@ we move on."
299
299
  > before we move on.
300
300
  >
301
301
  > By the way: this advanced tutorial assumes you already went
302
- > through `sm-tutorial` (the onboarding one). If you have not, it
303
- > is the same flow with the `tutorial` keyword from an empty dir.
304
- > Want to keep going here, or pause and run that one first?
302
+ > through `sm-tutorial` (the onboarding one). If you have not, run
303
+ > `sm tutorial` in an empty dir to install its skill, then open
304
+ > your agent there and ask for it, the same way you reached this
305
+ > one. Want to keep going here, or pause and run that one first?
305
306
 
306
307
  ### 2. Verify `sm`
307
308
 
@@ -399,18 +400,15 @@ tester already completed.
399
400
  All set up! Pick your tour, you can come back for the others
400
401
  later.
401
402
 
402
- **1. Built-in plugins** (~13 min)
403
- > The six extension kinds, what comes pre-installed, how to inspect and toggle them.
403
+ **1. Settings** (~10 min)
404
+ > Config layers, the `sm config` verbs, and the active provider lens that decides how the project is read.
404
405
 
405
- **2. Settings and consent** (~5 min)
406
- > Where settings live (`settings.json` vs `settings.local.json`), and the per-user consent gate that controls when `sm` may write `.sm` companion files in this project.
406
+ **2. Built-in plugins** (~13 min)
407
+ > The six extension kinds, what comes pre-installed, how to inspect and toggle them.
407
408
 
408
409
  **3. Build and configure plugins** (~17 min)
409
410
  > Scaffold a plugin with `sm plugins create`, tour what landed, edit a setting and a view-slot, see the contribution appear in the UI, validate with `doctor` and `upgrade`.
410
411
 
411
- **4. I'm done for today**
412
- > Wrap up.
413
-
414
412
  Which one?
415
413
 
416
414
  **Rendering rules** (apply on every render of the menu, first
@@ -435,16 +433,15 @@ time and on subsequent loops):
435
433
  the description visually with two spaces so it stays
436
434
  subordinate to its title.
437
435
  - The trailing "Which one?" stays on its own line, separated
438
- from option 4's description by a blank line.
436
+ from option 3's description by a blank line.
439
437
 
440
438
  Mapping:
441
- - **1** → the tour `plugins-tour`. Its step order is defined in
439
+ - **1** → the tour `settings`. Its step order is defined in
440
+ `master-state.yml.tours.settings.steps`. All step ids are
441
+ `settings-*`, the bodies live in `references/tour-settings.md`.
442
+ - **2** → the tour `plugins-tour`. Its step order is defined in
442
443
  `master-state.yml.tours.plugins-tour.steps`. All step ids are
443
444
  `tour-*`, the bodies live in `references/tour-plugins.md`.
444
- - **2** → the tour `settings-and-consent`. Its step order is
445
- defined in `master-state.yml.tours.settings-and-consent.steps`.
446
- All step ids are `settings-*`, the bodies live in
447
- `references/tour-settings.md`.
448
445
  - **3** → the **merged tour** `build-and-configure`. Its step
449
446
  order is defined in `master-state.yml.tours.build-and-configure.steps`.
450
447
  Walk those step ids in sequence; for each id, find its body in
@@ -455,13 +452,16 @@ Mapping:
455
452
  1..N where N is the length of `steps`, not restarting between
456
453
  the settings-* and authoring-* runs. The two reference files
457
454
  are the step library; the YAML is authoritative for order.
458
- - **4** → jump to §Final wrap-up.
455
+
456
+ There is no "finish" option in the menu: the tester ends the
457
+ session by saying they are done (or by completing every tour),
458
+ which routes to §Final wrap-up.
459
459
 
460
460
  > **Adding a new tour**: append an entry to `master-state.yml.tours`
461
461
  > with its `steps` array, create (or extend) a `references/tour-<id>.md`
462
462
  > step library with the matching step ids, add a new option to the
463
- > menu above (and bump the "I'm done" option number), and add a
464
- > mapping row here. Keep step id prefixes consistent with the file
463
+ > menu above, and add a mapping row here. Keep step id prefixes
464
+ > consistent with the file
465
465
  > name so the dispatch stays mechanical.
466
466
 
467
467
  After a tour finishes, mark it `done` in `master-state.yml`,
@@ -470,12 +470,12 @@ the menu**. Re-render every option using the same layout from
470
470
  §Rendering rules above (plain bold title line + single-level `> `
471
471
  description line, back-to-back, one blank line between options,
472
472
  no outer blockquote), prefixing the title of any completed tour
473
- with `✓ ` (e.g. `**1. ✓ Built-in plugins** (~13 min)`). Skip the
473
+ with `✓ ` (e.g. `**2. ✓ Built-in plugins** (~13 min)`). Skip the
474
474
  intro sentence ("All set up...") and close with:
475
475
 
476
476
  What next?
477
477
 
478
- If they say "I'm done" or pick option 4, jump to §Final wrap-up.
478
+ If they say "I'm done" (or have completed every tour), jump to §Final wrap-up.
479
479
 
480
480
  ## Per-step cycle (inside a tour)
481
481
 
@@ -498,8 +498,8 @@ For every step in the tour:
498
498
  **Numbering rule**: `N` is the 1-based index of the current
499
499
  step inside the picked tour's `steps` array in
500
500
  `master-state.yml`. The count **resets to 1 when the tester
501
- picks a new tour**, so the first step of `plugins-tour` is
502
- "Step 1", the first step of `settings-and-consent` (after
501
+ picks a new tour**, so the first step of `settings` is
502
+ "Step 1", the first step of `plugins-tour` (after
503
503
  returning to the menu and picking option 2) is again "Step 1",
504
504
  and the first step of `build-and-configure` (option 3) is
505
505
  again "Step 1" and runs straight through to "Step 7" without
@@ -578,8 +578,8 @@ orchestrator, the tour file is the lesson.
578
578
 
579
579
  | Menu option | Tour id | Reference file(s) |
580
580
  |-------------|-------------------------|--------------------------------------------------------------------------------------------|
581
- | 1 | `plugins-tour` | `references/tour-plugins.md` |
582
- | 2 | `settings-and-consent` | `references/tour-settings.md` (settings-* steps only) |
581
+ | 1 | `settings` | `references/tour-settings.md` (settings-* steps only) |
582
+ | 2 | `plugins-tour` | `references/tour-plugins.md` |
583
583
  | 3 | `build-and-configure` | both `references/tour-settings.md` (settings-* steps) AND `references/tour-authoring.md` (authoring-* steps), dispatched by step id |
584
584
 
585
585
  Each tour file contains: a short overview, a precondition check
@@ -596,8 +596,8 @@ and re-render the menu.
596
596
 
597
597
  ## Final wrap-up
598
598
 
599
- When the tester picks option 4 or signals they are done, show the
600
- closing block:
599
+ When the tester signals they are done (or has completed every
600
+ tour), show the closing block:
601
601
 
602
602
  > Thanks! That's a wrap.
603
603
  >
@@ -147,8 +147,25 @@ tours:
147
147
  # (e.g. tour-foo.md → steps prefixed `foo-*`). The orchestrator
148
148
  # in SKILL.md walks this list and dispatches each step id to its
149
149
  # reference file.
150
- plugins-tour:
150
+ settings:
151
151
  status: "not_started" # not_started | in_progress | done | declined
152
+ estimated_min: 10
153
+ # Config layers + the `sm config` verbs + the active provider
154
+ # lens. The `.sm` consent gate is covered in the basic
155
+ # sm-tutorial, not repeated here. Step bodies live in
156
+ # tour-settings.md (settings-* ids).
157
+ steps:
158
+ - id: "settings-1-layers"
159
+ title: "The config layers and `sm config list`"
160
+ status: "pending"
161
+ - id: "settings-2-resolve"
162
+ title: "Read, resolve, and set a value with `sm config`"
163
+ status: "pending"
164
+ - id: "settings-3-lens"
165
+ title: "The active provider lens (`activeProvider`)"
166
+ status: "pending"
167
+ plugins-tour:
168
+ status: "not_started"
152
169
  estimated_min: 13
153
170
  # All step bodies live in tour-plugins.md (tour-* ids).
154
171
  steps:
@@ -161,18 +178,6 @@ tours:
161
178
  - id: "tour-3-explore"
162
179
  title: "Explore one extension up close"
163
180
  status: "pending"
164
- settings-and-consent:
165
- status: "not_started"
166
- estimated_min: 5
167
- # Settings + the `.sm` consent gate. Step bodies live in
168
- # tour-settings.md (settings-* ids).
169
- steps:
170
- - id: "settings-1-project"
171
- title: "Project settings: `.skill-map/settings.json`"
172
- status: "pending"
173
- - id: "settings-2-local"
174
- title: "Per-user overrides: `settings.local.json`"
175
- status: "pending"
176
181
  build-and-configure:
177
182
  status: "not_started"
178
183
  estimated_min: 17
@@ -66,14 +66,10 @@ with you. They DO NOT edit anything yet.
66
66
 
67
67
  Then narrate, one file at a time:
68
68
 
69
- > **`plugin.json`**: the manifest
69
+ > **`plugin.json`**: the plugin manifest
70
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.
71
+ > The contract the CLI validates at load. It is deliberately lean,
72
+ > four keys:
77
73
  >
78
74
  > - `version`: starts at `0.1.0`; you bump it yourself, the CLI
79
75
  > does not touch it.
@@ -81,34 +77,37 @@ Then narrate, one file at a time:
81
77
  > - `specCompat` / `catalogCompat`: which `sm` and plugin catalog
82
78
  > version your plugin targets.
83
79
  >
84
- > - `settings`: user-configurable knobs. The scaffold ships
85
- > `keywords`, a `string-list` defaulting to `["TODO", "FIXME"]`.
86
- > Browse other input types with `sm plugins slots list`.
80
+ > - `description`: the one-liner shown in `sm plugins list`.
87
81
  >
88
- > There is no `extensions` field. The kernel discovers each
89
- > extension by walking `<plugin-dir>/<kind>s/<name>/index.js`;
90
- > the folder layout IS the contract.
82
+ > Notice what is NOT here. There is no `id`: the plugin id is the
83
+ > folder name (`demo-highlight`). There is no `extensions` list: the
84
+ > kernel discovers each extension by walking
85
+ > `<plugin-dir>/<kind>s/<name>/index.js`. And there is no `settings`
86
+ > block: settings live per-extension, inside the extractor's
87
+ > `index.js` (you'll see them next). The folder layout IS the
88
+ > contract, that's the "structure-as-truth" idea.
91
89
 
92
90
  > **`extractors/demo-highlight-extractor/index.js`**: the code
93
91
  >
94
92
  > Plain JavaScript with a default export. **Structure-as-truth**:
95
- > the loader derives `id`, `kind`, and `pluginId` from the folder
96
- > path; the manifest itself never declares them.
93
+ > the loader derives the extension `id` and its `pluginId` from the
94
+ > folder path, so the export never repeats them. It does declare its
95
+ > `kind` (`extractor`), which the loader cross-checks against the
96
+ > parent folder (`extractors/`); a mismatch is rejected at load.
97
97
  >
98
98
  > **What the loader reads:**
99
99
  >
100
100
  > - The folder layout tells the loader this is an extractor named
101
101
  > `demo-highlight-extractor` (`extractors/<id>/index.js`).
102
102
  >
103
- > - `ui`: which slots the extension emits to (renamed from
104
- > `viewContributions` with the structure-as-truth refactor). The
105
- > scaffold declares `count`, targeting `card.footer.left` (the
106
- > chip in the bottom-left of every node card). The slot pins
107
- > both the renderer (`NodeCounter`) and the payload shape.
103
+ > - `ui`: which slots the extension emits to. The scaffold declares
104
+ > `count`, targeting `card.footer.left` (the chip in the
105
+ > bottom-left of every node card). The slot pins both the renderer
106
+ > (`NodeCounter`) and the payload shape.
108
107
  >
109
- > - `settings`: per-extension user-configurable knobs (moved here
110
- > from `plugin.json` with the same refactor). Exposed at runtime
111
- > via `ctx.settings.<settingId>`.
108
+ > - `settings`: the per-extension user-configurable knobs, this is
109
+ > where the `keywords` list lives. Exposed at runtime via
110
+ > `ctx.settings.<settingId>`.
112
111
  >
113
112
  > - `extract(ctx)`: the function the kernel runs per node.
114
113
  > `ctx.body` is the markdown body, `ctx.settings` carries what
@@ -158,28 +157,24 @@ content, not configuration). Append at the end:
158
157
  - [ ] XXX revisit naming.
159
158
  ```
160
159
 
161
- Now re-scan and confirm the extractor picks them up:
160
+ Now re-scan so the extractor re-reads its settings and re-counts:
162
161
 
163
162
  ```bash
164
163
  sm scan
165
- sm show notes/ideas.md
166
164
  ```
167
165
 
168
- `sm show` prints the node's persisted contributions. Look for a
169
- `count` contribution with `value: 3` (one match per keyword). The
170
- exact JSON shape is in the body of the `show` output under a
171
- `contributions` key.
172
-
173
- > Three matches. The setting flowed from `plugin.json` through
174
- > `ctx.settings.keywords` into the extractor, the extractor
175
- > counted them, the kernel persisted the contribution, `sm show`
176
- > reads it back. That's the whole loop.
177
-
178
- If the tester wants to see it in the UI: ask them to run `sm` in
179
- the second terminal, open the browser, click `notes/ideas`, and
180
- spot the new chip in the **left footer** of the card (or the
181
- bottom-left badge in the inspector). The chip says `🔍 kw 3` (icon
182
- and label from the manifest's `ui.count`).
166
+ The scan re-emits the contribution with the new count. To actually
167
+ see it we open the UI: `sm show` covers a node's frontmatter, links,
168
+ and issues, but not plugin contributions. Ask the tester to run `sm`
169
+ in the second terminal, open the browser, click `notes/ideas`, and
170
+ spot the chip in the **left footer** of the card (or the bottom-left
171
+ badge in the inspector). It reads `🔍 kw 3`, one match per keyword,
172
+ the icon and label come from the manifest's `ui.count`.
173
+
174
+ > Three matches. The setting flowed from the extension's `settings`
175
+ > through `ctx.settings.keywords` into the extractor, the extractor
176
+ > counted them, the kernel persisted the contribution, and the UI
177
+ > rendered it. That's the whole loop.
183
178
 
184
179
  Mark `authoring-3-edit-setting: done`.
185
180
 
@@ -1,9 +1,9 @@
1
1
  # Tour: plugins-tour
2
2
 
3
3
  Guided tour of the **built-in plugins** that ship with `sm`. Three
4
- steps: a quick mental model of what bundles are plus a peek at
4
+ steps: a quick mental model of what plugins are plus a peek at
5
5
  the catalogue, then the six extension kinds rounded off by opening
6
- one bundle to see them in the wild, and finally a deeper drill
6
+ one plugin to see them in the wild, and finally a deeper drill
7
7
  into a single extension (detail view, diagnostic, disable/enable
8
8
  toggle). By the end the tester has the mental model and knows
9
9
  which verbs reach which surface.
@@ -22,41 +22,40 @@ restore the files.") and stop.
22
22
 
23
23
  ## Step `tour-1-intro` — how plugins work (~4 min)
24
24
 
25
- **Context**: A short tour of what a plugin is, how they're
26
- packaged into bundles, and a peek at the five bundles that ship
25
+ **Context**: A short tour of what a plugin is, how it groups
26
+ extensions, and a peek at the five plugins that ship
27
27
  pre-installed.
28
28
 
29
- > Plugins are how skill-map gets extended. A **plugin** groups one
30
- > or more **extensions**, the actual code units that run inside
31
- > the kernel. So when we say "skill-map has a plugin for Claude",
32
- > what we really mean is "there is a plugin called `claude` that
33
- > contains one extension (a provider) which knows how to walk
34
- > `.claude/`".
29
+ > Plugins are how skill-map gets extended. A **plugin** is the
30
+ > deployable unit: one directory with a `plugin.json` manifest and
31
+ > the extension code. It groups one or more **extensions**, the
32
+ > actual code units that run inside the kernel. So when we say
33
+ > "skill-map has a plugin for Claude", what we really mean is
34
+ > "there is a plugin called `claude` that contains one extension
35
+ > (a provider) which knows how to walk `.claude/`".
35
36
  >
36
- > Plugins ship as **bundles**. A bundle is the deployable unit,
37
- > one directory with a `plugin.json` manifest and the extension
38
- > code. Two ways they reach your project:
37
+ > Two ways plugins reach your project:
39
38
  >
40
- > 📦 **Built-in bundles**
39
+ > 📦 **Built-in plugins**
41
40
  > Travel inside the CLI itself. Available the moment you
42
41
  > `npm install -g @skill-map/cli`.
43
42
  >
44
- > 📥 **Drop-in bundles**
43
+ > 📥 **Drop-in plugins**
45
44
  > You (your company, or someone else) drop them by hand under
46
45
  > `<cwd>/.skill-map/plugins/`. The directory lives inside the
47
- > project, so a bundle committed here travels with the repo
46
+ > project, so a plugin committed here travels with the repo
48
47
  > and the rest of the team picks it up on the next pull.
49
48
 
50
49
  > Now let's look at what's actually installed. `sm plugins list`
51
- > shows every bundle the CLI shipped with. Run it in your second
50
+ > shows every plugin the CLI shipped with. Run it in your second
52
51
  > terminal:
53
52
 
54
53
  ```bash
55
54
  sm plugins list
56
55
  ```
57
56
 
58
- > There are the five bundles. The next step zooms into the six
59
- > kinds of extension that bundles can carry, you'll see at least
57
+ > There are the five plugins. The next step zooms into the six
58
+ > kinds of extension that a plugin can carry, you'll see at least
60
59
  > one of each living inside `core`.
61
60
 
62
61
  Mark `tour-1-intro: done`.
@@ -101,7 +100,7 @@ Mark `tour-1-intro: done`.
101
100
  > newer skill-map is available on npm.
102
101
  > Example: `update-check`.
103
102
  >
104
- > Putting it together: a **bundle** packages one or more
103
+ > Putting it together: a **plugin** packages one or more
105
104
  > **extensions**, each extension has a **kind**, the kind decides
106
105
  > where it plugs into the kernel.
107
106
  >
@@ -111,7 +110,7 @@ Mark `tour-1-intro: done`.
111
110
  > from there. CLI and UI use the same store, so a change in one
112
111
  > is reflected in the other.
113
112
 
114
- > Now let's see those six kinds inside a real bundle. Open `core`
113
+ > Now let's see those six kinds inside a real plugin. Open `core`
115
114
  > in your second terminal:
116
115
 
117
116
  ```bash
@@ -121,7 +120,7 @@ sm plugins show core
121
120
  Expected: the 28 extensions grouped by kind, each row showing its
122
121
  kind and qualified id (e.g. `extractor core/markdown-link`). You
123
122
  can spot at least one of each of the six kinds you just read about,
124
- all packed into a single bundle.
123
+ all packed into a single plugin.
125
124
 
126
125
  Mark `tour-2-kinds: done`.
127
126
 
@@ -139,8 +138,9 @@ the change persists.
139
138
  sm plugins show core/external-url-counter
140
139
  ```
141
140
 
142
- Expected: a focused detail block for that one extension (header,
143
- Kind, Version, Stability, Description, Preconditions, Entry).
141
+ Expected: a focused detail block for that one extension, the header
142
+ line (`✓ core/external-url-counter built-in`) plus its Kind
143
+ (`extractor`) and Description.
144
144
 
145
145
  > Now run the diagnostic. The `doctor` verb reports every plugin
146
146
  > and extension status in one go: enabled, disabled, load errors,
@@ -160,15 +160,15 @@ spec-compatibility mismatch, `doctor` is the verb that flags it.
160
160
 
161
161
  ```bash
162
162
  sm plugins disable core/external-url-counter
163
- sm plugins doctor
163
+ sm plugins show core
164
164
  sm plugins enable core/external-url-counter
165
- sm plugins doctor
165
+ sm plugins show core
166
166
  ```
167
167
 
168
- Expected: between the two `doctor` calls, the
169
- `core/external-url-counter` row flips from `enabled` to
170
- `disabled` and back. The change persists in the project DB; if
171
- you restarted `sm`, the disabled state would still be there.
168
+ Expected: between the two `show core` calls, the
169
+ `core/external-url-counter` row flips its marker from `✓` (enabled)
170
+ to `✕` (disabled) and back. The change persists in the project DB;
171
+ if you restarted `sm`, the disabled state would still be there.
172
172
 
173
173
  Mark `tour-3-explore: done`.
174
174
 
@@ -176,8 +176,8 @@ Mark `tour-3-explore: done`.
176
176
 
177
177
  > All set. You now know:
178
178
  >
179
- > - What plugins, extensions, bundles, and the six kinds are.
180
- > - Five bundles ship pre-installed (`claude`, `antigravity`,
179
+ > - What plugins, extensions, and the six kinds are.
180
+ > - Five plugins ship pre-installed (`claude`, `antigravity`,
181
181
  > `openai`, `agent-skills`, `core`).
182
182
  > - How to list, inspect, diagnose, and toggle extensions from
183
183
  > the CLI (and the same lives in the UI).