Install
$ agentstack add skill-terryc21-tutorial-creator-tutorial-creator ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
tutorial-creator
Three surfaces, gateway-mediated:
tutorial— generate a lesson (six writing-to-learn entries, five audience-facing entries)vocab— manage vocabulary independent of lesson generationstatus— inspect your learning state (read-only dashboard)
The legacy v1.1 invocation (/skill tutorial-creator ) still works; it routes to writing-to-learn entry [b] (topic + file).
Usage
/skill tutorial-creator # opens gateway question
/skill tutorial-creator # legacy v1.1 path → entry [b]
/skill tutorial-creator tutorial # tutorial surface
/skill tutorial-creator vocab # vocab surface
/skill tutorial-creator status # status surface
/skill tutorial-creator undo # revert last generation
/skill tutorial-creator undo --session # revert a specific session (rare)
/skill tutorial-creator renumber # rename Day-N + rewrite cross-references
/skill tutorial-creator --mode learn|audience|both|vocab|status [args]
# skip gateway, route directly
/skill tutorial-creator open # register a tutorial-creator project
# in ~/.claude/tutorial-creator/registry.yaml
# so future invocations from any cwd find it
/skill tutorial-creator open # list registered projects + pick one
# (sets it as the registry default)
/skill tutorial-creator forget # remove a project from the registry
# (no filesystem changes; project files stay)
/skill tutorial-creator --project-dir [args]
# one-shot override; resolves config
# from /.claude/tutorial-config.yaml
# instead of the default discovery rule
Where the project lives. .claude/tutorial-config.yaml and .claude/tutorial-sessions/ live in the resolved project root, not necessarily cwd. The skill walks a discovery chain on every invocation; see ## Project resolution. This means you can keep a tutorial-creator project at /Volumes/.../Tutorials/ and invoke /skill tutorial-creator status from any working directory and it Just Works — same mental model as git status walking up from cwd to find .git/.
Routing logic
Every invocation runs through this dispatch:
- Resolve the project root (NEW in this revision). Run
## Project resolutionfirst to determine which.claude/tutorial-config.yamlthis invocation should read or write to. The resolved path becomes$PROJECT_ROOTfor the rest of the invocation; all subsequent file operations described in this document use$PROJECT_ROOT/.claude/,$PROJECT_ROOT/{tutorials_dir}/, etc. Steps 1–4 below assume this has run. - Read
--modeflag if present. If set, echo it back to the user as a one-line confirmation, then jump directly to that surface or path. Skip the gateway question. Mode values:learn,audience,both,vocab,status. - Else, recognize first-positional subcommand keywords. If the first positional arg is one of:
tutorial→ tutorial surface (Path 1 unless--mode audiencefollows)vocab→ vocab surface; the second positional is the subcommand (add,list,show,edit,merge,review,gap,regen-md,undo)status→ status surface (STATUS.md)undo→ recoveryundoroute (see## Recovery§undocommand). May be followed by--sessionrenumber→ recoveryrenumberroute (see## Recovery§renumber). Requires two more positional args:(e.g.,renumber 8 7.5)open→ registry route (see## Project resolution§opencommand). May be followed by an optional `` positionalforget→ registry route (see## Project resolution§forgetcommand). Requires one positional arg: ``
Route directly. Skip the gateway question.
- Else, parse two-positional legacy form. If the user invoked with two positional args matching
AND the source is an existing file in the project, treat as entry [b] legacy path — produce a v1.1-shaped tutorial. This preserves the v1.1 invocation contract for users who haven't seen the v2 changes. - Else, ask the gateway question. Present the four-option menu (below). Route based on answer.
Gateway question
Use AskUserQuestion (or plain-text prompt if AskUserQuestion is unavailable):
What do you want to do?
[1] Write a tutorial for myself (for my own learning)
[2] Write a tutorial for others (preparing a lesson for others to learn)
[3] Manage vocabulary (edit vocabulary)
[4] Inspect my learning state (see my progress and what I'm forgetting)
- Answer [1] → tutorial surface, Path 1 (writing-to-learn). Ask the entry-point question (six options; see
## Tutorial surface — entry points). - Answer [2] → tutorial surface, Path 2 (audience-facing). Load
AUDIENCE.mdand run the Path 2 routing flow (entry-point question, audience question, honest-machine opt-in, length budget, venue selection, then handoff to the chosenvenues/.md). - Answer [3] → vocab surface (load
VOCAB.md). - Answer [4] → status surface (load
STATUS.md).
Mode-mismatch detection
If the user picked Path 2 (audience-facing) AND their topic phrasing matches one of these patterns, soft-nudge once:
- starts with
I want to understand - starts with
I'm confused about - starts with
why does my - starts with
what is
Nudge text:
> This phrasing reads like writing-to-learn. Confirm audience-facing, or switch to writing-to-learn?
Single-fire per session. A session-scoped flag (mode_mismatch_nudge_fired: true) flips after the first surface. Subsequent matching topics in the same session do NOT re-nudge. The user has demonstrated awareness.
Not blocking. The user always has final say. The nudge is purely advisory; either answer proceeds without delay.
Tutorial surface — entry points
After gateway answer = [1] (writing-to-learn), ask:
Where does the lesson start?
[a] Daily progression — pick what's next based on my progress
[b] Topic + file — I have both a topic and a source file
[c] Topic only — I have a topic, find the best file
[d] Question — I'm stuck on something specific
[e] Gap-driven — show me my "confused" vocabulary, pick from there
[f] Notes & synthesis — from a doc, post, video, or past session
After gateway answer = [2] (audience-facing), ask:
Where does the tutorial start?
[a] Annotated source — file in my codebase that demonstrates the pattern
[b] Incident-grounded — a real failure or decision I want to write about
[c] Synthesized example — contrived minimal example for the concept
[d] External source — public repo, Apple sample, blog post
[e] Documentation-grounded — Apple Developer docs, RFCs, etc.
After the entry letter is picked, the Path 2 flow runs four more AskUserQuestion prompts in this order, then hands off to a venue template:
- Audience question. Options:
beginner/intermediate/senior/mixed. Drives in-voice content shifts (definitions vs. tradeoffs). - Honest-machine opt-in. Y / N. When Y, the venue template appends a section on what the article does NOT cover (section name varies by venue; resolved from
venues/_schema.yaml#venues..honest_machine_section_name). - Length budget. Options:
S/M/L/X. Each option label includes the venue's word target and ceiling, looked up fromvenues/_schema.yaml#venues..length_budget. - Venue selection. Options:
reddit/book-chapter/apple-developer-article/medium/blog/repo-doc. All six venues are shipped as ofv2.0.0; the runtime loadsvenues/.mdand renders the article using that venue's voice signature.
The full procedure for each Path 2 entry, the venue handoff payload schema, the audience × budget interaction rules, and the recovery-asymmetry rationale all live in AUDIENCE.md. SKILL.md is the routing surface; AUDIENCE.md is the procedure surface.
Implementation status
All six writing-to-learn entries are implemented (Phases 3abc + 3def):
- [a] daily progression — see
## Entry [a] — Daily progression - [b] topic + file — see
## Entry [b] — Tutorial Format (topic + file)(this is also the legacy v1.1 path) - [c] topic only — see
## Entry [c] — Topic only (skill finds the file) - [d] question-led — see
## Entry [d] — Question-led - [e] gap-driven — see
## Entry [e] — Gap-driven - [f] external source — see
## Entry [f] — External source
All five audience-facing entries are implemented (Phase 7); all six venue templates are shipped:
- [a] annotated source — see
AUDIENCE.md§ Entry [a] - [b] incident-grounded — see
AUDIENCE.md§ Entry [b] - [c] synthesized example — see
AUDIENCE.md§ Entry [c] - [d] external source — see
AUDIENCE.md§ Entry [d] - [e] documentation-grounded — see
AUDIENCE.md§ Entry [e]
Venue templates available right now:
| Venue | File | Status | |---|---|---| | reddit | venues/reddit.md | ✅ shipped | | book-chapter | venues/book-chapter.md | ✅ shipped | | apple-developer-article | venues/apple-developer-article.md | ✅ shipped | | medium | venues/medium.md | ✅ shipped | | blog | venues/blog.md | ✅ shipped | | repo-doc | venues/repo-doc.md | ✅ shipped |
The five Path 2 entries [a]-[e] share letters with the Path 1 entries but are different procedures; do not conflate them. Path 1 produces artifacts for the user (writing-to-learn); Path 2 produces artifacts for an audience (Reddit posts, book chapters, articles, blog posts, repo docs). After the entry is chosen, Path 2 hands off to one of the 6 venue templates in venues/.
Entry [a] — Daily progression
Use when the user wants the next concept in their learning sequence and doesn't have a specific topic or file in mind.
Procedure
- Read config.
.claude/tutorial-config.yaml. Required fields for entry [a]:language,next_day,experience_level,tutorials_dir. Ifprogression_overrideis set, use that path; otherwise loadprogressions/.yamlfrom the skill bundle. - Determine current phase. Read
PROGRESS.md. Look for the most recent Score Log row to find the last-shipped phase number. If PROGRESS.md is empty (first day), current phase = 1. - Read the active progression. Parse the matching
progressions/*.yaml. Extract the current phase'sconceptslist. - Identify uncovered concepts in this phase. Cross-reference
conceptsagainst the Concepts Mastery Checklist in PROGRESS.md (entries marked- [ ]or- [x]). Concepts NOT yet appearing in the checklist are the candidates. - Recommend the next concept. Pick the first uncovered concept in the phase's list (the list order is teaching order). Show the user one candidate with brief reasoning:
`` Next in your progression: Concept: Phase: . Reason: First uncovered concept in this phase. / concepts done. Generate a tutorial for this? [yes / pick different concept / advance to next phase / cancel] ``
- Handle user response.
yes: proceed to step 7pick different concept: list all uncovered concepts in current phase, let user chooseadvance to next phase: increment phase number; re-run from step 4 with the next phase. If the user is already in the last phase (phase 6 in built-in progressions), say: "You're in the last built-in phase. Use entry [c] (topic only) for advanced topics, or define a custom progression intutorial-config.yaml#progression_override." Stop.cancel: stop without generating
- Find a source file. With concept chosen, scan the project for files demonstrating it. Use the same ranking heuristic as Entry [c] below ("pedagogical fit beats density"). Show 1-3 candidates; user picks one.
- Generate the tutorial. Follow the tutorial format in
## Entry [b] — Tutorial Format. The chosen concept becomes the topic; the chosen file becomes the source.
Cold-start handling
If next_day == 1 AND PROGRESS.md doesn't exist yet AND no tutorials have been written:
- The user has just completed first-run setup
- Phase = 1; pick the first concept of phase 1 ("optionals" for Swift, "basic types" for TypeScript, etc.)
- Note in the recommendation: "First lesson — picking the foundational concept for your language."
Honesty rule
If no source file in the project demonstrates the recommended concept (scan returns zero candidates above the quality threshold defined in Entry [c]), say so explicitly:
> No good example of `` in your codebase. Two options: > 1. Pick a different concept from this phase (I can list them) > 2. Use audience-facing path [c] (synthesized minimal example) if you want a contrived example
Do not silently fall back to a synthesized example or pick a marginal file. The user's confidence in the recommendation is load-bearing.
Project resolution
Runs as step 0 of every invocation, before routing. Determines $PROJECT_ROOT — the directory whose .claude/tutorial-config.yaml this invocation reads from and writes to. Resolution must succeed before any other step runs; if it doesn't, the skill either runs first-run setup (if no project anywhere) or refuses (if multiple registered projects can't be disambiguated).
Discovery chain (highest precedence first)
--project-dirflag. If set on the invocation, treat `as$PROJECT_ROOTand stop. The path must be absolute or resolvable relative to cwd. If/.claude/tutorial-config.yamldoes not exist, the skill **does not** auto-create it from this flag — say--project-dir has no tutorial-creator config. Run "/skill tutorial-creator open " first, or invoke from to trigger first-run setup.and stop. The--project-dir` flag is for picking among already-set-up projects, not for bootstrapping new ones in unusual locations.- Environment variable
TUTORIAL_CREATOR_PROJECT_DIR. If set and points to a directory with.claude/tutorial-config.yaml, use it as$PROJECT_ROOT. If the env var is set but the path is invalid, warn (TUTORIAL_CREATOR_PROJECT_DIR= doesn't have a tutorial-creator config; ignoring) and fall through to the next step. - Cwd's
.claude/tutorial-config.yaml. If./.claude/tutorial-config.yamlexists in the current working directory, use cwd as$PROJECT_ROOT. This preserves backward compatibility with v1.1 / v2.0-pre-resolution behavior — if you're already in your project, nothing changes. - Ancestor walk from cwd. Walk up from cwd one directory at a time until either: (a) a
.claude/tutorial-config.yamlexists at that level — use that directory as$PROJECT_ROOT; (b) the filesystem root is reached — fall through to the next step. Stop at filesystem root, do NOT cross into another user's home directory or into/. - Registry lookup. Read
~/.claude/tutorial-creator/registry.yaml(per SCHEMAS.md Schema 5). If the file exists and:
- has exactly one project entry → use it as
$PROJECT_ROOT - has a
defaultfield pointing at a registered project → use it - has multiple projects with no default → prompt the user to pick one (and offer to set it as default for next time):
`` Multiple tutorial-creator projects registered. Pick one for this invocation: [1] /Volumes/.../Tutorials (last invoked: 2026-05-10) [2] /Users/me/Code/learn-rust (last invoked: 2026-04-15) [3] /Users/me/code-smarter (last invoked: 2026-03-22) Choose [1-3]; add --default` to also set this as the
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Terryc21
- Source: Terryc21/tutorial-creator
- License: Apache-2.0
- Homepage: https://github.com/Terryc21/tutorial-creator
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.