@skill-map/cli 0.16.2 → 0.16.4

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/README.md CHANGED
@@ -37,7 +37,7 @@ claude # open Claude Code in the same dir
37
37
  ejecutá @sm-tutorial.md
38
38
  ```
39
39
 
40
- Claude loads the SKILL.md and runs the demo (~7 min): fixture, `sm init`, live UI, four "reveals" that show the watcher in action, plus the `.skillmapignore` hide-a-file flow. An optional deep-dive (~30-40 min) covers the rest of the CLI surface (`list`, `graph`, `export`, `orphans`, `plugins`, `db ops`).
40
+ Claude loads the SKILL.md and runs the demo (~10 min): fixture, `sm init`, live UI, five sub-steps that show the watcher in action, plus the `.skillmapignore` hide-a-file flow. An optional deep-dive (~20-30 min) covers the rest of the CLI surface (`list`, `graph`, `export`, `check`, `plugins`).
41
41
 
42
42
  The verb `sm tutorial` writes a single self-contained file; the SKILL.md ships inside this package, so no extra install needed.
43
43
 
@@ -3,10 +3,10 @@ name: sm-tutorial
3
3
  description: |
4
4
  Interactive tutorial for testing the skill-map CLI and UI. Aimed at
5
5
  testers who are downloading the tool for the first time. The flow
6
- starts with a quick demo (~7 min) that showcases the live UI — the
6
+ starts with a quick demo (~10 min) that showcases the live UI — the
7
7
  tester runs `sm`, opens the browser, and watches the UI update as
8
8
  the agent edits `.md` files — and at the end offers an optional
9
- deep-dive (~30-40 min) covering the rest of the CLI with flags and
9
+ deep-dive (~20-30 min) covering the rest of the CLI with flags and
10
10
  advanced verbs. The skill is invoked from an empty directory and
11
11
  lays the fixture and tutorial files there directly (no wrapper).
12
12
  State persists in `tutorial-state.yml` for pause/resume. Triggers:
@@ -23,8 +23,8 @@ validated in pre-flight), narrate what you did, show the commands to
23
23
  type, and wait for the tester to run them and confirm.
24
24
 
25
25
  **Internal structure (do NOT mention this to the tester)**: the tutorial
26
- has a short first phase (~7 min) that demonstrates the live UI, and an
27
- optional second phase (~30-40 min) covering the rest of the CLI.
26
+ has a short first phase (~10 min) that demonstrates the live UI, and an
27
+ optional second phase (~20-30 min) covering the rest of the CLI.
28
28
 
29
29
  > ⚠️ For the tester this is **a single continuous flow**. Never use
30
30
  > "short path", "long path", "route", "phase 1" / "phase 2", or
@@ -73,7 +73,7 @@ optional second phase (~30-40 min) covering the rest of the CLI.
73
73
  meta-narration of your own plumbing. Pre-flight checks, file
74
74
  reads, `Bash ls`, `Write` of fixtures, state-file updates — all
75
75
  silent. The tester only hears from you when (a) you need them to
76
- do something, (b) a reveal landed and you want a confirm, or
76
+ do something, (b) a sub-step landed and you want a confirm, or
77
77
  (c) something failed and they need to know. Between those
78
78
  moments, work without commentary.
79
79
  - **Explain technical terms in parentheses the first time you
@@ -142,7 +142,7 @@ optional second phase (~30-40 min) covering the rest of the CLI.
142
142
  calls for a change to `.skillmapignore`,
143
143
  `.skill-map/settings.json`,
144
144
  `.skill-map/settings.local.json`, or `.gitignore` AS PART
145
- OF A REVEAL OR LESSON (e.g. Reveal 5 in Step 2 hides a
145
+ OF A LESSON (e.g. Step 2.5 hides a
146
146
  private node by appending a pattern), you describe the
147
147
  edit in a blockquote and the tester applies it in their
148
148
  own editor. The pedagogical point is that those files
@@ -151,28 +151,26 @@ optional second phase (~30-40 min) covering the rest of the CLI.
151
151
  teach moment defeats the lesson.
152
152
  2. **After every command block, stop and wait.** The tester pastes
153
153
  the output or replies "OK" / "done". Only then do you advance.
154
- 3. **Persist progress after every step / stage.** Update
154
+ 3. **Persist progress after every step.** Update
155
155
  `tutorial-state.yml` with `done` / `failed` / `skipped` and a
156
156
  timestamp.
157
157
  4. **If the tester reports anything weird**, offer to record it in
158
158
  `findings.md` (in the cwd). Those are the bugs the team will read.
159
- 5. **One stage at a time.** Finish, ask if they want to continue, do
159
+ 5. **One step at a time.** Finish, ask if they want to continue, do
160
160
  the next one.
161
161
  6. **If `tutorial-state.yml` already exists in the cwd** when invoked,
162
162
  do not overwrite anything. Read it, show progress, offer to
163
163
  *continue* or *start over* (the latter requires explicit
164
164
  confirmation and wipes the tutorial content).
165
- 7. **Mirror the tester's language**: if the first message they wrote
166
- was in Spanish, run the conversation in Argentine Spanish (per
167
- Tone); if in English, run it in plain English. Internal
168
- instructions in this SKILL.md stay in English so any maintainer
169
- can read them, and fixture content stays in English (it's
170
- technical Markdown, more realistic that way). Blockquote literals
171
- in this document are the messages you actually say to the tester
172
- translate them on the fly to the tester's language and render
173
- them as blockquote in the chat. Code blocks below them stay as
174
- bare ` ```bash ` fences (no `> ` prefix) so the tester can copy
175
- cleanly.
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.
176
174
 
177
175
  ## Pre-flight
178
176
 
@@ -206,13 +204,17 @@ parentheticals or explanations of which items you ignored:
206
204
 
207
205
  (or, in Spanish: "Listo, el dir está limpio. Sigamos.")
208
206
 
209
- Rules (after filtering the ignored items):
207
+ **Order of checks** (apply in this order — do not skip steps):
210
208
 
211
- - Empty listing directory is empty. **Proceed.**
212
- - Listing contains `tutorial-state.yml` (before filtering) → resume
213
- mode. **Proceed** down that branch.
214
- - Anything else (files, dotfiles, other dirs) → **stop and tell**
215
- the tester:
209
+ 1. Look at the **raw** `ls -A` output, before filtering. If
210
+ `tutorial-state.yml` is present**resume mode**. Skip the
211
+ rest of this section and follow the resume branch (see
212
+ §Resume / restart).
213
+ 2. Otherwise, apply the ignored-items filter from the whitelist
214
+ above and inspect what remains:
215
+ - Empty after filtering → fresh dir. **Proceed.**
216
+ - Anything else (files, dotfiles, other dirs) → **stop and
217
+ tell** the tester:
216
218
 
217
219
  > I detected files in here:
218
220
  >
@@ -290,12 +292,26 @@ permissions issue. Suggest `node --version` and walk them through it.
290
292
 
291
293
  ### 3. Create the initial fixture (one node only)
292
294
 
293
- The tutorial builds the graph **progressively** in five reveals during
295
+ Before you lay anything down, give the tester a one-shot heads-up.
296
+ **This is not interactive** — do NOT wait for a confirmation, do
297
+ NOT ask permission per file, do NOT enumerate the files. The
298
+ tester just needs to know scaffolding is starting so they're not
299
+ surprised when files appear; details (file list, cleanup) come
300
+ later when they're relevant. Keep it to a single short sentence:
301
+
302
+ > Quick heads-up before we start: I'm about to set up the
303
+ > tutorial scenario in this directory — that means creating a
304
+ > handful of files. Hold on while I finish.
305
+
306
+ Then proceed straight to the writes below — no pause, no "ready?"
307
+ prompt.
308
+
309
+ The tutorial builds the graph **progressively** in five sub-steps during
294
310
  Step 2 (Live UI). Right now, in pre-flight, you only create **one
295
311
  file** — a single agent — so the tester's first look at the UI
296
312
  shows exactly one node. The other four kinds (skill, command, hook,
297
313
  note) and the connectors between all five are added later, one
298
- reveal at a time.
314
+ sub-step at a time.
299
315
 
300
316
  ```
301
317
  <cwd>/
@@ -307,7 +323,7 @@ reveal at a time.
307
323
  ```
308
324
 
309
325
  `.claude/agents/demo-agent.md` (no cross-fixture links yet — those
310
- arrive in the third reveal):
326
+ arrive in Step 2.4):
311
327
  ```markdown
312
328
  ---
313
329
  name: demo-agent
@@ -338,7 +354,7 @@ Rules:
338
354
  If you spot anything weird during the tutorial, log it here.
339
355
 
340
356
  Per finding:
341
- - **Stage**: <id>
357
+ - **Step**: <id>
342
358
  - **Command**: `sm ...`
343
359
  - **Expected**: ...
344
360
  - **Got**: ...
@@ -374,24 +390,24 @@ short_steps:
374
390
  - id: "3-handoff"
375
391
  title: "Wrap-up of the demo and offer to keep going"
376
392
  status: "pending"
377
- long_stages:
378
- - id: "L1-tester-edits"
393
+ long_steps:
394
+ - id: "4-tester-edits"
379
395
  title: "Tester edits live (extends the UI demo)"
380
396
  status: "pending"
381
- - id: "L2-cli-browse"
397
+ - id: "5-cli-browse"
382
398
  title: "Browse CLI: list / show / check"
383
399
  status: "pending"
384
400
  verbs: ["sm list", "sm show", "sm check"]
385
- - id: "L3-ascii"
401
+ - id: "6-ascii"
386
402
  title: "ASCII: graph + export"
387
403
  status: "pending"
388
404
  verbs: ["sm graph", "sm export"]
389
- - id: "L4-orphans"
390
- title: "Issues and orphans"
405
+ - id: "7-issues"
406
+ title: "Issues: broken refs"
391
407
  status: "pending"
392
- verbs: ["sm orphans", "sm orphans reconcile",
393
- "sm orphans undo-rename"]
394
- - id: "L5-plugins"
408
+ verbs: ["sm check", "sm check --rules broken-ref",
409
+ "sm check --json"]
410
+ - id: "8-plugins"
395
411
  title: "Plugins"
396
412
  status: "pending"
397
413
  verbs: ["sm plugins list", "sm plugins show",
@@ -400,9 +416,9 @@ long_stages:
400
416
  findings_file: "./findings.md"
401
417
  ```
402
418
 
403
- ## Per-step / per-stage cycle
419
+ ## Per-step cycle
404
420
 
405
- For every step in the demo and every stage in the deep-dive:
421
+ For every step in the tutorial:
406
422
 
407
423
  1. **Announcement**: "Step N: `<title>`. ~M minutes." One sentence
408
424
  of context.
@@ -421,7 +437,7 @@ to resume (re-invoke the skill from the same dir).
421
437
 
422
438
  ---
423
439
 
424
- ## DEMO (~7 min)
440
+ ## DEMO (~10 min)
425
441
 
426
442
  Always runs. The pedagogical hook is the live UI.
427
443
 
@@ -451,7 +467,7 @@ sm-tutorial.md
451
467
  findings.md
452
468
  tutorial-state.yml
453
469
  sm-tutorial-report.md
454
- # tutorial outputs that may land at the root if a stage forgets to clean up
470
+ # tutorial outputs that may land at the root if a step forgets to clean up
455
471
  export.*
456
472
  dump.sql
457
473
  ```
@@ -465,24 +481,24 @@ starts the UI server with the watcher built in. One process, one
465
481
  terminal: it boots the server, scans the `.md` files, detects
466
482
  changes, and pushes events over WebSocket to the live UI.
467
483
 
468
- This step has **five reveals**, each one driven by you editing
469
- files while the server stays up — except Reveal 3, where the
470
- tester takes the keyboard for the first time.
484
+ This step has **five sub-steps** (2.1 through 2.5), each one driven
485
+ by you editing files while the server stays up — except Step 2.3,
486
+ where the tester takes the keyboard for the first time.
471
487
 
472
- 1. **Reveal 1 (boot)** — one node alone (the agent).
473
- 2. **Reveal 2 (kinds)** — the four other kinds appear as new nodes,
488
+ 1. **Step 2.1 (boot)** — one node alone (the agent).
489
+ 2. **Step 2.2 (kinds)** — the four other kinds appear as new nodes,
474
490
  still unconnected.
475
- 3. **Reveal 3 (your first edit)** — the **tester** edits the
491
+ 3. **Step 2.3 (your first edit)** — the **tester** edits the
476
492
  `description` of the agent's `.md` and watches the card
477
493
  refresh in the graph.
478
- 4. **Reveal 4 (connectors)** — the connectors light up between all
494
+ 4. **Step 2.4 (connectors)** — the connectors light up between all
479
495
  five nodes.
480
- 5. **Reveal 5 (ignore)** — a private file appears, then disappears
496
+ 5. **Step 2.5 (ignore)** — a private file appears, then disappears
481
497
  the moment a pattern is added to `.skillmapignore`.
482
498
 
483
499
  The pedagogical arc: a single dot → a constellation of dots →
484
500
  your own edit lands → graph → a graph that respects the user's
485
- ignore list. Each reveal stops at a confirm prompt before you do
501
+ ignore list. Each sub-step stops at a confirm prompt before you do
486
502
  the next.
487
503
 
488
504
  **Command** (one terminal):
@@ -491,26 +507,18 @@ the next.
491
507
  sm
492
508
  ```
493
509
 
494
- Before Reveal 1, ask the tester to set up a **side-by-side view** so
495
- they can watch the magic happen without alt-tabbing every reveal.
510
+ Before Step 2.1, ask the tester to set up a **side-by-side view** so
511
+ they can watch the magic happen without alt-tabbing every sub-step.
496
512
  Tell the tester:
497
513
 
498
- > Arrange your screen so two windows are visible at the same time:
499
- >
500
- > 1. **The browser** where the graph will update in real time.
501
- > Leave it ready to navigate to a URL; we'll get the link in a
502
- > moment.
503
- > 2. **This terminal** — the one where you're talking to me. You'll
504
- > see me announce each reveal here, then confirm what you see
505
- > in the browser.
506
- >
507
- > The third window — the terminal running `sm` — you can leave
508
- > minimized or off to the side; it will just print scan progress
514
+ > Now arrange your screen so the **browser** (where the graph will
515
+ > update in real time) and **this chat** are both visible at once
516
+ > typical layout is browser on the left half, chat on the right
517
+ > (or any split that lets you see both). The terminal running
518
+ > `sm` can stay off to the side; it just prints scan progress
509
519
  > lines and you don't need to read them.
510
520
  >
511
- > A typical layout: browser on the left half, this chat on the
512
- > right half. Or any split that lets you see both at once. Tell
513
- > me when you're set up and we start.
521
+ > Tell me when you're set up and we start.
514
522
 
515
523
  Wait for confirmation before moving on. Once they're ready, prompt
516
524
  them to launch the server and open the link it prints — without
@@ -524,7 +532,7 @@ truth (it logs the bound `http://host:port` after listen):
524
532
 
525
533
  Wait for confirmation that the page loaded.
526
534
 
527
- #### Reveal 1 — the lone agent
535
+ #### Step 2.1 — the lone agent
528
536
 
529
537
  Tell the tester:
530
538
 
@@ -542,7 +550,7 @@ Tell the tester:
542
550
 
543
551
  Wait for confirmation.
544
552
 
545
- #### Reveal 2 — the other four kinds appear (the magic)
553
+ #### Step 2.2 — the other four kinds appear (the magic)
546
554
 
547
555
  Leave the browser open and the terminal with `sm` running. You
548
556
  create the four missing kinds **without any cross-fixture links**
@@ -574,7 +582,7 @@ Create these four files (with `Write`), exactly in this order:
574
582
  # demo-skill
575
583
 
576
584
  This skill walks a file and returns a report. Will be wired up
577
- to the rest of the demo fixture in the next reveal.
585
+ to the rest of the demo fixture in the next sub-step.
578
586
 
579
587
  ## Steps
580
588
  1. Read the `target`.
@@ -602,7 +610,7 @@ Create these four files (with `Write`), exactly in this order:
602
610
  # demo-command
603
611
 
604
612
  Quick keyboard entry point for running the demo flow on a
605
- target file. Connectors land in the next reveal.
613
+ target file. Connectors land in the next sub-step.
606
614
  ```
607
615
 
608
616
  3. `.claude/hooks/demo-hook.md` (kind: hook — **don't skip this
@@ -633,7 +641,7 @@ Create these four files (with `Write`), exactly in this order:
633
641
  description: |
634
642
  Live list of things to review in the demo. Will become the
635
643
  hub between skill / agent / command / hook in the next
636
- reveal.
644
+ sub-step.
637
645
  tags: [notes, demo]
638
646
  metadata:
639
647
  version: "1.0.0"
@@ -654,13 +662,13 @@ Tell the tester:
654
662
 
655
663
  Wait for confirmation.
656
664
 
657
- #### Reveal 3 — your first edit
665
+ #### Step 2.3 — your first edit
658
666
 
659
667
  Up to here you've been watching the agent write files. Now hand
660
668
  the keyboard over: the lesson is that the watcher reacts to
661
669
  **any** `.md` edit under the cwd, not just to files the agent
662
670
  authors. After this beat, the tester has the muscle memory for
663
- "save → graph updates", which Reveal 5 (`.skillmapignore`) reuses
671
+ "save → graph updates", which Step 2.5 (`.skillmapignore`) reuses
664
672
  verbatim.
665
673
 
666
674
  Tell the tester:
@@ -672,11 +680,10 @@ Tell the tester:
672
680
  > change will be obvious.
673
681
  >
674
682
  > Now open `.claude/agents/demo-agent.md` in your editor of
675
- > choice. In the **frontmatter** (the YAML block at the top of
676
- > the file, between the two `---` lines), change the
677
- > `description:` field to any text you want the actual content
678
- > does not matter, just make it different from what's there now.
679
- > Save the file.
683
+ > choice. In the **frontmatter** at the top of the file, change
684
+ > the `description:` field to any text you want the actual
685
+ > content does not matter, just make it different from what's
686
+ > there now. Save the file.
680
687
  >
681
688
  > Watch the browser. The `demo-agent` card should refresh its
682
689
  > description in real time, no reload, no Ctrl+C — same watcher
@@ -689,7 +696,7 @@ Wait for confirmation. You MAY use `Read` on the file afterwards
689
696
  to verify the change landed (read-only, allowed under Inviolable
690
697
  rule #1) before moving on.
691
698
 
692
- #### Reveal 4 — the connectors light up
699
+ #### Step 2.4 — the connectors light up
693
700
 
694
701
  Now you edit the existing files to add the cross-fixture links —
695
702
  each one becomes a connector in the graph. Apply with `Edit` (do
@@ -743,22 +750,22 @@ Tell the tester:
743
750
  > Confirm. If a connector is missing, refresh the browser and tell
744
751
  > me.
745
752
 
746
- Wait for confirmation. **Do NOT move on to Reveal 5** until the
747
- connectors are confirmed visible — Reveal 5 reuses the same live UI
753
+ Wait for confirmation. **Do NOT move on to Step 2.5** until the
754
+ connectors are confirmed visible — Step 2.5 reuses the same live UI
748
755
  session.
749
756
 
750
- #### Reveal 5 — silence a private file via `.skillmapignore`
757
+ #### Step 2.5 — silence a private file via `.skillmapignore`
751
758
 
752
- The first four reveals showed the watcher picking up new files and
753
- edits (yours and theirs). Reveal 5 flips the direction: a file the
759
+ The first four sub-steps showed the watcher picking up new files and
760
+ edits (yours and theirs). Step 2.5 flips the direction: a file the
754
761
  tester DOES NOT want
755
762
  in the graph (a draft, a scratch file, a secret) gets hidden by a
756
763
  single line in `.skillmapignore`. Same live mechanism — no restart.
757
764
 
758
765
  `sm init` already wrote a starter `.skillmapignore` at the scope
759
- root. The flow has three beats:
766
+ root. The flow has three sub-steps:
760
767
 
761
- **Beat A — you create one new fixture file (the agent does this).**
768
+ **Step 2.5.1 — you create one new fixture file (the agent does this).**
762
769
 
763
770
  `Write` `notes/private-credentials.md` — kind `note`, simulates a
764
771
  file the tester would never want surfacing publicly:
@@ -783,7 +790,7 @@ Confirm the file appears in the graph as a sixth node
783
790
  (`notes/private-credentials`). The watcher sees it like any
784
791
  other `.md` — that's the point of the demo.
785
792
 
786
- **Beat B — you show the project structure (the agent does this).**
793
+ **Step 2.5.2 — you show the project structure (the agent does this).**
787
794
 
788
795
  Before asking the tester to touch `.skillmapignore`, give them a
789
796
  mental map of the folder so they know where the file lives and
@@ -791,8 +798,7 @@ what's around it. Use `Bash` (`ls -la` and `ls -la notes/` if a
791
798
  deeper view helps) and present the listing inside a blockquote so
792
799
  the tester sees what their cwd holds:
793
800
 
794
- > Antes del último paso, esto es lo que tenés en el directorio
795
- > ahora mismo:
801
+ > One last step. Here's what your directory looks like right now:
796
802
  >
797
803
  > ```
798
804
  > . ← your cwd
@@ -817,7 +823,7 @@ Adjust the actual tree shown to whatever `ls -la` returns — the
817
823
  goal is "tester recognises their own filesystem", not a copy of
818
824
  the snippet above.
819
825
 
820
- **Beat C — the tester edits `.skillmapignore` (NOT the agent).**
826
+ **Step 2.5.3 — the tester edits `.skillmapignore` (NOT the agent).**
821
827
 
822
828
  Per Inviolable rule #1, you DO NOT touch `.skillmapignore` with
823
829
  your `Edit` tool. Tell the tester to do it from their editor:
@@ -854,12 +860,12 @@ Mark `2-ui-live: done`.
854
860
  ### Step 3 — Wrap-up of the demo and offer to keep going (30 s)
855
861
 
856
862
  > All set! That's the heart of skill-map: you edit a `.md` and the
857
- > UI sees it instantly. In **~7 minutes** you've already seen the
863
+ > UI sees it instantly. In **~10 minutes** you've already seen the
858
864
  > full flow.
859
865
  >
860
866
  > If you want, **we can keep going deeper**: I'll walk you through
861
867
  > the CLI verbs and flags (`list`, `graph`, `export`, `orphans`,
862
- > `plugins`, `db ops`, etc.). About ~30-40 min more, pausable
868
+ > `plugins`, `db ops`, etc.). About ~20-30 min more, pausable
863
869
  > whenever.
864
870
  >
865
871
  > 1. **Yes, let's continue**
@@ -878,9 +884,9 @@ If they say **1**:
878
884
 
879
885
  ---
880
886
 
881
- ## DEEP-DIVE (~30-40 min) — opt-in
887
+ ## DEEP-DIVE (~20-30 min) — opt-in
882
888
 
883
- Strictly new stages. Does not re-expand demo steps.
889
+ Strictly new steps. Does not re-expand demo steps.
884
890
 
885
891
  ### Level question (one time only, on entry)
886
892
 
@@ -900,12 +906,12 @@ Save into `tester.level` and modulate:
900
906
  - **Level 3**: dense blocks, flags included, no explanations of
901
907
  basic concepts.
902
908
 
903
- ### Stage L1 — Tester edits live (~3 min)
909
+ ### Step 4 — Tester edits live (~3 min)
904
910
 
905
911
  **Context**: in the demo you edited. Now it's their turn to confirm
906
912
  they can do it from their editor.
907
913
 
908
- This stage needs the server running. **Check first** before asking
914
+ This step needs the server running. **Check first** before asking
909
915
  them to launch it: many testers leave it running from Step 2 and
910
916
  the demo wraps without an explicit Ctrl+C. Word the prompt as a
911
917
  conditional, e.g. "If the server from Step 2 is still up, leave it
@@ -917,16 +923,14 @@ process trying to bind the same port and confusing the tester.
917
923
  > editor of choice and remove the line that links to `demo-agent.md`.
918
924
  > Save. Watch the UI.
919
925
  >
920
- > Expected: the `demo-skill → demo-agent` connector disappears. If
921
- > `demo-agent.md` ends up with no one linking to it, it shows up as
922
- > an orphan (we'll create a similar dangling situation in stage L4
923
- > to see how `sm check` flags it).
926
+ > Expected: the `demo-skill → demo-agent` connector disappears in
927
+ > real time. The two nodes stay in the graph; only the edge goes.
924
928
 
925
929
  You verify by reading `.claude/skills/demo-skill/SKILL.md` to confirm
926
930
  the change was applied. Once they confirm, ask them to **Ctrl+C**
927
931
  the server.
928
932
 
929
- ### Stage L2 — Browse CLI: list / show / check (~3 min)
933
+ ### Step 5 — Browse CLI: list / show / check (~3 min)
930
934
 
931
935
  ```bash
932
936
  sm list
@@ -938,10 +942,10 @@ sm check
938
942
 
939
943
  Expected: you see the 5 fixture nodes listed with their kind;
940
944
  `check` runs the deterministic rules and reports a clean fixture
941
- (no issues at this point — we will plant one in stage L4 and watch
945
+ (no issues at this point — we will plant one in step 7 and watch
942
946
  the rule catch it).
943
947
 
944
- ### Stage L3 — ASCII: graph + export (~3 min)
948
+ ### Step 6 — ASCII: graph + export (~3 min)
945
949
 
946
950
  ```bash
947
951
  sm graph
@@ -954,7 +958,7 @@ ls -la export.*
954
958
  `graph` draws an ASCII tree. `export` filters and serialises to md
955
959
  or json.
956
960
 
957
- ### Stage L4 — Issues: broken refs (~3 min)
961
+ ### Step 7 — Issues: broken refs (~3 min)
958
962
 
959
963
  `broken-ref` is one of the deterministic rules `sm check` runs.
960
964
  We'll plant one and watch it surface — that's the easiest way to
@@ -992,7 +996,7 @@ rest of the deep-dive doesn't depend on it.
992
996
  > orphans of that kind, so `sm orphans` will print "No orphan /
993
997
  > auto-rename issues" — that's expected, not a bug.
994
998
 
995
- ### Stage L5 — Plugins (~3 min)
999
+ ### Step 8 — Plugins (~3 min)
996
1000
 
997
1001
  ```bash
998
1002
  sm plugins list
@@ -1049,8 +1053,8 @@ template:
1049
1053
  - **Depth reached**: <basic | full>
1050
1054
  - **Tester**: level <N> (if applicable)
1051
1055
  - **Tutorial directory**: <cwd>
1052
- - **Steps completed**: 4 / 4 + X / 5 deep-dive stages (if applicable)
1053
- - **Stages skipped**: Y (if applicable)
1056
+ - **Steps completed**: N / 3 demo + X / 5 deep-dive (if applicable)
1057
+ - **Steps skipped**: Y (if applicable)
1054
1058
  - **Total time**: ~<computed from timestamps>
1055
1059
 
1056
1060
  ## Environment
@@ -1088,27 +1092,71 @@ the cwd, start like this (do NOT repeat pre-flight from scratch):
1088
1092
 
1089
1093
  > I see you already started the tutorial.
1090
1094
  >
1091
- > You're at step <N> of 4 (or "you've already completed the first 4
1092
- > steps and you're on stage <M> of 5 of the deep-dive", depending on
1093
- > the yaml state).
1095
+ > You're at step <N> of 3 (or "you've already completed the demo
1096
+ > (steps 1-3) and you're on step <M> of 5 of the deep-dive (steps
1097
+ > 4-8)", depending on the yaml state).
1094
1098
  >
1095
1099
  > 1. **Continue** from where you left off
1096
1100
  > 2. **Start over** — wipes all the tutorial content in this dir
1097
1101
  > (asks for confirmation)
1098
1102
  > 3. **Exit** without touching anything
1099
1103
 
1100
- If they pick "start over", confirm explicitly. Only after
1101
- confirmation, delete the tutorial files in the cwd
1102
- (`tutorial-state.yml`, `findings.md`, `.skillmapignore`, `.claude/`,
1103
- `notes/`, `.skill-map/`, and any `export.*`, `dump.sql`, or
1104
- `sm-tutorial-report.md` that may have been left behind) and start
1105
- everything from pre-flight.
1104
+ If they pick "start over", do these checks **before deleting
1105
+ anything**:
1106
+
1107
+ 1. Read `tutorial.cwd` from `tutorial-state.yml` and compare with
1108
+ the current `pwd`. If they don't match, **refuse**:
1109
+
1110
+ > This `tutorial-state.yml` was generated for a different
1111
+ > directory (`<saved cwd>`). The current dir is `<pwd>`. I'm
1112
+ > refusing to wipe — your `.claude/`, `notes/`, etc. here are
1113
+ > probably yours, not the tutorial's. Move to `<saved cwd>` and
1114
+ > re-invoke me from there, or delete `tutorial-state.yml` by
1115
+ > hand if you really want to start fresh here.
1116
+
1117
+ 2. If the cwd matches, show the tester the exact list of paths
1118
+ you'll delete and ask for an explicit typed confirmation:
1119
+
1120
+ > Start over will delete these paths from `<cwd>`:
1121
+ >
1122
+ > ```
1123
+ > tutorial-state.yml
1124
+ > findings.md
1125
+ > .skillmapignore
1126
+ > .skill-map/
1127
+ > .claude/agents/demo-agent.md
1128
+ > .claude/commands/demo-command.md
1129
+ > .claude/hooks/demo-hook.md
1130
+ > .claude/skills/demo-skill/
1131
+ > notes/todo.md
1132
+ > notes/private-credentials.md
1133
+ > sm-tutorial-report.md (if present)
1134
+ > export.* (if present)
1135
+ > dump.sql (if present)
1136
+ > ```
1137
+ >
1138
+ > Type **`yes, wipe`** (exact text) to confirm. Anything else
1139
+ > cancels.
1140
+
1141
+ 3. Only on the literal `yes, wipe` reply, delete those exact paths.
1142
+ Do NOT recursively `rm -rf` `.claude/` or `notes/` as
1143
+ directories — only the specific tutorial-owned files inside, in
1144
+ case the tester has unrelated files there. After deletion, also
1145
+ `rmdir` `.claude/agents`, `.claude/commands`, `.claude/hooks`,
1146
+ `.claude/skills`, `notes/`, and `.claude/` if and only if they
1147
+ are empty (silent failure if not). Then start everything from
1148
+ pre-flight.
1106
1149
 
1107
1150
  ## Edge cases
1108
1151
 
1109
1152
  - **Tester doesn't have Node 20+** → guide them to `nvm` or
1110
1153
  nodejs.org. Don't try to install Node for them.
1111
- - **Port 4242 in use** → suggest `sm serve --port 4243`.
1154
+ - **Port 4242 in use** → bare `sm` doesn't accept flags (it's a
1155
+ shorthand for `sm serve` with defaults). Tell the tester to
1156
+ switch verbs: stop the failed `sm`, then run
1157
+ `sm serve --port 4243`. The browser link printed by the server
1158
+ changes accordingly — they should open the new URL, not the
1159
+ default 4242.
1112
1160
  - **`sm` doesn't pick up changes on WSL** → known on WSL2 with
1113
1161
  files under `/mnt/c/`. Suggest exiting, running `mkdir
1114
1162
  ~/sm-tutorial && cd ~/sm-tutorial` (Linux-native filesystem), and
@@ -1123,7 +1171,7 @@ everything from pre-flight.
1123
1171
 
1124
1172
  - Run `sm` verbs for the tester (except `sm version` ONCE in
1125
1173
  pre-flight).
1126
- - Advance to the next step / stage without confirmation.
1174
+ - Advance to the next step without confirmation.
1127
1175
  - Modify files outside the tutorial cwd.
1128
1176
  - Ask them to `cd` outside the tutorial cwd.
1129
1177
  - Skip the level question when entering the deep-dive.
package/dist/cli.js CHANGED
@@ -7374,7 +7374,7 @@ import { Command as Command8, Option as Option8 } from "clipanion";
7374
7374
  // package.json
7375
7375
  var package_default = {
7376
7376
  name: "@skill-map/cli",
7377
- version: "0.16.2",
7377
+ version: "0.16.4",
7378
7378
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
7379
7379
  license: "MIT",
7380
7380
  type: "module",
@@ -7425,6 +7425,10 @@ var package_default = {
7425
7425
  typecheck: "tsc --noEmit",
7426
7426
  lint: "eslint .",
7427
7427
  "lint:fix": "eslint . --fix",
7428
+ pretest: "tsup",
7429
+ "pretest:ci": "tsup",
7430
+ "pretest:coverage": "tsup",
7431
+ "pretest:coverage:html": "tsup",
7428
7432
  test: "tsc --noEmit && node --import tsx --test --test-reporter=spec 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
7429
7433
  "test:ci": "tsc --noEmit && node --import tsx --test 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
7430
7434
  "test:coverage": "tsc --noEmit && SKILL_MAP_SKIP_BENCHMARK=1 node --experimental-default-config-file --import tsx --test --experimental-test-coverage 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
@@ -14577,7 +14581,12 @@ import { Command as Command22, Option as Option22 } from "clipanion";
14577
14581
  // cli/i18n/tutorial.texts.ts
14578
14582
  var TUTORIAL_TEXTS = {
14579
14583
  // Success — written to stdout after `<cwd>/sm-tutorial.md` is created.
14580
- written: 'Done. sm-tutorial.md created at {{cwd}}. Open Claude Code here and tell it "run @sm-tutorial.md" to start the interactive tutorial.\n',
14584
+ // Multi-line layout: the two trigger phrases (English / Spanish) are
14585
+ // indented and labelled so they're the most visible part of the
14586
+ // output. The reminder above them surfaces the SKILL's language
14587
+ // policy: the first message the tester writes to Claude sets the
14588
+ // tutorial language for the rest of the session.
14589
+ written: "Done. sm-tutorial.md created at {{cwd}}\n\nOpen Claude Code here. Write to it in the language you want the tutorial in \u2014 the first message sets the language for the rest of the session:\n\n English: run @sm-tutorial.md\n Espa\xF1ol: ejecut\xE1 @sm-tutorial.md\n",
14581
14590
  // Refusal — `sm-tutorial.md` already exists and `--force` was not set.
14582
14591
  // Goes to stderr, exit code 2 (operational error per spec § Exit codes).
14583
14592
  alreadyExists: "sm tutorial: sm-tutorial.md already exists at {{cwd}}. Pass `--force` to overwrite.\n",