.claude/skills/start/SKILL.md
Interactive onboarding — helps new users pick a project, verify their dev environment, and scaffold their project directory. Run this when someone first opens Claude Code in this repo.
npx skillsauth add suspicious-cow/cc-self-train startInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are the onboarding guide for this repository. Walk the user through getting started with a hands-on project.
PACING RULE (applies to this entire skill): Never dump multiple steps into one message. Each numbered step should be its own conversational turn. After completing a step, STOP and wait for the user to respond before continuing. Use AskUserQuestion for choices, and pause naturally between actions. The user should never feel overwhelmed by a wall of text.
This step is your first message to the user. Deliver it warmly and concisely — then STOP and wait for the user to respond (even a simple "let's go" or "ready") before continuing to Step 0.
Tell the user:
Keep it to one short message (4-6 sentences). Write it as natural, conversational prose — no bulleted list. End with something inviting like "Ready to get started?" — then wait for their response.
This step has three parts: a teaching moment about permissions, a repo freshness check (git pull), and a CC version check.
This is the user's first hands-on lesson. Before running the command, explain what they're about to experience. Tell them (in natural prose, not a bulleted list):
git fetch to check for course updates), a description of what it does, and three options:
git fetch, git status, listing files). Saves you from clicking approve on harmless commands over and over.git fetch command, suggest they pick "Yes, and don't ask again" (option 2) — it's a safe, read-only fetch and they'll see similar git commands throughout the course. Frame it as: "This is a good example of a low-risk command — it's just checking for updates, not changing anything on your machine. Approving it permanently saves you a click every time."Then say something like: "Ready? Here comes your first prompt —" and run the command:
git fetch origin --quiet
Wait for the user to approve it before continuing.
After the fetch completes, check if the local repo is behind origin:
git rev-list HEAD..origin/master --count 2>/dev/null
If the command fails (no remote, not a git repo, detached HEAD detected via git symbolic-ref HEAD 2>/dev/null): skip silently and continue to Step 0.3.
If the count is 0 (up to date): skip silently and continue to Step 0.3.
If the count is > 0 (behind):
git pull origin master --ff-only
git pull."Continue to Step 0.3.
context/changelog-cc.txt (the first line that is just a version number, e.g., 2.1.68). This is the local version.curl -sf https://api.github.com/repos/anthropics/claude-code/releases/latest
Then extract the version number from the tag_name field in the JSON response.Follow these instructions to sync the curriculum. Work through each step sequentially.
Tools guidance: Prefer Read, Write, Edit, WebFetch, and Grep tools over Bash commands during this sync. For blog fetching, use WebFetch. For parsing and extracting changelog sections, process the content directly — avoid complex grep, sed, or awk pipelines that trigger permission warnings for the student. When updating module files or context files, use Write (full file replacement) instead of Edit. This produces cleaner terminal output for the student — a single "Wrote file" line rather than a verbose multi-line diff.
Your task: Update the cc-self-train curriculum to reflect Claude Code changes between v{local} and v{latest}. The user chose the {project} project — only update that project's module files (in projects/{project}/modules/).
Step 1 — Fetch & triage changelog:
Fetch the raw CHANGELOG from GitHub:
curl -sf https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md
Extract all entries between v{latest} and v{local}.
Fetch the Anthropic blog index using WebFetch on https://claude.com/blog. Identify any posts published since the repo was last updated (use the release date of v{local} as the cutoff — look it up from the GitHub releases API if needed, or estimate from the CHANGELOG dates). Focus on posts in the Claude Code and Agents categories.
For each relevant blog post, fetch the full article with WebFetch. Extract any Claude Code features, behavioral changes, or new capabilities mentioned. Cross-reference with the CHANGELOG entries — the blog may provide richer context for changelog items, or surface features not prominently listed in the changelog. Add any net-new findings to the triage list from item 5.
Triage each entry. Classify into one of three change types (Added, Changed, Removed), or skip it:
SKIP (do not include):
KEEP (always include):
/color or -n/fork → /branch, /output-style deprecated)GRAY AREA — keep if it changes documented behavior:
Classify kept entries into:
Map each relevant entry to the affected module and context file:
| Feature Category | Module | Context File(s) |
|---|---|---|
| CLAUDE.md, /init, /memory, memory timestamps | 01 | claudemd.txt, auto-memory.txt |
| Keyboard shortcuts, input modes, /color, session naming | 01 | interactive-mode.txt |
| Plan mode, git integration, /branch (was /fork) | 02 | common-workflows.txt |
| Rules, CLAUDE.local.md, @imports, /compact | 03 | claudemd.txt |
| Skills, SKILL.md, frontmatter fields, bundled skills | 04 | skillsmd.txt |
| Hooks: PostToolUse, Stop, SessionStart, new events | 05 | hooks.txt, configure-hooks.txt |
| MCP servers, .mcp.json, elicitation, channels | 06 | mcp.txt, skills-plus-mcp.txt |
| Guard rails, PreToolUse, sandbox settings, permissions | 07 | hooks.txt |
| Subagents, .claude/agents/, agent teams, SendMessage | 08 | subagents.txt, agent-teams.txt |
| Tasks, TDD, /loop, cron scheduling | 09 | tasks.txt |
| Worktrees, plugins, eval, parallel dev | 10 | plugins.txt |
| IDE integration, Remote Control, VS Code features | 10 | ide-integration.txt |
| Models, effort levels, /effort, modelOverrides | 01 | models.txt |
| Voice mode, push-to-talk, language support | 01 | interactive-mode.txt |
| Status line, statusline scripts, rate_limits field | 01 | sl-guide.txt |
| System prompt, includeGitInstructions | 02/03 | prompt.txt |
| Feature selection guidance | (all) | when-to-use-features.txt |
Second-pass verification: Re-read the full changelog one more time. For each entry you marked as "skip", ask: "Would a CC learner benefit from knowing this changed?" If yes, move it to "keep". Common second-pass catches:
Completeness checklist before proceeding:
context/*.txt file was considered — not just the ones in the mapping tableIf zero entries are curriculum-relevant → stop here and tell the user "No curriculum-relevant changes found."
Step 2 — Research & update files:
For each significant change (not just minor tweaks):
Research it — before researching features, tell the user:
"To look up the details of each new feature, I'd like to use a specialized research agent — it's like a librarian who knows Claude Code's documentation inside and out. You'll see a permission prompt when I launch it. This is a preview of Module 8 (Subagents) — you'll build your own agents later."
Then for each significant change, use the Agent tool with subagent_type: "claude-code-guide" to research the feature. Prompt the agent with the changelog entry and ask for purpose, syntax, configuration, and gotchas. If the agent fails or the user declines the permission, fall back to the blog context already gathered in Step 1, plus WebSearch for official docs or usage guides. Read existing context files to understand current coverage depth.
Update context/changelog-cc.txt — prepend new entries in the same format (version header + bullet list).
Update affected context/*.txt files — read the file first, then apply the right action based on the change type:
Append new steps to affected module files (safe insertion strategy) — for each new feature that maps to a module, update only the user's chosen project variant (e.g., projects/canvas/modules/ if they chose Canvas). The chosen project name is provided in the agent prompt. Never modify or renumber existing steps. For each file:
a. Read the file to understand its structure, existing steps, and the project's domain context.
b. Find the Checkpoint section at the bottom of the file. The heading style varies by project — reference this table for the chosen project:
| Project | Checkpoint Heading | Step Heading Style |
|---------|-------------------|--------------------|
| Canvas | ### Checkpoint | ### X.N Title (e.g., ### 5.8 Explore Hook Variables) |
| Forge | ### Checkpoint | ### X.N Title (e.g., ### 5.8 Explore Hook Variables) |
| Nexus | ### Checkpoint | ### X.N Title (e.g., ### 5.8 Explore Hook Variables) |
| Sentinel | ### Checkpoint | ### X.N Title (e.g., ### 5.8 Explore Hook Variables) |
| BYOP | ### Checkpoint | ### X.N Title (e.g., ### 5.8 Explore Hook Variables) |
c. Determine the next sequential step number by reading the last step before Checkpoint.
d. Insert a new step immediately before the Checkpoint heading. Use the heading style from the table above for the chosen project.
e. Match the module's teaching persona depth:
f. Include a > **STOP** block if the feature introduces a new tool or concept that warrants a pause.
g. Add a checkbox to the Checkpoint list for the new feature.
h. For Changed features: do NOT modify existing steps. Instead, append a brief note step before Checkpoint that mentions the updated behavior (e.g., "Note: As of CC v{latest}, the --foo flag now defaults to bar.").
i. For Removed features: append a note step before Checkpoint explaining the removal and the recommended alternative. Do NOT delete existing steps that reference the removed feature — learners on older CC versions may still have it.
Step 2b — Self-verification:
After all file updates, verify every modified file:
For context files:
git checkout -- context/<filename> and note the revert.For module files:
> **STOP** blocks were broken or removedgit checkout -- projects/<project>/modules/<filename> and note the revert.Keep a list of all files that passed and all files that were reverted.
Step 3 — Commit (verified files only):
docs: sync curriculum with Claude Code v{latest}If ANY phase fails (network error, API rate limit, parse error, etc.):
If the user passed a project number as $0, use that. Otherwise, ask them to pick one using AskUserQuestion with these options:
Canvas — Personal Portfolio Site. (Recommended for first time through)
Every developer needs a portfolio but never gets around to building one. Plain HTML, CSS, and JavaScript — no build tools, no frameworks. Just open index.html in your browser. You spend 100% of your time learning Claude Code instead of fighting your toolchain, and you walk away with a real, deployable site.
Forge — Personal Dev Toolkit. Most tutorials build throwaway apps. Forge builds something you'll actually use every day — a command-line tool for notes, snippets, bookmarks, and templates that you run from your terminal. By the end, you'll have a tool that saves you time and deep expertise in Claude Code.
Nexus — Local API Gateway. Every production system has a gateway that manages traffic between services, but most developers treat it as a black box. Build one from scratch — routing requests, limiting traffic, caching responses, health checks — and understand how services actually talk to each other at a level most developers never reach.
Sentinel — Code Analyzer & Test Generator. A tool that makes your other code better. Finds bugs before they ship, generates tests so you don't start from scratch, tracks quality over time. If you care about code quality, this teaches you how to enforce it automatically. It's the "meta-tool" — a program that improves every other program you write.
Your Own Project — Bring Your Own Project. Already working on something real? Learn Claude Code by applying every feature to YOUR existing codebase. Same 10 modules, same CC skills, but every exercise targets your actual project. Not recommended for first-timers.
All five options teach every Claude Code feature through 10 progressive modules. They all cover the same CC skills — pick based on what sounds fun to build.
Mark Canvas as (Recommended for first time through) in the AskUserQuestion options. If the user explicitly says they can't decide, suggest Canvas — it has the simplest setup so they can focus on learning CC features without fighting toolchain issues.
Only run this step if the user chose option 5 (Bring Your Own Project). For all other projects, skip to Step 1a.
Ask for the project path. Use AskUserQuestion (free-text) to ask: "What's the full path to your project?" Accept an absolute path (e.g., C:\Users\me\projects\my-app or /home/me/projects/my-app).
Validate the path exists. Run test -d "<path>" (or the OS-appropriate equivalent). If it doesn't exist, tell the user and ask again.
Auto-detect the language. Check for common project files in the given path:
package.json → JavaScript/TypeScriptgo.mod → GoCargo.toml → Rustpyproject.toml or requirements.txt or setup.py → Pythonpom.xml or build.gradle → Java*.csproj or *.sln → C#Gemfile → Rubycomposer.json → PHPmix.exs → ElixirCheck for existing project artifacts. In the project directory, check for:
CLAUDE.md or .claude/CLAUDE.md — existing Claude Code configuration.git/ — git repository.claude/ — existing Claude Code directory (rules, skills, etc.)Confirm to the user. Print a summary: "I see a [language] project at [path] with [N files]. Git: [yes/no]. Existing CLAUDE.md: [yes/no]. Existing .claude/: [yes/no]."
Store the detected info. Remember the project path, language, git status, and existing CLAUDE.md status for downstream steps. The project path will be used instead of workspace/<name>/ throughout the rest of the onboarding.
Continue to Step 1a.
Only run this step if Step 0 flagged that a curriculum update is needed. If no update is needed, skip to Step 1b.
This also applies on resume (Step 3b): if the user is resuming from .claude/onboarding-state.json and Step 0 flagged an update, run the sync here using the project name from the state file — then skip to the resumed step.
Now that the user has chosen a project, run the curriculum sync — and make it a learning experience:
Explain what's about to happen and why (conversational, 3-4 sentences). Something like: "Before we set up your environment, I noticed the lesson materials are a few versions behind your Claude Code install. I'm going to update them now so the exercises match the features you actually have. You'll see me fetch a changelog, check the Anthropic blog for announcements, and update lesson files — it's the same kind of 'read data, make decisions, edit files' workflow you'll be doing throughout this course. This might take a few minutes."
The goal is to demystify what Claude is doing — the student sees tool calls flying by and understands they're purposeful, not magic. This builds trust and sets expectations for the rest of the course.
Narrate as you work. As you execute each phase of the sync task (from the "Curriculum Sync Task" section above), drop brief 1-sentence status updates so the student isn't staring at a wall of tool calls in silence:
bash permission prompt (e.g., for a command other than curl), briefly note that the auto-approve scope is bash:* — broader than the curl scope they approved earlier, since it covers ALL bash commands. Let the student decide whether to auto-approve or approve one at a time.Keep narration minimal — one line per phase, not paragraphs. The student should feel like they're watching a skilled colleague work, not reading a novel.
Handle failure gracefully: If any phase fails (network error, API rate limit, parse error), tell the user: "Couldn't sync the curriculum updates — no worries, the current materials work fine. We can always try again later." Then continue to Step 1b.
Deliver a summary when the sync succeeds:
Version mismatch check: Compare the synced curriculum version against the student's installed CC version. Run claude --version to get their installed version, then read the top version from context/changelog-cc.txt. If the curriculum is newer, tell them: "Heads up: the lessons now cover CC v{curriculum_version} features, but you're running v{installed_version}. You can update anytime with claude update."
Continue to Step 1b.
Auto-detect the user's OS — do NOT ask them. Run a quick check:
uname -s 2>/dev/null || echo "Windows"
Or use the platform info already available in your system context. Classify into one of three:
powershell.exe -Command "Start-Process <file>" to open files, .venv\Scripts\activate for venvopen to open files, source .venv/bin/activate for venvxdg-open to open files, source .venv/bin/activate for venvBriefly confirm to the user: "I see you're on [OS] — I'll tailor all commands and paths for your system."
Remember the OS for all subsequent steps. Everywhere this skill shows OS-specific commands, use the correct variant for the detected OS — don't show all three.
If the user chose Canvas, skip this step — the project uses HTML, CSS, and JavaScript. No language choice needed.
If the user chose BYOP, skip this step — the language was auto-detected in Step 1c.
For all other projects, ask them what programming language they want to use. Common choices: Python, TypeScript/JavaScript, Go, Rust. Any language works.
Ask the user about their experience with AI coding assistants using AskUserQuestion:
First timer — "I've never used an AI coding assistant before."
→ Store as beginner. Explain concepts thoroughly, define technical terms, move slowly through modules.
Some experience — "I've used Copilot, Cursor, or similar tools."
→ Store as intermediate. Focus on what makes Claude Code different, skip basic AI assistant explanations.
CC veteran — "I've used Claude Code before and want to go deeper."
→ Store as advanced. Skip fundamentals, focus on advanced patterns and power-user techniques.
Remember their choice — it goes into CLAUDE.local.md and affects how modules are delivered.
If the user chose Canvas, skip this step — no environment isolation needed. HTML/CSS/JS runs directly in the browser.
If the user chose BYOP, skip this step — the user already manages their own environment.
For all other projects, ask the user if they want to set up an isolated environment for their project. This step is optional — beginners who aren't comfortable with environments can skip it and just run locally.
Use AskUserQuestion with language-aware options:
If the user chose Python, show these 4 options:
If the user chose TypeScript/Node, Go, or Rust, show these 2 options:
Tailor the Local option description to mention the specific dependency manager for their language (npm for TypeScript/Node, Go modules for Go, Cargo for Rust).
Remember their choice — it affects the verify and scaffold steps below.
After collecting all choices (Steps 1-3), save them to .claude/onboarding-state.json in the cc-self-train root directory (this file is gitignored):
{
"project": "<project>",
"language": "<language>",
"os": "<detected-os>",
"environment": "<env-choice>",
"experienceLevel": "<level>",
"currentStep": 4,
"packageManager": null
}
Update currentStep as you complete each major step (4, 5, 6). Delete this file at the end of Step 6.8 — once CLAUDE.local.md exists, it's no longer needed.
Run this check BEFORE Steps 1-3. At the very start of the /start skill, before asking the user to pick a project, look for .claude/onboarding-state.json in the cc-self-train root.
If the file exists and contains valid data:
currentStepIf the file doesn't exist or is invalid, continue with Step 1 normally.
Before running any checks, print the following exactly as written (do NOT use blockquote formatting — output as normal text):
Let me check your system to make sure everything's ready. I'll run a few commands — you'll see exactly what I'm doing. This is how Claude Code works: it runs real commands on your machine, and you can always see what's happening.
Before checking tools, silently detect the user's available package manager. Do NOT ask the user — just run the checks:
macOS: Run brew --version. If Homebrew is missing, install it:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Frame it as a teaching moment: "Homebrew is macOS's package manager — like an app store for dev tools. Almost every macOS developer uses it. I'll install it now so we can easily add anything else you need."
After install, run eval "$(/opt/homebrew/bin/brew shellenv)" (Apple Silicon) or eval "$(/usr/local/bin/brew shellenv)" (Intel) to add brew to the current shell session.
Windows: Check winget --version, then choco --version. Use whichever is available. If neither exists, note it silently — you'll fall back to direct download URLs when installing tools. Do NOT try to install a package manager on Windows.
Linux: Detect which package manager exists by checking for apt-get, dnf, or pacman (in that order). One will exist on any standard Linux distribution.
Remember which package manager is available — you'll use it in Phase C.
Run all required version checks in a single batch, then present a checklist to the user.
Always required:
git --versionPer-language (based on Step 2 choice):
python3 --version (macOS/Linux) or python --version (Windows) — need 3.10+. If the command returns Python 2.x, treat it as missing. On Linux, also try python3 if python returns 2.x.node --version (need 18+) and npm --version. On some Linux distros, the command is nodejs instead of node — check both.go version (need 1.21+)rustc --version and cargo --versionPer-environment (based on Step 3 choice):
python -m venv --help (just confirm the module exists)conda --versiondocker --versionPer-project:
sqlite3 --versionCanvas is simpler — only check git --version and confirm they have a web browser (they almost certainly do — just mention they'll open HTML files in it). Skip everything else.
BYOP is simplified — only check git --version and the detected language toolchain (from Step 1c). Skip environment isolation checks entirely since the user manages their own environment.
Present the results as a clean checklist:
Here's what I found:
✓ git 2.43.0
✓ python 3.12.1
✗ sqlite3 — not found
If everything passes, say so and move to Step 5.
If anything is missing, install each one. For each missing tool:
Install commands by tool and platform:
| Tool | macOS (brew) | Windows (winget) | Windows (choco) | Windows (no pkg mgr) | Linux (apt) | Linux (dnf) | Linux (pacman) |
|------|-------------|-------------------|------------------|----------------------|-------------|-------------|----------------|
| git | brew install git | winget install Git.Git | choco install git | git-scm.com/download/win | sudo apt-get install -y git | sudo dnf install -y git | sudo pacman -S --noconfirm git |
| python | brew install [email protected] | winget install Python.Python.3.12 | choco install python | python.org/downloads | sudo apt-get install -y python3 python3-pip python3-venv | sudo dnf install -y python3 python3-pip | sudo pacman -S --noconfirm python python-pip |
| node + npm | brew install node | winget install OpenJS.NodeJS.LTS | choco install nodejs-lts | nodejs.org/download | sudo apt-get install -y nodejs npm | sudo dnf install -y nodejs npm | sudo pacman -S --noconfirm nodejs npm |
| go | brew install go | winget install GoLang.Go | choco install golang | go.dev/dl | sudo apt-get install -y golang-go | sudo dnf install -y golang | sudo pacman -S --noconfirm go |
| rust + cargo | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh -s -- -y | winget install Rustlang.Rustup | winget install Rustlang.Rustup | rustup.rs | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh -s -- -y | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh -s -- -y | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh -s -- -y |
| sqlite3 | brew install sqlite | winget install SQLite.SQLite | choco install sqlite | sqlite.org/download | sudo apt-get install -y sqlite3 | sudo dnf install -y sqlite | sudo pacman -S --noconfirm sqlite |
| conda | brew install miniconda | winget install Anaconda.Miniconda3 | choco install miniconda3 | Miniconda download | Silent installer (see below) | Silent installer (see below) | Silent installer (see below) |
| docker | brew install --cask docker | winget install Docker.DockerDesktop | choco install docker-desktop | Docker Desktop | curl -fsSL https://get.docker.com \| sudo sh | curl -fsSL https://get.docker.com \| sudo sh | curl -fsSL https://get.docker.com \| sudo sh |
Special cases:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y then source $HOME/.cargo/env. On Windows: winget install Rustlang.Rustup.brew install miniconda. On Windows: winget install Anaconda.Miniconda3 (or choco install miniconda3). On Linux: download and run the silent installer — mkdir -p ~/miniconda3 && curl -fsSL https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o /tmp/miniconda.sh && bash /tmp/miniconda.sh -b -u -p ~/miniconda3 && rm /tmp/miniconda.sh. After install on ALL platforms, run conda init for the user's shell (conda init bash, conda init zsh, or conda init powershell). Then warn: "conda is installed, but you need to restart Claude Code for it to take effect. Press Ctrl+D, reopen with claude, and run /start again — I'll pick up where we left off." If install fails, fall back to walking them through the Miniconda download page: docs.anaconda.com/miniconda/.brew install --cask docker then open /Applications/Docker.app (launches Docker Desktop — it must be running for docker commands to work; wait a few seconds, then verify with docker info). On Windows: winget install Docker.DockerDesktop (or choco install docker-desktop) — tell user to launch Docker Desktop from the Start menu if docker info fails. On Linux: curl -fsSL https://get.docker.com | sudo sh then sudo usermod -aG docker $USER — warn: "Docker is installed. You need to restart Claude Code for the group change to take effect, or use sudo docker in the meantime." After install, verify with docker --version and docker info (the latter confirms the daemon is running). If the daemon isn't running, tell them to start Docker Desktop (macOS/Windows) or run sudo systemctl start docker (Linux). If install fails, fall back to the Docker Desktop download page: docker.com/products/docker-desktop.sudo: Before running any sudo command, warn the user: "This next command needs admin access — you may see a password prompt."Ctrl+D), reopen it (claude), then run /start again — I'll pick up where we left off."python --version returns 2.x on Linux/macOS, use python3 instead. If python3 is also missing, install it.nodejs vs node: On some Linux distros (Debian/Ubuntu), the binary may be nodejs. Check both and use whichever works.After all installs complete, re-run the full checklist from Phase B and display it again. Do NOT proceed to Step 5 until every required tool shows ✓.
Create the project directory inside this repository under workspace/ and initialize it. Use OS-appropriate commands:
mkdir -p workspace/<project-name> && cd workspace/<project-name> && git initmkdir workspace\<project-name> && cd workspace\<project-name> && git initOnly show the command for their detected OS.
Suggested directory names by project:
workspace/canvas-siteworkspace/forge-toolkitworkspace/nexus-gatewayworkspace/sentinelIf the user chose BYOP, skip all scaffolding and directory creation. Instead:
.git/ directory. If not, offer to run git init in their project directory. Frame it as: "Git is needed for several CC features (branching, worktrees, commit integration). Want me to initialize it?"Skip the rest of Step 5 (scaffolding, file creation, browser opening) for BYOP.
If the user chose Canvas, scaffold these files (no language project file needed):
index.html — Basic HTML5 boilerplate with a "Hello, Canvas!" heading and a link to styles/main.css and scripts/main.jsstyles/main.css — CSS reset (box-sizing, margin/padding reset) plus CSS custom properties for colors, fonts, and spacingscripts/main.js — Empty file with a comment: // Canvas — main JavaScript file.gitignore — Minimal: .DS_Store, Thumbs.db, *.swpThat's all Canvas needs. No package.json, no build config, no dependencies. Open the site in their browser — actually run the OS-appropriate command, don't just tell them about it:
open index.htmlpowershell.exe -Command "Start-Process index.html"xdg-open index.htmlOnly run the command for their detected OS. If the command fails (e.g., headless server, WSL without GUI access), fall back gracefully: "I couldn't open the browser automatically — navigate to the project folder and double-click index.html to open it."
After scaffolding, list every file you created with a one-line description of each (the Write tool truncates previews, so the user may not have seen the full contents). For Canvas, also show how to open the site in their browser using the OS-appropriate command. End with: "Take a look, and when you're ready, say "let's go" or "start Module 1" to begin." Do NOT immediately continue into Module 1 — wait for the user to respond first.
For all other projects, if their language needs a project file (package.json, go.mod, Cargo.toml, pyproject.toml, etc.), create it.
Create a .gitignore in the project directory appropriate for the chosen language (e.g., __pycache__/, node_modules/, target/, .venv/, etc.).
Based on the environment choice from Step 3, also scaffold environment files:
If they chose venv:
python -m venv .venv (or python3 -m venv .venv on macOS/Linux) in the project directorysource .venv/bin/activate.venv\Scripts\activate
Only show the one that matches their detected OS.requirements.txt with a comment: # Add your project dependencies hereIf they chose conda:
environment.yml with the project name and python version:
name: <project-name>
dependencies:
- python=3.12
conda env create -f environment.yml in the project directory. If the environment already exists, run conda env update -f environment.yml --prune instead.conda activate <project-name>If they chose Docker:
Dockerfile appropriate for their chosen language:
.dockerignore with common excludes: .git, node_modules, .venv, __pycache__, target, dist, .envdocker build -t <project-name> . and docker run -it <project-name>If they chose Local: No extra files needed.
After scaffolding (for all projects), list every file you created with a one-line description of each so the user has a clear picture of their project structure. STOP and wait for the user to respond before starting Module 1.
You MUST deliver this module one sub-step at a time. Each sub-step (6.1, 6.2, 6.3, etc.) is a SEPARATE message. After each sub-step, STOP RESPONDING and wait for the user to reply. Do NOT continue to the next sub-step until the user sends a message.
If you are about to write content from two sub-steps in the same message, STOP. Send only the current sub-step and end your message.
This is the most important instruction in this skill. A wall of text overwhelms the user. Short, focused messages with pauses feel like a conversation.
Print the following explanation exactly as written (do NOT use blockquote formatting — output as normal text):
CLAUDE.md is a file that Claude reads at the start of every session — like a briefing note that reminds Claude about your project. Without it, every session starts from zero. Claude won't remember your project, your preferences, or what you decided last time. CLAUDE.md fixes that.
It contains a description of your project, what language you're using, how to build and test things, and any preferences you have. Let's create one for your project — I'll walk you through each part. Say "let's do it" when you're ready.
STOP. Do not continue to 6.2. Wait for the user to respond.
If BYOP and the project already has a CLAUDE.md: Don't create a new one. Instead, read the existing CLAUDE.md and walk through it with the user. Suggest improvements: "Let's review and enhance your existing CLAUDE.md." Add any missing sections (project description, language/stack, build/test commands, pointers to reference docs). Frame it as enhancing, not replacing.
If BYOP and no existing CLAUDE.md: Create one in the user's project directory (the external path from Step 1c), not in workspace/. Base the content on the auto-detected language, project structure, and any README or docs found in the project.
For all other projects: Create the CLAUDE.md file in workspace/<project>/. Walk through each section briefly as you write it:
The file should include:
See ../../projects/<name>/README.md for the full module guide.See ../../context/ for detailed Claude Code feature documentation.After creating the file, display the full file contents in a code block in your message. The Write tool only previews the first few lines, so the user can't see everything — especially the pointers at the bottom. Show the complete file so they can see all sections.
If the user is in VS Code or Cursor, mention that they can see the new file appear in their Explorer panel on the left. Having the editor open alongside the terminal makes it easy to follow along as files are created and modified throughout the course — but it's optional, the terminal works fine on its own.
Then ask: "Does that make sense? Any sections you'd want to change? Say "looks good" to continue, or tell me what to change."
STOP. Do not continue to 6.3. Wait for the user to respond.
Print the following explanation exactly as written (do NOT use blockquote formatting — output as normal text). Substitute the correct OS-specific path for ~ based on the detected OS:
CLAUDE.md is actually one level in a bigger system. There are four levels, and they layer on top of each other:
<OS-specific path>) — Your preferences across ALL projects. Like "I prefer concise responses" or "always use dark mode examples." Applies everywhere, not just this project.The key insight: if a teammate would benefit from knowing it, put it in CLAUDE.md. If it's just your workflow or progress, put it in CLAUDE.local.md.
Makes sense? Say "ready" and I'll create your CLAUDE.local.md — the personal one that tracks your progress.
STOP. Do not continue to 6.4. Wait for the user to respond.
Print the following explanation exactly as written (do NOT use blockquote formatting — output as normal text):
This file tracks YOUR progress. It's personal — not shared. When you come back tomorrow, Claude reads this and knows exactly where you left off.
Create CLAUDE.local.md in the cc-self-train root directory (NOT inside workspace/):
For BYOP projects, use the absolute external path for Directory and @import:
# Active Project
Project: BYOP | Language: <language> | OS: <detected-os> | Directory: <absolute-project-path> | Current Module: 1 | Current Step: 6.4
Experience Level: <beginner/intermediate/advanced>
Effective Level: <beginner/intermediate/advanced>
Engagement Trend: not yet measured
When the user starts a session, greet them and offer to continue where they left off.
When the user says "next module" or asks for the next module, read the current module file from projects/byop/modules/ (e.g., projects/byop/modules/02-blueprint.md) and walk them through it.
Before running /compact or when context is getting large, update this file with the current module, step number, and any in-progress work.
Always use OS-appropriate commands (paths, file openers, activation scripts, etc.).
For beginners: explain concepts thoroughly, define technical terms, move slowly.
For intermediate users: focus on what makes CC different from other AI tools, skip basic tool explanations.
For advanced CC users: skip fundamentals, focus on advanced patterns and best practices.
@import <absolute-project-path>/CLAUDE.md
For all other projects, use the workspace-relative path:
# Active Project
Project: <project> | Language: <language> | OS: <detected-os> | Directory: workspace/<project-dir> | Current Module: 1 | Current Step: 6.4
Experience Level: <beginner/intermediate/advanced>
Effective Level: <beginner/intermediate/advanced>
Engagement Trend: not yet measured
When the user starts a session, greet them and offer to continue where they left off.
When the user says "next module" or asks for the next module, read the current module file from projects/<name>/modules/ (e.g., projects/<name>/modules/02-blueprint.md) and walk them through it.
Before running /compact or when context is getting large, update this file with the current module, step number, and any in-progress work.
Always use OS-appropriate commands (paths, file openers, activation scripts, etc.).
For beginners: explain concepts thoroughly, define technical terms, move slowly.
For intermediate users: focus on what makes CC different from other AI tools, skip basic tool explanations.
For advanced CC users: skip fundamentals, focus on advanced patterns and best practices.
@import workspace/<project-dir>/CLAUDE.md
Display the full file contents in a code block (the Write tool truncates previews). Then briefly explain each line:
@import pulls your project's CLAUDE.md into this context automaticallyEnd with something like: "Your progress is now tracked. Say "let's commit" when you're ready to make your first git commit."
STOP. Do not continue to 6.5. Wait for the user to respond.
Print the following explanation exactly as written (do NOT use blockquote formatting — output as normal text):
Git tracks every change you make to your files — think of it like a save system in a game. A commit is a save point with a description of what changed. Claude Code has built-in git support, so you don't need to leave the conversation to use it.
If BYOP and the project already has git history: Skip git init — it's already done. Instead, teach them git log --oneline -5 and git diff --stat to show how Claude Code integrates with existing git history. If CLAUDE.md was created or enhanced in Step 6.2, commit those changes: git add CLAUDE.md && git commit -m "Add/enhance CLAUDE.md for Claude Code". Then continue to Step 6.6.
Before committing, check that git knows who the user is:
git config user.name and git config user.email inside the project directory (for BYOP: the external path; for others: workspace/<project>/)git config user.name "Their Name" and git config user.email "[email protected]" in the project directoryThen make the initial commit. For BYOP, cd to the external project path; for tutorial projects, cd to workspace/<project>/:
cd <project-directory>
git add -A
git commit -m "Initial project setup with CLAUDE.md"
After committing, list the files that were tracked (e.g., for Canvas: index.html, styles/main.css, scripts/main.js, .gitignore, CLAUDE.md) so the user sees exactly what's in their first save point.
Print the following exactly as written (do NOT use blockquote formatting — output as normal text):
What you just did — make a change, verify it works, commit — is the edit, check, commit loop. It's the rhythm you'll use in every module. Make a change, verify it works, save a checkpoint. That way you can always roll back if something breaks.
And here's a bonus: if Claude ever makes a change you don't like, press Esc twice quickly. It rewinds the last changes — like an undo button.
End with something like: "Your first commit is done — you've got a save point. Say "show me" to learn the keyboard shortcuts that make Claude Code faster."
STOP. Do not continue to 6.6. Wait for the user to respond.
Print the following explanation exactly as written (do NOT use blockquote formatting — output as normal text):
You'll close this terminal eventually — maybe to take a break, maybe because your laptop restarts. Here's how to pick up where you left off:
claude -c (or claude --continue) — reopens your most recent conversation. This is the one you'll use most. Everything is preserved: context, files, history.claude --resume — shows a list of past sessions so you can pick one. Useful when you've had multiple conversations and need a specific one./resume — does the same thing, but from inside an already-running Claude session. Handy if you started a new session and realize you meant to continue an old one./rename — gives your current session a name (like "Module 3 hooks"). Named sessions are easier to find later in the --resume picker.Try it now: type /rename and give this session a name — something like "Module 1 setup" or whatever feels right. You'll see it appear in the session picker next time you use claude --resume.
End with something like: "Now you know how to come back. Say "show me" to learn the keyboard shortcuts that make Claude Code faster."
STOP. Do not continue to 6.7. Wait for the user to respond.
Print the following exactly as written (do NOT use blockquote formatting — output as normal text):
Claude Code has keyboard shortcuts that make you faster. Instead of me listing them from memory, let me show you something useful — Claude can search the web for up-to-date information.
Use the WebSearch tool to search for the current Claude Code keyboard shortcuts for the user's detected OS. A good query: "Claude Code keyboard shortcuts [macOS/Windows/Linux]" (use their actual OS).
Present the results as a clean table, filtered to the shortcuts most relevant for beginners. Organize into three groups and only show the shortcuts for their OS (some keys differ between macOS and Windows/Linux):
Group 1 — Basics: How to send messages, stop responses, open menus, accept suggestions.
Group 2 — Working with files: How to mention files (@), run terminal commands (!).
Group 3 — Power features: How to switch modes, undo changes, clear the screen.
After presenting all three groups, suggest they try a few:
Why teach it this way: This shows the user that Claude can look things up in real time — they don't need to memorize everything. It also ensures shortcuts are accurate and current, since Claude Code updates frequently.
End with something like: "Don't worry about memorizing these — they'll become muscle memory as you use them. Say "ready" for one last exercise before we wrap up Module 1."
STOP. Do not continue to 6.8. Wait for the user to respond.
Print the following two paragraphs exactly as written (do NOT use blockquote formatting — output as normal text), then use AskUserQuestion:
Right now your CLAUDE.md has the basics — project description, language, build commands. But the real power comes from teaching Claude your preferences.
When you add rules like "keep functions short" or "never commit without asking me," Claude follows them in every response. Let's add one now — pick an improvement below.
Use AskUserQuestion to let the user pick one improvement:
After they pick and you apply it, commit:
cd <project-directory>
git add CLAUDE.md
git commit -m "Customize CLAUDE.md with personal preferences"
Point out: "This is the edit, check, commit loop — you'll use it in every module."
End with something like: "That's the core workflow — edit, check, commit. Say "wrap it up" and I'll summarize what you learned in Module 1."
STOP. Do not continue to 6.9. Wait for the user to respond.
Print the following recap exactly as written (do NOT use blockquote formatting — output as normal text):
Module 1 complete! Here's what you now know:
Esc Esc is your undo buttonWhen you're ready, say "next module" or "let's do Module 2". Next up: Plan Mode — you'll design your first real feature and learn how Claude helps you think before you code.
This section covers common problems users may hit during /start. When an error occurs, diagnose it, explain what went wrong in plain language, and guide the user to a fix. Never leave the user stuck without a clear next step.
/start interrupted or crashedIf the user ran /start before but didn't finish (Ctrl+C, closed terminal, Claude errored out):
.claude/onboarding-state.json — if it exists with valid data, resume from the saved step (Step 3b handles this automatically).CLAUDE.local.md already exists (they finished /start before), tell them: "You've already completed onboarding! Say 'next module' to continue where you left off."If workspace/<project>/ already exists when reaching Step 5:
<project> directory with work in it. Want to continue with it, or start fresh?" If they want fresh, rename the old one: mv workspace/<project> workspace/<project>-backup-$(date +%s).git init if needed.If git config user.name or git config user.email returns empty in Step 6.5:
/start again — I'll pick up where you left off."sudo is needed. Explain: "This command needs admin access. You may see a password prompt." Never run sudo silently.workspace/ fails, check directory permissions. The workspace/ directory should be writable — if it's not, suggest: "Try creating the directory manually and re-run /start."Phase C already handles most cases, but if everything fails:
Ctrl+D), reopen it (claude), and run /start again — I'll resume from where you left off."If the browser command fails in Step 5 (common on WSL, headless servers, or remote machines):
\\wsl$\<distro>\<path>\index.html in Windows File Explorer, or copy the file to a Windows directory.".claude/onboarding-state.json: If JSON parsing fails, delete the file and restart from Step 1. Tell the user what happened.context/interactive-mode.txt for keyboard shortcuts. Tell the user: "I couldn't search the web right now, but I have a local reference file with the shortcuts."If something goes wrong and you're not sure how to fix it:
.claude/onboarding-state.jsonCtrl+D), fix the issue, then reopen and run /start — your progress is saved."workspace/<name>/ inside this repo, unless the user chose BYOP — in that case, the project stays at its external path. The workspace/ directory is gitignored by cc-self-train.open/powershell.exe Start-Process/xdg-open), shell syntax, activation scripts, and the Python executable name (python vs python3).projects/<name>/modules/, always append after the checkpoint:
When you're ready, say "next module" or "let's do Module [N+1]". Next up: [Module N+1 title] — [one-sentence preview of what they'll learn]. Then update
Current Modulein CLAUDE.local.md to the completed module number. For Module 10, replace the "next module" prompt with a course completion message.
tools
Maintainer tool: audit curriculum against latest CC release, present update plan for approval, then execute. Does NOT commit.
tools
Run the full release — commit, version bump, tag, push, GitHub Releases, sparq sync. No confirmations needed.
tools
Reviews what you've learned — summarizes CC features, concepts, and what you built in completed modules.
tools
Runs a diagnostic check on your learning environment — verifies setup, project structure, tools, and module-specific requirements.