| name | tutorial-factory |
| description | Autonomous tutorial generator — brainstorms a tutorial idea, implements it, self-reviews, and links it into the registry. Designed for /loop. |
What This Skill Does
Generates one tutorial per invocation. Reads existing tutorials to avoid duplicates, brainstorms via Six Hats,
implements the winning idea as a Kotlin data file, adds it to the registry, and self-reviews.
CRITICAL: This skill runs autonomously. Only use tools that do NOT require human acceptance: Read, Write, Edit, Glob,
Grep, Agent. NO Bash commands. NO git commands.
Step 1: Check Existing Tutorials
Read the registry file to see what already exists:
/opt/dev/peekandpoke/klang/src/jsMain/kotlin/pages/docs/tutorials/TutorialRegistry.kt
Also read the generation log to track what has been created:
/opt/dev/peekandpoke/klang/src/jsMain/kotlin/pages/docs/tutorials/GENERATION_LOG.md
Note all existing tutorial slugs, topics, difficulty levels, and scopes. The goal is DIVERSITY — avoid duplicating
topics and spread across difficulty levels and scopes.
Step 2: Brainstorm via Six Hats
Run /six-hats with this topic:
"What is the single best NEW tutorial to create next for the Klang live-coding music platform?
It must teach something concrete using Sprudel pattern language.
It must NOT overlap with existing tutorials: [list existing slugs/titles here].
Current difficulty spread: [list counts per difficulty].
Current topic spread: [list existing tags].
The tutorial should use ONLY these verified functions: note(), n(), sound(), s(), stack(), cat(), fastcat(),
slowcat(), silence, fast(), slow(), gain(), pan(), lpf(), hpf(), bandf(), delay(), delaytime(), delayfeedback(), room(),
rsize(), scale(), transpose(), chord(), adsr(), attack(), decay(), sustain(), release(), legato(), every(),
superimpose(), jux(), scramble(), shuffle(), pick(), distort(), crush(), tremolo(), vibrato(), phaser(), sine, saw, tri,
square, brown, pink, supersaw, pure(), range(), bpm(), cps, arrange(), orbit(), spread()."
Step 3: Pick the Winner
From the Six Hats output, select the tutorial idea that:
- Fills the biggest gap in difficulty/topic coverage
- Has the strongest "wow moment" potential (Blue Hat input)
- Is technically feasible with current functions (Black Hat validation)
- Has genuine creative appeal (Red Hat + Green Hat input)
- SERIES THINKING: For complex topics (mini-notation, chords, effects, arrangement), prefer creating a tutorial
that fills a missing difficulty level in an existing topic series. E.g., if there's already a Pro mini-notation
tutorial, consider a Beginner or Intermediate one on the same topic. Don't cram everything into one tutorial.
Step 4: Implement the Tutorial
Create a new file at:
src/jsMain/kotlin/pages/docs/tutorials/tut_<PascalCaseSlug>.kt
Use this template:
package io.peekandpoke.klang.pages.docs.tutorials
val <camelCaseSlug> Tutorial = Tutorial(
slug = "<kebab-case-slug>",
title = "<Human Readable Title>",
description = "<One sentence describing what the learner will achieve>",
difficulty = TutorialDifficulty.< level >,
scope = TutorialScope.< scope >,
tags = listOf(TutorialTag.< Tag1 >, TutorialTag.< Tag2 >),
sections = listOf(
TutorialSection(
heading = "Introduction",
text = "<Brief context — why this matters, what you'll learn>",
),
TutorialSection(
heading = "<Step heading>",
text = "<Explanation of the concept>",
code = "<working sprudel code>",
),
TutorialSection(
heading = "Putting It All Together",
text = "<Summary of what was learned>",
code = "<final combined example that sounds good>",
),
),
)
Code Example Rules
CRITICAL — every code example must be valid Sprudel that runs in the engine:
- Notes use string mini-notation:
note("c3 d3 e3") not note(c3, d3, e3)
- Samples use names:
sound("bd hh sd hh")
- Angle brackets for slow sequences:
note("<c3 e3 g3>")
- Square brackets for grouping:
note("[c3 e3] g3")
- Stack for layering:
stack(pattern1, pattern2)
- Method chaining:
note("c3").sound("sine").gain(0.5)
- Scale applied after note numbers:
n("0 2 4 6").scale("C4:major").sound("saw")
- ADSR as string:
.adsr("0.01:0.2:0.8:0.1")
- Filter values are numbers:
.lpf(800) not .lpf("800")
- Available waveforms for .sound(): "sine", "saw", "tri", "square", "pulse", "brown", "pink", "supersaw"
- Available samples for .sound(): "bd", "hh", "sd", "cp", "oh", "ch", "rim"
- Gain values typically 0.0 to 1.0
- Available scales: "major", "minor", "dorian", "mixolydian", "pentatonic", "blues", "chromatic"
- CHORDS:
chord() alone does NOT produce sound. Correct usage:
chord("<Am C F G>").voicing().sound("supersaw"). The chord() takes chord name strings, voicing() turns them into
notes.
- ORBITS: Effects like delay and reverb are PER-ORBIT. When stacking patterns with different delay/reverb
settings, EACH layer needs its own
.orbit(N). Layers sharing the same effects (or no effects) can share an orbit.
Dry drums should be on a different orbit than wet synths.
- Do NOT use the old pattern
n().scale().chord("minor") — that syntax is wrong. Use chord("<ChordName>").voicing()
instead.
- PAN RANGE:
pan(0.0) = hard LEFT, pan(0.5) = CENTER, pan(1.0) = hard RIGHT. The range is 0.0 to 1.0, NOT -1
to +1.
- LINE LENGTH: Break long chains (~70+ chars). Indent continuation lines by 2 spaces. Break after logical groups
(pattern+scale, sound+filter, before effects, before orbit).
- COMMENTS — playful sculptor tone: Add a comment before the key teaching concept in each code block. Do NOT
be dry ("NOTICE: superimpose adds a copy"). Be playful, like a sculptor shaping raw material:
// Watch: this is where the shape emerges, // Chisel away: just a touch of reverb,
// Now carve out some stereo width, // Feel the grain: this gives great texture
- ALWAYS lpf() harsh waveforms:
sound("saw"), sound("supersaw"), sound("square") must have .lpf() to
sound nice. Exception: when deliberately demonstrating the raw unfiltered sound.
- No big words in titles: Avoid "masterclass", "ultimate", "definitive", "comprehensive". Keep titles simple and
concrete — describe what you'll do, not how impressive it is.
Difficulty Guidelines
- Beginner: 1-2 functions, immediate result, < 3 code examples. "Paste and play."
- Intermediate: 3-5 functions, building on basics, 3-4 code examples. Introduces one new concept.
- Advanced: Combines multiple concepts, 4-5 code examples. Pattern design thinking.
- Pro: Complex compositions, creative technique, 4-6 code examples. Pushes boundaries.
Scope Guidelines
- Quick: 1-2 minutes to complete, 2-3 sections
- Standard: 3-5 minutes, 3-5 sections
- DeepDive: 5-10 minutes, 5-7 sections
Step 5: Register the Tutorial
Edit TutorialRegistry.kt to add the new tutorial to allTutorials. Add the import and list entry.
Step 6: Self-Review
Read back the created file and verify:
- All code examples use only documented functions from the list above
- Code examples are syntactically valid (method chaining, string arguments, proper parentheses)
- The tutorial has a clear learning progression
- The slug is unique
- Description is one sentence
- Tags are lowercase single words
Fix any issues found.
Step 7: Update Generation Log
Edit GENERATION_LOG.md to append:
| <slug> | <title> | <difficulty> | <scope> | <tags> |
Output
After completion, briefly state:
- Tutorial created: [title]
- Difficulty: [level], Scope: [scope]
- Tags: [list]
- File: [path]