@skill-map/cli 0.24.4 → 0.25.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.
@@ -30,11 +30,13 @@ optional second phase (~20-30 min) covering the rest of the CLI.
30
30
  > "short path", "long path", "route", "phase 1" / "phase 2", or
31
31
  > "let's start the short one" in messages to the tester. The internal
32
32
  > split exists so YOU know what comes next; for the tester you only
33
- > talk about the current step and, at the end of step 4, offer
34
- > "if you want, we can keep going deeper" without labelling it.
33
+ > talk about the current step and, at the end of step 7 (wrap-up),
34
+ > offer "if you want, we can keep going deeper" without labelling it.
35
35
 
36
36
  ## Tone
37
37
 
38
+ ### Language and register
39
+
38
40
  - Spanish (when the tester's language is Spanish): casual, neutral,
39
41
  NOT rioplatense. Short sentences. No unnecessary jargon. Use
40
42
  `tú` form, not `vos` — `puedes`, `mira`, `prueba`, `crea`, NOT
@@ -45,12 +47,17 @@ optional second phase (~20-30 min) covering the rest of the CLI.
45
47
  invent a stand-in pronoun.
46
48
  - Don't be condescending. If they ask for something that will
47
49
  break, say so directly.
50
+ ### Vocabulary translation (Spanish)
51
+
48
52
  - **Translate product vocabulary into Spanish, do NOT leave English
49
53
  loanwords embedded in Spanish prose.** When rendering tester-facing
50
54
  copy in Spanish, use these equivalences:
51
55
  - `kind` → `tipo` (skill-map talks about node "kinds"; in
52
56
  Spanish output the word is `tipo` / `tipos`, NOT "kinds").
53
- - `connector` → `conector`.
57
+ - `connector` / `edge` → `conector` (**NEVER** `arista`, even
58
+ though it's the common Spanish translation for graph edge;
59
+ skill-map's house word is `conector` everywhere — UI, docs,
60
+ CLI, conversation).
54
61
  - `watcher` → `observador` (or rephrase: "skill-map sigue tus
55
62
  cambios" instead of "el watcher detecta...").
56
63
  - `scan` (verb) → `escanear`; `scan` (noun) → `escaneo`.
@@ -64,6 +71,8 @@ optional second phase (~20-30 min) covering the rest of the CLI.
64
71
  "el watcher detectó el cambio", "vamos a hacer un scan ahora".
65
72
  Correct: "aparecen los otros cuatro tipos", "skill-map detectó
66
73
  el cambio", "vamos a escanear ahora".
74
+ ### Silence during backstage work
75
+
67
76
  - **Stay silent during backstage work.** Do NOT narrate operational
68
77
  steps you're about to take or internal checks. Forbidden patterns
69
78
  include "Voy a verificar primero que el directorio esté listo",
@@ -76,6 +85,8 @@ optional second phase (~20-30 min) covering the rest of the CLI.
76
85
  do something, (b) a sub-step landed and you want a confirm, or
77
86
  (c) something failed and they need to know. Between those
78
87
  moments, work without commentary.
88
+ ### Glossing technical terms
89
+
79
90
  - **Explain technical terms in parentheses the first time you
80
91
  mention them in a tester-facing blockquote.** Assume the tester
81
92
  is non-technical; many will not know what `frontmatter`,
@@ -87,6 +98,8 @@ optional second phase (~20-30 min) covering the rest of the CLI.
87
98
  Internal narration in this SKILL.md does not need the gloss;
88
99
  this rule is purely about what the agent says to the tester.
89
100
  After the first mention in a session, the bare term is fine.
101
+ ### Tester-facing Markdown (blockquotes vs code blocks)
102
+
90
103
  - **Messages addressed to the tester are rendered as Markdown
91
104
  blockquotes** (lines prefixed with `> `): instructions, narrative
92
105
  context, numbered choice menus, prompts, confirmations. The
@@ -96,6 +109,8 @@ optional second phase (~20-30 min) covering the rest of the CLI.
96
109
  plain code blocks so the copy works cleanly. If a step has both
97
110
  narrative and a command, write the narrative in a blockquote
98
111
  *above* the bare code block (not inside it).
112
+ ### Language mirroring + fixture content
113
+
99
114
  - **Mirror the tester's language**: if the first message they wrote
100
115
  was in Spanish, run the conversation in neutral Spanish (per
101
116
  the Tone bullets above — `tú` form, no rioplatense); if in
@@ -129,48 +144,47 @@ optional second phase (~20-30 min) covering the rest of the CLI.
129
144
  demo needs this so the watcher has something to react to).
130
145
  - Read files to verify what the tester modified.
131
146
  - Everything else is run by the tester.
132
- - **Configuration files have two-mode access**: backstage setup
133
- vs teach moment.
134
- - **Backstage setup (you DO edit)**: right after `sm init` in
135
- Step 1, you append the tutorial's internal entries
136
- (`sm-tutorial.md`, `findings.md`, `tutorial-state.yml`,
137
- `sm-tutorial-report.md`, etc.) to the freshly created
138
- `.skillmapignore` with `Edit`. That is plumbing — the
139
- tester does not need to learn that the tutorial hides its
140
- own scaffolding from the scan. Do it silently and move on.
141
- - **Teach moment (you DO NOT edit)**: any time the SKILL
142
- calls for a change to `.skillmapignore`,
143
- `.skill-map/settings.json`,
144
- `.skill-map/settings.local.json`, or `.gitignore` AS PART
145
- OF A LESSON (e.g. Step 2.5 hides a
146
- private node by appending a pattern), you describe the
147
- edit in a blockquote and the tester applies it in their
148
- own editor. The pedagogical point is that those files
149
- belong to the user they need to internalise where they
150
- live and how to change them. Doing it for them in a
151
- teach moment defeats the lesson.
152
- 2. **After every command block, stop and wait.** The tester pastes
147
+ 2. **Configuration files have two-mode access**: backstage setup
148
+ vs teach moment.
149
+ - **Backstage setup (you DO edit)**: right after `sm init` in
150
+ Step 1, you append the tutorial's internal entries
151
+ (`sm-tutorial.md`, `findings.md`, `tutorial-state.yml`,
152
+ `sm-tutorial-report.md`, etc.) to the freshly created
153
+ `.skillmapignore` with `Edit`. That is plumbing — the
154
+ tester does not need to learn that the tutorial hides its
155
+ own scaffolding from the scan. Do it silently and move on.
156
+ - **Teach moment (you DO NOT edit)**: any time the SKILL
157
+ calls for a change to `.skillmapignore`,
158
+ `.skill-map/settings.json`,
159
+ `.skill-map/settings.local.json`, or `.gitignore` AS PART
160
+ OF A LESSON (e.g. Step 6 hides a private node by appending
161
+ a pattern), you describe the edit in a blockquote and the
162
+ tester applies it in their own editor. The pedagogical point
163
+ is that those files belong to the user — they need to
164
+ internalise where they live and how to change them. Doing it
165
+ for them in a teach moment defeats the lesson.
166
+ 3. **After every command block, stop and wait.** The tester pastes
153
167
  the output or replies "OK" / "done". Only then do you advance.
154
- 3. **Persist progress after every step.** Update
168
+ 4. **Persist progress after every step.** Update
155
169
  `tutorial-state.yml` with `done` / `failed` / `skipped` and a
156
170
  timestamp.
157
- 4. **If the tester reports anything weird**, offer to record it in
171
+ 5. **If the tester reports anything weird**, offer to record it in
158
172
  `findings.md` (in the cwd). Those are the bugs the team will read.
159
- 5. **One step at a time.** Finish, ask if they want to continue, do
173
+ 6. **One step at a time.** Finish, ask if they want to continue, do
160
174
  the next one.
161
- 6. **If `tutorial-state.yml` already exists in the cwd** when invoked,
175
+ 7. **If `tutorial-state.yml` already exists in the cwd** when invoked,
162
176
  do not overwrite anything. Read it, show progress, offer to
163
177
  *continue* or *start over* (the latter requires explicit
164
178
  confirmation and wipes the tutorial content).
165
- 7. **Mirror the tester's language**: see §Tone for the language rules
166
- (neutral Spanish `tú` form, NOT rioplatense — when the tester
167
- writes in Spanish; plain English otherwise). Fixture human prose
168
- also follows the tester's language, per the Tone bullet on fixture
169
- content. Internal instructions in this SKILL.md stay in English
170
- so any maintainer can read them. Blockquote literals in this
171
- document are the messages you actually say to the tester —
172
- translate them on the fly. Code blocks below them stay as bare
173
- ` ```bash ` fences (no `> ` prefix) so the tester can copy cleanly.
179
+ 8. **Mirror the tester's language** per §Tone. Internal narration
180
+ and code-block fences stay English regardless.
181
+ 9. **Never modify files outside the tutorial cwd.** Stay scoped to
182
+ the directory verified in pre-flight.
183
+ 10. **Never ask the tester to `cd` outside the tutorial cwd.** All
184
+ command blocks assume the second terminal is anchored to the
185
+ tutorial folder.
186
+ 11. **Never skip the level question when entering the deep-dive.**
187
+ The level drives modulation of every Step 8+ instruction.
174
188
 
175
189
  ## Pre-flight
176
190
 
@@ -192,6 +206,9 @@ ls -A
192
206
  user content — they're internal infrastructure of the skill itself):
193
207
 
194
208
  - `.claude` — skills/agents infrastructure.
209
+ - `.tmp` — Claude Code scratch directory; created automatically
210
+ when the harness starts, has nothing to do with the tester.
211
+ Ignore whether it exists or not.
195
212
  - `SKILL.md` — a loose copy of the skill.
196
213
  - `sm-tutorial.md` — the skill copy materialised by `sm tutorial`.
197
214
  - `tutorial-state.yml` — resume mode (see §Resume / restart).
@@ -306,12 +323,12 @@ later when they're relevant. Keep it to a single short sentence:
306
323
  Then proceed straight to the writes below — no pause, no "ready?"
307
324
  prompt.
308
325
 
309
- The tutorial builds the graph **progressively** in five sub-steps during
310
- Step 2 (Live UI). Right now, in pre-flight, you only create **one
311
- file** — a single agent — so the tester's first look at the UI
312
- shows exactly one node. The other four kinds (skill, command, hook,
313
- note) and the connectors between all five are added later, one
314
- sub-step at a time.
326
+ The tutorial builds the graph **progressively** across Steps 2-6
327
+ (the live UI block). Right now, in pre-flight, you only create
328
+ **one file** — a single agent — so the tester's first look at the
329
+ UI shows exactly one node. The other four kinds (skill, command,
330
+ hook, note) and the connectors between all five are added later,
331
+ one step at a time.
315
332
 
316
333
  ```
317
334
  <cwd>/
@@ -323,7 +340,7 @@ sub-step at a time.
323
340
  ```
324
341
 
325
342
  `.claude/agents/demo-agent.md` (no cross-fixture links yet — those
326
- arrive in Step 2.4):
343
+ arrive in Step 5):
327
344
  ```markdown
328
345
  ---
329
346
  name: demo-agent
@@ -333,8 +350,6 @@ description: |
333
350
  Live UI step.
334
351
  tools: [Read, Bash]
335
352
  model: sonnet
336
- metadata:
337
- version: "1.0.0"
338
353
  ---
339
354
 
340
355
  # demo-agent
@@ -384,36 +399,48 @@ short_steps:
384
399
  - id: "1-init"
385
400
  title: "sm init"
386
401
  status: "pending"
387
- - id: "2-ui-live"
388
- title: "⭐ Live UI: bare sm + live edits by the agent"
402
+ - id: "2-live-boot"
403
+ title: "⭐ Live UI: the lone agent"
404
+ status: "pending"
405
+ - id: "3-live-kinds"
406
+ title: "⭐ Live UI: the other four kinds appear"
407
+ status: "pending"
408
+ - id: "4-live-edit"
409
+ title: "⭐ Live UI: your first edit"
410
+ status: "pending"
411
+ - id: "5-live-connectors"
412
+ title: "⭐ Live UI: the connectors light up"
389
413
  status: "pending"
390
- - id: "3-handoff"
414
+ - id: "6-live-ignore"
415
+ title: "⭐ Live UI: silence via .skillmapignore"
416
+ status: "pending"
417
+ - id: "7-handoff"
391
418
  title: "Wrap-up of the demo and offer to keep going"
392
419
  status: "pending"
393
420
  long_steps:
394
- - id: "4-tester-edits"
421
+ - id: "8-tester-edits"
395
422
  title: "Tester edits live (extends the UI demo)"
396
423
  status: "pending"
397
- - id: "5-cli-browse"
424
+ - id: "9-cli-browse"
398
425
  title: "Browse CLI: list / show / check"
399
426
  status: "pending"
400
427
  verbs: ["sm list", "sm show", "sm check"]
401
- - id: "6-ascii"
428
+ - id: "10-ascii"
402
429
  title: "ASCII: graph + export"
403
430
  status: "pending"
404
431
  verbs: ["sm graph", "sm export"]
405
- - id: "7-issues"
432
+ - id: "11-issues"
406
433
  title: "Issues: broken refs"
407
434
  status: "pending"
408
435
  verbs: ["sm check", "sm check --analyzers broken-ref",
409
436
  "sm check --json"]
410
- - id: "8-plugins"
437
+ - id: "12-plugins"
411
438
  title: "Plugins"
412
439
  status: "pending"
413
440
  verbs: ["sm plugins list", "sm plugins show",
414
441
  "sm plugins doctor", "sm plugins enable",
415
442
  "sm plugins disable"]
416
- - id: "9-annotations"
443
+ - id: "13-annotations"
417
444
  title: "Annotations and the .sm consent prompt"
418
445
  status: "pending"
419
446
  verbs: ["sm sidecar annotate"]
@@ -422,6 +449,14 @@ findings_file: "./findings.md"
422
449
 
423
450
  ## Per-step cycle
424
451
 
452
+ Before Step 1's announcement, call `TaskCreate` once with one task
453
+ per entry in `tutorial-state.yml` (`short_steps`, plus `long_steps`
454
+ if the deep-dive is accepted later). Update each task to
455
+ `in_progress` when its block begins and `completed` when it ends —
456
+ the harness task list gives the tester a live "where am I" view
457
+ during the session, while `tutorial-state.yml` remains the
458
+ cross-session source of truth for pause/resume.
459
+
425
460
  For every step in the tutorial:
426
461
 
427
462
  1. **Announcement**: "Step N: `<title>`. ~M minutes." One sentence
@@ -478,32 +513,14 @@ dump.sql
478
513
 
479
514
  Mark `1-init: done`.
480
515
 
481
- ### Step 2 — ⭐ Live UI (4-5 min)
516
+ ### Step 2 — ⭐ Live UI: the lone agent (~1 min)
482
517
 
483
518
  **Context**: typing `sm` alone (no arguments) in an initialised dir
484
519
  starts the UI server with the watcher built in. One process, one
485
520
  terminal: it boots the server, scans the `.md` files, detects
486
- changes, and pushes events over WebSocket to the live UI.
487
-
488
- This step has **five sub-steps** (2.1 through 2.5), each one driven
489
- by you editing files while the server stays up — except Step 2.3,
490
- where the tester takes the keyboard for the first time.
491
-
492
- 1. **Step 2.1 (boot)** — one node alone (the agent).
493
- 2. **Step 2.2 (kinds)** — the four other kinds appear as new nodes,
494
- still unconnected.
495
- 3. **Step 2.3 (your first edit)** — the **tester** edits the
496
- `description` of the agent's `.md` and watches the card
497
- refresh in the graph.
498
- 4. **Step 2.4 (connectors)** — the connectors light up between all
499
- five nodes.
500
- 5. **Step 2.5 (ignore)** — a private file appears, then disappears
501
- the moment a pattern is added to `.skillmapignore`.
502
-
503
- The pedagogical arc: a single dot → a constellation of dots →
504
- your own edit lands → graph → a graph that respects the user's
505
- ignore list. Each sub-step stops at a confirm prompt before you do
506
- the next.
521
+ changes, and pushes events over WebSocket to the live UI. The next
522
+ five steps (2-6) all run against the same `sm` session — you boot
523
+ it here and keep it alive through Step 6.
507
524
 
508
525
  **Command** (one terminal):
509
526
 
@@ -511,8 +528,8 @@ the next.
511
528
  sm
512
529
  ```
513
530
 
514
- Before Step 2.1, ask the tester to set up a **side-by-side view** so
515
- they can watch the magic happen without alt-tabbing every sub-step.
531
+ Before launching, ask the tester to set up a **side-by-side view** so
532
+ they can watch the magic happen without alt-tabbing every step.
516
533
  Tell the tester:
517
534
 
518
535
  > Now arrange your screen so the **browser** (where the graph will
@@ -534,11 +551,7 @@ truth (it logs the bound `http://host:port` after listen):
534
551
  > UI is listening — copy that link and open it in the browser you
535
552
  > just arranged. Tell me when you see the page load.
536
553
 
537
- Wait for confirmation that the page loaded.
538
-
539
- #### Step 2.1 — the lone agent
540
-
541
- Tell the tester:
554
+ Wait for confirmation that the page loaded. Then tell the tester:
542
555
 
543
556
  > You'll see exactly **one node** in the graph: `demo-agent` (kind
544
557
  > `agent`). That's our starting point.
@@ -552,9 +565,9 @@ Tell the tester:
552
565
  >
553
566
  > Did the node show up?
554
567
 
555
- Wait for confirmation.
568
+ Wait for confirmation. Mark `2-live-boot: done`.
556
569
 
557
- #### Step 2.2 — the other four kinds appear (the magic)
570
+ ### Step 3Live UI: the other four kinds appear (~1 min)
558
571
 
559
572
  Leave the browser open and the terminal with `sm` running. You
560
573
  create the four missing kinds **without any cross-fixture links**
@@ -579,8 +592,6 @@ Create these four files (with `Write`), exactly in this order:
579
592
  - name: report
580
593
  type: string
581
594
  description: Markdown summary.
582
- metadata:
583
- version: "1.0.0"
584
595
  ---
585
596
 
586
597
  # demo-skill
@@ -607,8 +618,6 @@ Create these four files (with `Write`), exactly in this order:
607
618
  type: path
608
619
  description: File the command will hand off to the skill.
609
620
  required: true
610
- metadata:
611
- version: "1.0.0"
612
621
  ---
613
622
 
614
623
  # demo-command
@@ -632,8 +641,6 @@ Create these four files (with `Write`), exactly in this order:
632
641
  event: SubagentStop
633
642
  blocking: false
634
643
  idempotent: true
635
- metadata:
636
- version: "1.0.0"
637
644
  ---
638
645
 
639
646
  # demo-hook
@@ -653,8 +660,6 @@ Create these four files (with `Write`), exactly in this order:
653
660
  hub between skill / agent / command / hook in the next
654
661
  sub-step.
655
662
  tags: [notes, demo]
656
- metadata:
657
- version: "1.0.0"
658
663
  ---
659
664
 
660
665
  # Pending
@@ -670,15 +675,15 @@ Tell the tester:
670
675
  >
671
676
  > Did the four appear? Confirm so we can wire them up.
672
677
 
673
- Wait for confirmation.
678
+ Wait for confirmation. Mark `3-live-kinds: done`.
674
679
 
675
- #### Step 2.3 — your first edit
680
+ ### Step 4Live UI: your first edit (~1 min)
676
681
 
677
682
  Up to here you've been watching the agent write files. Now hand
678
683
  the keyboard over: the lesson is that the watcher reacts to
679
684
  **any** `.md` edit under the cwd, not just to files the agent
680
685
  authors. After this beat, the tester has the muscle memory for
681
- "save → graph updates", which Step 2.5 (`.skillmapignore`) reuses
686
+ "save → graph updates", which Step 6 (`.skillmapignore`) reuses
682
687
  verbatim.
683
688
 
684
689
  Tell the tester:
@@ -704,9 +709,9 @@ Tell the tester:
704
709
 
705
710
  Wait for confirmation. You MAY use `Read` on the file afterwards
706
711
  to verify the change landed (read-only, allowed under Inviolable
707
- rule #1) before moving on.
712
+ rule #1) before moving on. Mark `4-live-edit: done`.
708
713
 
709
- #### Step 2.4 — the connectors light up
714
+ ### Step 5Live UI: the connectors light up (~1 min)
710
715
 
711
716
  Now you edit the existing files to add the cross-fixture links —
712
717
  each one becomes a connector in the graph. Apply with `Edit` (do
@@ -760,22 +765,21 @@ Tell the tester:
760
765
  > Confirm. If a connector is missing, refresh the browser and tell
761
766
  > me.
762
767
 
763
- Wait for confirmation. **Do NOT move on to Step 2.5** until the
764
- connectors are confirmed visible — Step 2.5 reuses the same live UI
765
- session.
768
+ Wait for confirmation. **Do NOT move on to Step 6** until the
769
+ connectors are confirmed visible — Step 6 reuses the same live UI
770
+ session. Mark `5-live-connectors: done`.
766
771
 
767
- #### Step 2.5 — silence a private file via `.skillmapignore`
772
+ ### Step 6Live UI: silence a private file via `.skillmapignore` (~2 min)
768
773
 
769
- The first four sub-steps showed the watcher picking up new files and
770
- edits (yours and theirs). Step 2.5 flips the direction: a file the
771
- tester DOES NOT want
772
- in the graph (a draft, a scratch file, a secret) gets hidden by a
773
- single line in `.skillmapignore`. Same live mechanism — no restart.
774
+ Steps 2-5 showed the watcher picking up new files and edits (yours
775
+ and theirs). Step 6 flips the direction: a file the tester DOES NOT
776
+ want in the graph (a draft, a scratch file, a secret) gets hidden by
777
+ a single line in `.skillmapignore`. Same live mechanism no restart.
774
778
 
775
779
  `sm init` already wrote a starter `.skillmapignore` at the scope
776
- root. The flow has three sub-steps:
780
+ root. The flow has three beats:
777
781
 
778
- **Step 2.5.1 — you create one new fixture file (the agent does this).**
782
+ **Beat 1 — you create one new fixture file (the agent does this).**
779
783
 
780
784
  `Write` `notes/private-credentials.md` — kind `note`, simulates a
781
785
  file the tester would never want surfacing publicly:
@@ -787,8 +791,6 @@ description: |
787
791
  Personal API tokens — exists in the repo but should not show
788
792
  up in the skill-map graph. Demonstrates the .skillmapignore
789
793
  flow.
790
- metadata:
791
- version: "0.0.1"
792
794
  ---
793
795
 
794
796
  # Private
@@ -800,7 +802,7 @@ Confirm the file appears in the graph as a sixth node
800
802
  (`notes/private-credentials`). The watcher sees it like any
801
803
  other `.md` — that's the point of the demo.
802
804
 
803
- **Step 2.5.2 — you show the project structure (the agent does this).**
805
+ **Beat 2 — you show the project structure (the agent does this).**
804
806
 
805
807
  Before asking the tester to touch `.skillmapignore`, give them a
806
808
  mental map of the folder so they know where the file lives and
@@ -833,9 +835,9 @@ Adjust the actual tree shown to whatever `ls -la` returns — the
833
835
  goal is "tester recognises their own filesystem", not a copy of
834
836
  the snippet above.
835
837
 
836
- **Step 2.5.3 — the tester edits `.skillmapignore` (NOT the agent).**
838
+ **Beat 3 — the tester edits `.skillmapignore` (NOT the agent).**
837
839
 
838
- Per Inviolable rule #1, you DO NOT touch `.skillmapignore` with
840
+ Per Inviolable rule #2, the agent does NOT touch `.skillmapignore` with
839
841
  your `Edit` tool. Tell the tester to do it from their editor:
840
842
 
841
843
  > Last step. Open `.skillmapignore` (it's at the cwd root) in
@@ -865,9 +867,9 @@ verify the appended pattern landed correctly (in case
865
867
  allowed. Once confirmed, ask them to stop the server with
866
868
  **Ctrl+C** in the terminal before continuing.
867
869
 
868
- Mark `2-ui-live: done`.
870
+ Mark `6-live-ignore: done`.
869
871
 
870
- ### Step 3 — Wrap-up of the demo and offer to keep going (30 s)
872
+ ### Step 7 — Wrap-up of the demo and offer to keep going (30 s)
871
873
 
872
874
  > All set! That's the heart of skill-map: you edit a `.md` and the
873
875
  > UI sees it instantly. In **~10 minutes** you've already seen the
@@ -923,10 +925,12 @@ Save into `tester.level` and modulate:
923
925
  - **Level 3**: dense blocks, flags included, no explanations of
924
926
  basic concepts.
925
927
 
926
- ### Step 4 — Tester edits live (~3 min)
928
+ ### Step 8 — Tester edits live (~3 min)
927
929
 
928
- **Context**: in the demo you edited. Now it's their turn to confirm
929
- they can do it from their editor.
930
+ **Context**: Step 4 had the tester edit a scalar (`description`)
931
+ and watch the inspector card refresh. Step 8 raises the bar: edit
932
+ a Markdown link and watch the GRAPH TOPOLOGY change (a connector
933
+ disappears). Same watcher, different surface.
930
934
 
931
935
  This step needs the server running. **Check first** before asking
932
936
  them to launch it: many testers leave it running from Step 2 and
@@ -947,7 +951,7 @@ You verify by reading `.claude/skills/demo-skill/SKILL.md` to confirm
947
951
  the change was applied. Once they confirm, ask them to **Ctrl+C**
948
952
  the server.
949
953
 
950
- ### Step 5 — Browse CLI: list / show / check (~3 min)
954
+ ### Step 9 — Browse CLI: list / show / check (~3 min)
951
955
 
952
956
  ```bash
953
957
  sm list
@@ -961,14 +965,13 @@ sm check
961
965
  Expected: you see the 5 fixture nodes listed with their kind:
962
966
  `demo-skill` (skill), `demo-agent` (agent), `demo-command`
963
967
  (command), and `demo-hook` + `notes/todo` (both `markdown` —
964
- the catch-all per Step 2.2). `check` reads the persisted
968
+ the catch-all per Step 3). `check` reads the persisted
965
969
  `scan_issues` table — it does NOT re-walk the filesystem. The
966
- fixture is clean (the watcher in Step 2 captured the latest
967
- state before Ctrl+C), so the verb prints `✓ No issues`. We will
968
- plant one in Step 7 and watch the rule catch it after a fresh
969
- `sm scan`.
970
+ fixture is clean (Steps 2-6 captured the latest state before
971
+ Ctrl+C), so the verb prints `✓ No issues`. We will plant one in
972
+ Step 11 and watch the rule catch it after a fresh `sm scan`.
970
973
 
971
- ### Step 6 — ASCII: graph + export (~3 min)
974
+ ### Step 10 — ASCII: graph + export (~3 min)
972
975
 
973
976
  ```bash
974
977
  sm graph
@@ -986,7 +989,7 @@ within a key, AND across keys) and a `--format` of `md` or
986
989
  segment, `**` spans segments) so `path=notes/**` cleanly
987
990
  captures the notes folder regardless of the catch-all kind.
988
991
 
989
- ### Step 7 — Issues: broken refs (~3 min)
992
+ ### Step 11 — Issues: broken refs (~3 min)
990
993
 
991
994
  `broken-ref` is one of the deterministic rules `sm check` runs.
992
995
  We'll plant one and watch it surface — that's the easiest way to
@@ -999,13 +1002,9 @@ Ask the tester to **append one bullet** to `notes/todo.md`:
999
1002
  - [ ] Document the [flow diagram](./missing-page.md).
1000
1003
  ```
1001
1004
 
1002
- `./missing-page.md` deliberately doesn't exist. Save the file.
1003
-
1004
- The watcher was stopped at the end of Step 4, so the persisted
1005
- `scan_issues` table still reflects the pre-edit state. `sm check`
1006
- reads from that table without re-walking, so a bare `sm check`
1007
- right now would still print `✓ No issues`. Run `sm scan` first
1008
- to refresh the snapshot:
1005
+ `./missing-page.md` deliberately doesn't exist. Save the file,
1006
+ then run `sm scan` first to refresh the snapshot before
1007
+ checking:
1009
1008
 
1010
1009
  ```bash
1011
1010
  sm scan
@@ -1021,65 +1020,56 @@ emits the structured payload (useful for CI / scripting). When
1021
1020
  done, the tester can leave the bullet in place or delete it — the
1022
1021
  rest of the deep-dive doesn't depend on it.
1023
1022
 
1024
- > **Heads up about scope** (mention only if the tester asks):
1023
+ If the tester asks about `sm orphans` vs `sm check`, see
1024
+ §Scope clarifications.
1025
+
1026
+ ### Step 12 — Plugins (~3 min)
1027
+
1028
+ **Context — present plugins to the tester before any command runs.**
1029
+ This is the official welcome to the plugin world; many testers will
1030
+ not have considered that skill-map is extensible at all. Frame it
1031
+ like this in a blockquote (translate to the tester's language per
1032
+ the standard rules):
1033
+
1034
+ > Plugins are how skill-map gets extended. The kernel ships with a
1035
+ > small set of built-in plugins out of the box, but anyone can
1036
+ > write their own and drop them into the project — `sm plugins
1037
+ > create` scaffolds a manifest and the stubs, so there is no
1038
+ > handwritten boilerplate to start from.
1039
+ >
1040
+ > The kernel exposes **six** plugin types you can implement:
1041
+ >
1042
+ > - **extractors** — find links and references inside markdown.
1043
+ > - **analyzers** — rules that surface issues on a node.
1044
+ > - **actions** — verbs the user can run on a node (e.g. `bump`).
1045
+ > - **hooks** — fire on lifecycle events (scan started, finished,
1046
+ > …).
1047
+ > - **formatters** — render outputs in different shapes (text,
1048
+ > JSON, custom).
1049
+ > - **providers** — declare new node kinds and where to look for
1050
+ > them.
1025
1051
  >
1026
- > - `sm check` reports broken-refs and other rule-driven issues
1027
- > (the deterministic catalog).
1028
- > - `sm orphans` is a **different scope**: auto-rename / orphan-node
1029
- > detection (a node whose file disappeared, or a candidate rename
1030
- > the kernel is still unsure about). Our fixture doesn't produce
1031
- > orphans of that kind, so `sm orphans` will print "No orphan /
1032
- > auto-rename issues" — that's expected, not a bug.
1052
+ > Let's look at what's installed right now.
1033
1053
 
1034
- ### Step 8 — Plugins (~3 min)
1054
+ Then run the commands:
1035
1055
 
1036
1056
  ```bash
1037
1057
  sm plugins list
1038
1058
  sm plugins doctor
1039
- sm plugins show core/external-url-counter
1059
+ sm plugins show core
1040
1060
  sm plugins disable core/external-url-counter
1041
1061
  sm plugins list # confirm it shows as disabled
1042
1062
  sm plugins enable core/external-url-counter
1043
1063
  ```
1044
1064
 
1045
- > **About `plugins doctor` warnings on a clean fixture**: `doctor` may
1046
- > emit 1-2 informational warnings about `explorationDir` not existing
1047
- > for `gemini/gemini` (`~/.gemini`) or `agent-skills/agent-skills`
1048
- > (`.agents`). These are normal on a machine that has not installed
1049
- > those tools — the providers declare optional discovery paths and
1050
- > warn when the path is absent. Nothing is broken; the providers just
1051
- > have nothing to scan.
1052
-
1053
- > **About `sm plugins show <qualified-id>`**: the verb is
1054
- > informational — passing `core/external-url-counter` validates the
1055
- > extension exists and then renders the **parent bundle's** detail
1056
- > (i.e. the full `core` listing). The extension you named lives in
1057
- > that list. This is deliberate: forcing the user to type the bundle
1058
- > id just to read a single extension's manifest would be hostile, so
1059
- > `show` accepts the qualified shape and resolves up. Use
1060
- > `sm plugins doctor` or scroll the bundle's extension table to spot
1061
- > the one you queried.
1062
-
1063
- > **About IDs for `disable` / `enable`**: those verbs accept either a
1064
- > **bundle id** (e.g. `claude`, which toggles every Claude extension
1065
- > at once) or a **qualified extension id** `<bundle>/<ext-id>` (e.g.
1066
- > `core/external-url-counter`). The display format you see in
1067
- > `plugins list` (`extractor:core/external-url-counter@1.0.0`)
1068
- > includes the kind prefix and the version for readability — strip
1069
- > both when passing the id to `disable` / `enable`. Per-extension
1070
- > toggles only work on extension-granularity bundles like `core`;
1071
- > the `claude` bundle is bundle-granularity and only accepts the
1072
- > bundle id.
1073
-
1074
- We pick `core/external-url-counter` because disabling it has the
1075
- smallest blast radius (one extractor that doesn't run, easily
1076
- re-enabled). Avoid disabling `claude` for this demo — it would kill
1077
- all Claude-kind extraction during the window.
1065
+ If the tester asks about `plugins doctor` warnings, `plugins show`
1066
+ behavior, or which id format `disable` / `enable` accept, see
1067
+ §Scope clarifications.
1078
1068
 
1079
1069
  If `plugins list` shows zero entries (depends on the build), tell
1080
1070
  the tester no plugins are installed yet and offer to skip.
1081
1071
 
1082
- ### Step 9 — Annotations and the `.sm` consent prompt (~3 min)
1072
+ ### Step 13 — Annotations and the `.sm` consent prompt (~3 min)
1083
1073
 
1084
1074
  **Context**: skill-map keeps a small **companion file** (extension
1085
1075
  `.sm`) next to each `.md` to track its version, history, and tags.
@@ -1109,26 +1099,74 @@ cat .skill-map/settings.local.json
1109
1099
 
1110
1100
  **Why the prompt?** The choice is **per-user, per-project** — stored
1111
1101
  in the gitignored `settings.local.json` so each contributor consents
1112
- independently and nothing about the choice travels via the repo. On a
1113
- CI / non-interactive session, pass `--yes` to grant up-front.
1102
+ independently and nothing about the choice travels via the repo.
1103
+ Once accepted, the flag stays set and skill-map will never ask
1104
+ again on this checkout (the next `sm sidecar annotate` or `sm bump`
1105
+ goes through silently). On a CI / non-interactive session, pass
1106
+ `--yes` to grant up-front.
1114
1107
 
1115
- **Try this**: delete `notes/todo.sm` and re-run the command — this
1116
- time it goes through silently because the flag is already set:
1108
+ If the tester asks about `sm bump` vs `sm sidecar annotate` vs
1109
+ `sm sidecar refresh`, see §Scope clarifications.
1117
1110
 
1118
- ```bash
1119
- rm notes/todo.sm
1120
- sm sidecar annotate notes/todo.md
1121
- ```
1122
-
1123
- Expected: same scaffold reappears, no prompt.
1111
+ ---
1124
1112
 
1125
- > **Heads up about scope** (mention only if the tester asks):
1126
- >
1127
- > - `sm sidecar annotate` is the scaffold verb (creates a fresh `.sm`).
1128
- > - `sm bump <node>` is the day-to-day verb that increments the
1129
- > sidecar's version and refreshes its hashes same consent gate.
1130
- > - `sm sidecar refresh <node>` is the hash-only update (no version
1131
- > bump).
1113
+ ## Scope clarifications (on demand)
1114
+
1115
+ Reference material for the "mention only if the tester asks"
1116
+ beats in Steps 7, 8 and 9. Do NOT volunteer these unprompted —
1117
+ they exist so the agent has a precise answer ready when the
1118
+ tester pulls on the thread.
1119
+
1120
+ ### `sm check` vs `sm orphans`
1121
+
1122
+ - `sm check` reports broken-refs and other rule-driven issues
1123
+ (the deterministic catalog).
1124
+ - `sm orphans` is a **different scope**: auto-rename / orphan-node
1125
+ detection (a node whose file disappeared, or a candidate rename
1126
+ the kernel is still unsure about). Our fixture doesn't produce
1127
+ orphans of that kind, so `sm orphans` will print "No orphan /
1128
+ auto-rename issues" — that's expected, not a bug.
1129
+
1130
+ ### `plugins doctor` warnings on a clean fixture
1131
+
1132
+ `doctor` may emit 1-2 informational warnings about `explorationDir`
1133
+ not existing for `gemini/gemini` (`~/.gemini`) or
1134
+ `agent-skills/agent-skills` (`.agents`). These are normal on a
1135
+ machine that has not installed those tools — the providers declare
1136
+ optional discovery paths and warn when the path is absent. Nothing
1137
+ is broken; the providers just have nothing to scan.
1138
+
1139
+ ### `sm plugins show <qualified-id>`
1140
+
1141
+ The verb is informational — passing `core/external-url-counter`
1142
+ validates the extension exists and then renders the **parent
1143
+ bundle's** detail (i.e. the full `core` listing). The extension
1144
+ you named lives in that list. This is deliberate: forcing the user
1145
+ to type the bundle id just to read a single extension's manifest
1146
+ would be hostile, so `show` accepts the qualified shape and
1147
+ resolves up. Use `sm plugins doctor` or scroll the bundle's
1148
+ extension table to spot the one you queried.
1149
+
1150
+ ### IDs for `plugins disable` / `plugins enable`
1151
+
1152
+ Those verbs accept either a **bundle id** (e.g. `claude`, which
1153
+ toggles every Claude extension at once) or a **qualified extension
1154
+ id** `<bundle>/<ext-id>` (e.g. `core/external-url-counter`). The
1155
+ display format you see in `plugins list`
1156
+ (`extractor:core/external-url-counter@1.0.0`) includes the kind
1157
+ prefix and the version for readability — strip both when passing
1158
+ the id to `disable` / `enable`. Per-extension toggles only work on
1159
+ extension-granularity bundles like `core`; the `claude` bundle is
1160
+ bundle-granularity and only accepts the bundle id.
1161
+
1162
+ ### `sm sidecar annotate` vs `sm bump` vs `sm sidecar refresh`
1163
+
1164
+ - `sm sidecar annotate` is the scaffold verb (creates a fresh
1165
+ `.sm`).
1166
+ - `sm bump <node>` is the day-to-day verb that increments the
1167
+ sidecar's version and refreshes its hashes — same consent gate.
1168
+ - `sm sidecar refresh <node>` is the hash-only update (no version
1169
+ bump).
1132
1170
 
1133
1171
  ---
1134
1172
 
@@ -1157,7 +1195,7 @@ template:
1157
1195
  - **Depth reached**: <basic | full>
1158
1196
  - **Tester**: level <N> (if applicable)
1159
1197
  - **Tutorial directory**: <cwd>
1160
- - **Steps completed**: N / 3 demo + X / 6 deep-dive (if applicable)
1198
+ - **Steps completed**: N / 7 demo + X / 6 deep-dive (if applicable)
1161
1199
  - **Steps skipped**: Y (if applicable)
1162
1200
  - **Total time**: ~<computed from timestamps>
1163
1201
 
@@ -1180,14 +1218,32 @@ Then show:
1180
1218
  > <cwd>/sm-tutorial-report.md
1181
1219
  >
1182
1220
  > Send it to Pusher whenever you're ready (over the agreed channel).
1221
+
1222
+ If they say **2**, skip the report path and go straight to the
1223
+ closing block below.
1224
+
1225
+ **Always show this closing block** (regardless of the report
1226
+ choice — both branches converge here):
1227
+
1228
+ > One more thing before you go: there's a companion skill called
1229
+ > **sm-master** that picks up where this tutorial leaves off. It's
1230
+ > a modular deep-dive — you choose which areas to explore from a
1231
+ > menu — and it covers a guided tour of the built-in plugins
1232
+ > (extractors, analyzers, actions, hooks, formatters, providers),
1233
+ > plugin authoring via `sm plugins create` / `sm plugins upgrade`,
1234
+ > and settings + view-slots at depth. Same external-tester
1235
+ > audience, same pause/resume style, but a lot more ground covered.
1236
+ >
1237
+ > When you're ready, **invoke it from a fresh empty directory**
1238
+ > (same setup as this tutorial), and just say `sm-master` or
1239
+ > `advanced tutorial` to start.
1183
1240
  >
1184
- > To delete everything the tutorial left behind, if the cwd was a
1241
+ > To delete everything THIS tutorial left behind, if the cwd was a
1185
1242
  > dedicated dir:
1186
1243
  >
1187
1244
  > cd ~ && rm -rf <cwd>
1188
-
1189
- If they say **2**, just show the deletion instructions and say
1190
- thanks.
1245
+ >
1246
+ > Thanks for testing skill-map!
1191
1247
 
1192
1248
  ## Resume / restart
1193
1249
 
@@ -1196,9 +1252,9 @@ the cwd, start like this (do NOT repeat pre-flight from scratch):
1196
1252
 
1197
1253
  > I see you already started the tutorial.
1198
1254
  >
1199
- > You're at step <N> of 3 (or "you've already completed the demo
1200
- > (steps 1-3) and you're on step <M> of 6 of the deep-dive (steps
1201
- > 4-9)", depending on the yaml state).
1255
+ > You're at step <N> of 7 (or "you've already completed the demo
1256
+ > (steps 1-7) and you're on step <M> of 6 of the deep-dive (steps
1257
+ > 8-13)", depending on the yaml state).
1202
1258
  >
1203
1259
  > 1. **Continue** from where you left off
1204
1260
  > 2. **Start over** — wipes all the tutorial content in this dir
@@ -1270,13 +1326,3 @@ anything**:
1270
1326
  `curl http://127.0.0.1:4242` from another terminal.
1271
1327
  - **Tester gets lost** → "no worries, tell me where you are and
1272
1328
  we'll pick up from there". State is in `tutorial-state.yml`.
1273
-
1274
- ## Things you NEVER do
1275
-
1276
- - Run `sm` verbs for the tester (except `sm version` ONCE in
1277
- pre-flight).
1278
- - Advance to the next step without confirmation.
1279
- - Modify files outside the tutorial cwd.
1280
- - Ask them to `cd` outside the tutorial cwd.
1281
- - Skip the level question when entering the deep-dive.
1282
- - Ignore findings — always offer to log them.