diff --git a/CHANGELOG.md b/CHANGELOG.md index 40531b7..8cf2785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to `tutorial-creator` are documented here. This project adheres to [Semantic Versioning](https://semver.org/) and the format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [Unreleased] + +### Added + +- **Codex support.** The skill now documents Codex installation and `$tutorial-creator` + invocation, includes Codex UI metadata, and renders follow-up commands using the + active runtime's syntax. + +### Changed + +- Claude Code and Codex deliberately share the existing `.claude/` project state and + registry paths, preserving one tutorial history when users switch agents. +- Skill frontmatter now keeps version and author under the portable `metadata` key so + it validates under the Agent Skills format while retaining the same information. + ## [2.0.1] — 2026-08-09 A documentation and correctness patch. No new features; the surfaces, entry points, and schemas are unchanged from 2.0.0. Every item below was found by an audit pass over the shipped spec. diff --git a/README.md b/README.md index 428d20c..9530891 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Works with Swift, TypeScript, Python, and Rust. ## Try it +### Claude Code + ```bash /plugin marketplace add Terryc21/tutorial-creator /plugin install tutorial-creator@tutorial-creator @@ -27,6 +29,22 @@ Then, in any Claude Code session: /skill tutorial-creator ``` +### Codex + +Clone the repository and link the skill folder into your personal Codex skills: + +```bash +git clone https://github.com/Terryc21/tutorial-creator ~/src/tutorial-creator +mkdir -p ~/.codex/skills +ln -s ~/src/tutorial-creator/skills/tutorial-creator ~/.codex/skills/tutorial-creator +``` + +Then, in Codex: + +``` +$tutorial-creator +``` + Pick **"Write a tutorial for myself"**, then **"Topic + file"**, and point it at any file you've worked on recently. About ten minutes later you have a real lesson. @@ -42,17 +60,24 @@ won't find it. git clone https://github.com/Terryc21/tutorial-creator ~/src/tutorial-creator && ln -s ~/src/tutorial-creator/skills/tutorial-creator ~/.claude/skills/tutorial-creator ``` -For one project only, link into that project's skills folder instead: +For one Claude Code project only, link into that project's skills folder instead: ```bash mkdir -p /path/to/project/.claude/skills && ln -s ~/src/tutorial-creator/skills/tutorial-creator /path/to/project/.claude/skills/tutorial-creator ``` +For one Codex project only, link into that project's agent skills folder instead: + +```bash +mkdir -p /path/to/project/.agents/skills && ln -s ~/src/tutorial-creator/skills/tutorial-creator /path/to/project/.agents/skills/tutorial-creator +``` + -**New to Claude Code?** A *skill* is a set of written instructions Claude Code knows how -to follow. Type `/skill tutorial-creator` and it asks what you want, then does it. There -is nothing to memorise — it walks you through every choice. +**New to agent skills?** A *skill* is a set of written instructions an agent knows how +to follow. Type `/skill tutorial-creator` in Claude Code or `$tutorial-creator` in Codex +and it asks what you want, then does it. There is nothing to memorise — it walks you +through every choice. --- diff --git a/USAGE.md b/USAGE.md index 8ddbad8..70a8962 100644 --- a/USAGE.md +++ b/USAGE.md @@ -20,8 +20,10 @@ Every command, setting, and option. If you just want to try the skill, the ## Commands -Type `/skill tutorial-creator` on its own and the skill asks what you want. Everything -below is a shortcut for people who already know. +Invoke the skill with `/skill tutorial-creator` in Claude Code or `$tutorial-creator` +in Codex. The examples below use the Claude Code spelling; in Codex, replace +`/skill tutorial-creator` with `$tutorial-creator`. Invoke it without arguments and the +skill asks what you want. Everything below is a shortcut for people who already know. ``` /skill tutorial-creator # ask me what I want to do @@ -203,7 +205,10 @@ The first time you run it, the skill asks five things: 4. How experienced you are 5. Which code you're learning from, if that's a different folder -Your answers go in `.claude/tutorial-config.yaml`. Edit it any time. +Your answers go in `.claude/tutorial-config.yaml`. Edit it any time. The same file is +used from Claude Code and Codex, so switching agents preserves your tutorials, +vocabulary, and progress. The directory name is retained for backward compatibility; +Codex treats it as tutorial-creator data, not as Codex configuration. One thing to know: that file goes **in the project folder you chose**, which isn't necessarily the folder you were sitting in when you ran the command. The skill then diff --git a/skills/tutorial-creator/AUDIENCE.md b/skills/tutorial-creator/AUDIENCE.md index 443a930..9a93e11 100644 --- a/skills/tutorial-creator/AUDIENCE.md +++ b/skills/tutorial-creator/AUDIENCE.md @@ -30,7 +30,7 @@ Future audits may flag these as "missing"; they are deliberate choices for Path 1. **Read config.** `.claude/tutorial-config.yaml`. Required fields: `language`, `project_dir`. `experience_level` is read but the audience-facing render uses the audience answer (step 4) instead. 2. **Receive topic + source.** The user provides both. If only one is provided, route them to entry [c] (synthesized example) for topic-only, or ask for a topic for source-only. 3. **Read the source file.** Identify the line range that demonstrates the topic (use the same matching heuristic as SKILL.md Entry [c] step 3, but skip the candidate-ranking step; the user has already chosen the file). -4. **Ask the four routing questions.** Via AskUserQuestion, in this order: +4. **Ask the four routing questions.** Use the runtime's structured question tool or plain text, in this order: - **Audience:** beginner / intermediate / senior / mixed - **Honest-machine opt-in:** Y / N (asks "Append a section on what this article does NOT cover and what's still uncertain?") - **Length budget:** S / M / L / X (show the venue's word count for each tier, resolved from `venues/_schema.yaml` — that file is authoritative if it ever disagrees with a venue file's front-matter or calibration table) @@ -44,7 +44,7 @@ Future audits may flag these as "missing"; they are deliberate choices for Path - `length_budget` (one of S/M/L/X, with resolved word target + ceiling) - `honest_machine_optin` (boolean) - The user's `vocabulary.yaml` (for terminology alignment) -6. **Write the artifact.** Save to a path the user picks (default: `./audience-artifacts/-.md`). The skill does not insert the artifact into a venue's CMS or post it; the user does that step manually. Tell the user, in one line, that the artifact is not session-logged and `/skill tutorial-creator undo` will not revert it (that command reverts the last *tutorial* generation, a different file) — to remove it, delete the file directly. See `## Asymmetries with Path 1` for why Path 2 has no recovery hook. +6. **Write the artifact.** Save to a path the user picks (default: `./audience-artifacts/-.md`). The skill does not insert the artifact into a venue's CMS or post it; the user does that step manually. Tell the user, in one line, that the artifact is not session-logged and ` undo` will not revert it (that command reverts the last *tutorial* generation, a different file) — render `` for the current runtime, and tell the user to delete the artifact directly if they want to remove it. See `## Asymmetries with Path 1` for why Path 2 has no recovery hook. ### Honesty rule diff --git a/skills/tutorial-creator/SCHEMAS.md b/skills/tutorial-creator/SCHEMAS.md index c76a201..92092e9 100644 --- a/skills/tutorial-creator/SCHEMAS.md +++ b/skills/tutorial-creator/SCHEMAS.md @@ -7,6 +7,10 @@ when a schema changes, update this file first, then the surfaces that touch it. **Status:** v2.0 baseline. Versioned at the bottom of each schema. **Last updated:** 2026-05-10 (Phase 6.5: Schema 5 added for cross-project registry; `$PROJECT_ROOT` clarified throughout). +The `.claude/` locations below are tutorial-creator's established data paths, shared by +Claude Code and Codex. The name is retained for backward compatibility so both runtimes +read and update the same learning history. + --- ## Files at a glance @@ -315,7 +319,7 @@ The registry is a single-writer file. The skill does not currently take a lock w ### Why not just walk to a known location? -An earlier design considered "always look at `~/.claude/tutorial-creator//` for configs." The registry is a cleaner separation: configs stay with their projects (so a project moves with a `git mv` or `mv` of the project directory), and the registry is just a pointer table. Same separation `git` uses between `.git/` directories and a hypothetical `git config --global` registry — except `git` doesn't actually need a registry because it always operates on cwd. tutorial-creator does need one because invocations from arbitrary cwds are the common case (`/skill tutorial-creator status` from anywhere should work). +An earlier design considered "always look at `~/.claude/tutorial-creator//` for configs." The registry is a cleaner separation: configs stay with their projects (so a project moves with a `git mv` or `mv` of the project directory), and the registry is just a pointer table. Same separation `git` uses between `.git/` directories and a hypothetical `git config --global` registry — except `git` doesn't actually need a registry because it always operates on cwd. tutorial-creator does need one because invocations from arbitrary cwds are the common case (`status` from anywhere should work). ### v1 → future migration diff --git a/skills/tutorial-creator/SKILL.md b/skills/tutorial-creator/SKILL.md index 6d30b4b..058d9c6 100644 --- a/skills/tutorial-creator/SKILL.md +++ b/skills/tutorial-creator/SKILL.md @@ -1,9 +1,10 @@ --- name: tutorial-creator description: Generate annotated code reading tutorials from your own codebase. Three surfaces - tutorial generation, vocabulary management, and learning-state inspection. Tracks vocabulary with status state machine, supports six writing-to-learn entry points and five audience-facing entry points. -version: 2.0.1 -author: Terry Nyberg, Coffee & Code LLC license: Apache-2.0 +metadata: + version: "2.0.1" + author: "Terry Nyberg, Coffee & Code LLC" --- # tutorial-creator @@ -14,35 +15,54 @@ Three surfaces, gateway-mediated: - **`vocab`** — manage vocabulary independent of lesson generation - **`status`** — 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). +## Runtime compatibility + +This skill supports Claude Code and Codex. At the start of every invocation, set +`` to the current runtime's syntax: + +- Claude Code: `/skill tutorial-creator` +- Codex: `$tutorial-creator` + +Treat every ` ...` example below as an agent-facing command, not a shell command. +When showing a command to the user, render the value of `` rather than the +placeholder. Use the runtime's structured question tool when one is available; +otherwise ask the same question in plain text. + +The `.claude/tutorial-config.yaml`, `.claude/tutorial-sessions/`, and +`~/.claude/tutorial-creator/registry.yaml` paths are shared tutorial-creator state for +both runtimes. Keep these paths unchanged so an existing project retains one learning +history when the user switches agents. In Codex, treat `.claude/` as application data, +not as Codex configuration. + +The legacy v1.1 invocation (` `) 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|vocab|status [args] + # opens gateway question + # legacy v1.1 path → entry [b] + tutorial # tutorial surface + vocab # vocab surface + status # status surface + undo # revert last generation + undo --session # revert a specific session (rare) + renumber # rename Day-N + rewrite cross-references + --mode learn|audience|vocab|status [args] # skip gateway, route directly -/skill tutorial-creator open # register a tutorial-creator project + 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 + open # list registered projects + pick one # (sets it as the registry default) -/skill tutorial-creator forget # remove a project from the registry + forget # remove a project from the registry # (no filesystem changes; project files stay) -/skill tutorial-creator --project-dir [args] + --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/`. +**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 ` status` from any working directory and it Just Works — same mental model as `git status` walking up from cwd to find `.git/`. ## Routing logic @@ -64,7 +84,7 @@ Every invocation runs through this dispatch: ### Gateway question -Use AskUserQuestion (or plain-text prompt if AskUserQuestion is unavailable): +Use the runtime's structured question tool (or a plain-text prompt if unavailable): ``` What do you want to do? @@ -124,7 +144,7 @@ Where does the tutorial start? [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: +After the entry letter is picked, the Path 2 flow runs four more structured or plain-text prompts in this order, then hands off to a venue template: 1. **Audience question.** Options: `beginner` / `intermediate` / `senior` / `mixed`. Drives in-voice content shifts (definitions vs. tradeoffs). 2. **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`). @@ -215,7 +235,7 @@ Runs as step 0 of every invocation, before routing. Determines `$PROJECT_ROOT` ### Discovery chain (highest precedence first) -1. **`--project-dir ` flag.** If set on the invocation, treat `` as `$PROJECT_ROOT` and stop. The path must be absolute or resolvable relative to cwd. If `/.claude/tutorial-config.yaml` does 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. +1. **`--project-dir ` flag.** If set on the invocation, treat `` as `$PROJECT_ROOT` and stop. The path must be absolute or resolvable relative to cwd. If `/.claude/tutorial-config.yaml` does not exist, the skill **does not** auto-create it from this flag — say `--project-dir has no tutorial-creator config. Run " open " first, or invoke from to trigger first-run setup.` and stop. Render `` for the current runtime before showing that message. The `--project-dir` flag is for picking among already-set-up projects, not for bootstrapping new ones in unusual locations. 2. **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. 3. **Cwd's `.claude/tutorial-config.yaml`.** If `./.claude/tutorial-config.yaml` exists 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. 4. **Ancestor walk from cwd.** Walk up from cwd one directory at a time until either: (a) a `.claude/tutorial-config.yaml` exists 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 `/`. @@ -253,11 +273,11 @@ After successful resolution (steps 1–5), if the project is in the registry, up Registers a tutorial-creator project so the resolution chain finds it from any cwd. Two forms: ``` -/skill tutorial-creator open # interactive: list registered, pick + set as default -/skill tutorial-creator open # add to the registry + open # interactive: list registered, pick + set as default + open # add to the registry ``` -**Form 1 — list and pick.** Read `~/.claude/tutorial-creator/registry.yaml`. If empty, say `No projects registered. Use "/skill tutorial-creator open " to add one.` and stop. Otherwise, list registered projects with their `last_invoked` timestamps, ask the user to pick one, and write that project as the registry's `default`. Confirm: `Default set to . Future invocations from any cwd will use this project unless you pass --project-dir.` +**Form 1 — list and pick.** Read `~/.claude/tutorial-creator/registry.yaml`. If empty, say `No projects registered. Use " open " to add one.` and render `` for the current runtime before showing the message, then stop. Otherwise, list registered projects with their `last_invoked` timestamps, ask the user to pick one, and write that project as the registry's `default`. Confirm: `Default set to . Future invocations from any cwd will use this project unless you pass --project-dir.` **Form 2 — add a path.** Verify `` exists and contains `.claude/tutorial-config.yaml`. If the config is missing, refuse: ` has no tutorial-creator config. Either run setup at first by invoking the skill from there, or pass a path to an already-set-up project.` On success, append to the registry. If this is the first registered project, also write it as the `default`. Confirm: `Registered . Now reachable from any cwd via the resolution chain.` @@ -266,7 +286,7 @@ The `open` command does NOT create a config; it only registers an existing one. ### `forget` command ``` -/skill tutorial-creator forget + forget ``` Removes `` from the registry. Filesystem changes: none. The project's files (`.claude/tutorial-config.yaml`, `tutorials_dir`, etc.) are untouched. If `` was the default, the registry's `default` field is cleared. If `` is not in the registry, say ` is not registered.` and stop. @@ -277,7 +297,7 @@ Use `forget` when a project moves (`forget` the old path, `open` the new one) or The previous behavior (`tutorial-config.yaml` pinned to cwd) created the same hostility `git` would have if `.git/` only worked from the exact directory you ran `git init` in. Tutorial projects often outlive any single coding session — the user's tutorials live at `/Volumes/.../Tutorials/` for years; the codebase they're learning from changes weekly. The discovery chain decouples "where the learning artifacts live" from "where I happen to be running the skill from right now," same as `git` decouples the working tree from the .git directory location. -The registry exists for the case where neither cwd nor an ancestor reveals a project. Without it, a user who keeps their tutorials at `~/Code/learn-rust/` and wants to invoke `/skill tutorial-creator status` from `~/`, `/tmp/`, or any other arbitrary cwd would have to type `--project-dir ~/Code/learn-rust` every time. The registry makes "I have one tutorial project" the zero-friction case. +The registry exists for the case where neither cwd nor an ancestor reveals a project. Without it, a user who keeps their tutorials at `~/Code/learn-rust/` and wants to invoke ` status` from `~/`, `/tmp/`, or any other arbitrary cwd would have to type `--project-dir ~/Code/learn-rust` every time. The registry makes "I have one tutorial project" the zero-friction case. ### Cwd-relative paths in resolved configs @@ -293,7 +313,7 @@ Triggered from `## Project resolution` step 6 (no project found anywhere in the Welcome to tutorial-creator! Let's set up your learning environment. ``` -Ask via AskUserQuestion: +Ask with the runtime's structured question tool, or a plain-text prompt: 1. **Confirm the project root.** Default: cwd. Show the resolved cwd path verbatim, ask "Use this directory as your tutorial-creator project? [yes / pick different path / cancel]". If the user picks a different path, that becomes `$PROJECT_ROOT` for the rest of setup. Refuse paths that don't exist; refuse paths inside another already-registered project (would create nested configs). 2. **Where should tutorials be saved?** Default: `$PROJECT_ROOT/tutorials/` (config written as `./tutorials/`, interpreted relative to `$PROJECT_ROOT`). User can pick an absolute path elsewhere if they want tutorial files outside the project root for some reason. @@ -331,7 +351,7 @@ If yes, append an entry per SCHEMAS.md Schema 5. If this is the first registered ## Entry [b] — Tutorial Format (topic + file) -When invoked as entry [b] (topic + file), produce a tutorial with these sections in this order. **This is also the legacy v1.1 invocation path** — when the user invokes `/skill tutorial-creator ` with two positional arguments and an existing source file, route here directly without the gateway question. The format is preserved verbatim from v1.1 so existing users see no behavior change. +When invoked as entry [b] (topic + file), produce a tutorial with these sections in this order. **This is also the legacy v1.1 invocation path** — when the user invokes ` ` with two positional arguments and an existing source file, route here directly without the gateway question. The format is preserved verbatim from v1.1 so existing users see no behavior change. ### Before Writing @@ -560,7 +580,7 @@ This entry is the writing-to-learn equivalent of "synthesizing notes after a mee ### Procedure 1. **Read config.** Need `language`, `project_dir` for the "how this applies to my codebase" mapping step. -2. **Receive the source.** AskUserQuestion (or plain prompt): +2. **Receive the source.** Use a structured question or plain-text prompt: ``` Where's the external source? [1] URL @@ -667,9 +687,9 @@ See `VOCAB.md` for the full procedure spec, state machine, and grading rules. Routes to `STATUS.md`. **Fully implemented.** Read-only dashboard. Invocation forms: ``` -/skill tutorial-creator status # direct invocation -/skill tutorial-creator # gateway question, then [4] -/skill tutorial-creator --mode status # skip gateway, route directly + status # direct invocation + # gateway question, then [4] + --mode status # skip gateway, route directly ``` The dashboard aggregates `tutorial-config.yaml`, `vocabulary.yaml`, the last 10 session logs, generated `Day*.md` files, and the active progression. It shows: @@ -714,7 +734,7 @@ After tutorial generation writes successfully: If generation **fails** mid-write (e.g., the tool errors after some files have been modified but before all are): 1. Do NOT write the session yaml. The session directory contains pre-write snapshots; without the yaml, the directory is orphaned but harmless and will be pruned by retention. -2. Tell the user: `Generation failed mid-write. Pre-write snapshots are at .claude/tutorial-sessions//. Run "/skill tutorial-creator undo --session " to manually revert.` +2. Tell the user: `Generation failed mid-write. Pre-write snapshots are at .claude/tutorial-sessions//. Run " undo --session " to manually revert.` Render `` for the current runtime before showing the message. ### Retention @@ -730,8 +750,8 @@ Pruning is silent. Retention applies to session yamls; standalone vocab-add sent Reverts the most recent tutorial generation. Invoked as: ``` -/skill tutorial-creator undo # most recent session -/skill tutorial-creator undo --session # specific session (rare; for orphaned mid-write recovery) + undo # most recent session + undo --session # specific session (rare; for orphaned mid-write recovery) ``` #### Procedure @@ -790,8 +810,8 @@ The session log is the single source of truth for what to revert. If it's missin Renames a Day-N tutorial file and rewrites every cross-reference. Supports whole-number days (`Day 8`) and half-step days (`Day 7.5`). ``` -/skill tutorial-creator renumber 8 7.5 -/skill tutorial-creator renumber 7.5 8 + renumber 8 7.5 + renumber 7.5 8 ``` #### Procedure diff --git a/skills/tutorial-creator/STATUS.md b/skills/tutorial-creator/STATUS.md index 9f3503d..3a765a6 100644 --- a/skills/tutorial-creator/STATUS.md +++ b/skills/tutorial-creator/STATUS.md @@ -61,9 +61,9 @@ Then render the cold-start block below and **stop**. Do not render the dashboard ``` You haven't shipped any tutorials yet. Start with: - /skill tutorial-creator # opens the gateway question + # opens the gateway question or - /skill tutorial-creator # legacy v1.1 invocation + # legacy v1.1 invocation ``` ### 3. Compute aggregates @@ -89,9 +89,9 @@ Tiebreak: - If `confused` count > 0, use (a). - Else if (b) produces a candidate, use (b). -- Else render the all-caught-up line: `Suggested next lesson: All caught up. Try a question-led entry: /skill tutorial-creator --mode learn → [d]`. +- Else render the all-caught-up line: `Suggested next lesson: All caught up. Try a question-led entry: --mode learn → [d]`. Render `` for the current runtime. -If the chosen candidate's file scan returns no good match (zero files under 300 lines, or no files at all reference the term/concept), still render the suggestion but replace the candidate-file line with `Candidate file: (no obvious match — let the skill scan when you start)` and replace the action line with `Action: /skill tutorial-creator `. +If the chosen candidate's file scan returns no good match (zero files under 300 lines, or no files at all reference the term/concept), still render the suggestion but replace the candidate-file line with `Candidate file: (no obvious match — let the skill scan when you start)` and replace the action line with `Action: `, rendering `` for the current runtime. ### 5. Render the dashboard @@ -130,7 +130,7 @@ Gap radar Suggested next lesson: Candidate file: Reason: - Action: /skill tutorial-creator + Action: ``` Substitution rules: diff --git a/skills/tutorial-creator/VOCAB.md b/skills/tutorial-creator/VOCAB.md index 5407f08..7163e8e 100644 --- a/skills/tutorial-creator/VOCAB.md +++ b/skills/tutorial-creator/VOCAB.md @@ -60,7 +60,7 @@ Where `{tutorials_dir}` comes from `.claude/tutorial-config.yaml`. [skip] cancel ``` If user picks `show` or `edit`, route to that subcommand instead. -3. **Draft the definition.** Use AskUserQuestion (or plain prompt) to gather: +3. **Draft the definition.** Use the runtime's structured question tool or plain text to gather: - **Type** — best guess from a list (swift-keyword / swift-attribute / api / concept / pattern / idiom; or language-specific equivalents). Show 4 candidate types with one-line explanations; user picks one or types `other` to enter free-form. - **Definition** — AI drafts a 1-3 sentence definition based on the term and the user's project context (active language from config). Show the draft with this prompt: ``` @@ -98,7 +98,7 @@ Where `{tutorials_dir}` comes from `.claude/tutorial-config.yaml`. ``` - Write a 24h soft-stage marker file: `/vocabulary.yaml.add-` containing the term name. Used by `vocab undo` (within 24h). The sentinel is the disambiguator that distinguishes standalone adds from tutorial-time adds; the latter are already captured by the session-log snapshot system in `SKILL.md` § Recovery and do NOT write a sentinel. - Regenerate VOCABULARY.md. - - Print confirmation: `Added "" (status: new). Undo within 24h via: /skill tutorial-creator vocab undo` + - Print confirmation: `Added "" (status: new). Undo within 24h via: vocab undo` after rendering `` for the current runtime. 5. **On `edit`:** drop into editable interactive editor for the four AI-drafted fields, then return to step 4. 6. **On `cancel`:** stop. No file written. @@ -389,7 +389,7 @@ If `` is ambiguous (multiple case-insensitive matches), show a numbered li ### Procedure 1. Read vocabulary.yaml; find the term (case-insensitive). -2. Show current values for editable fields; allow user to update each one. AskUserQuestion per field, or one big prompt with default-values pre-filled. +2. Show current values for editable fields; allow user to update each one. Use a structured question per field, or one plain-text prompt with default values pre-filled. 3. **Recompute status** — only if `--reset-mastery` flag was passed AND current status is `mastered`: - Set status to `reviewing` - Append no new test_history entry @@ -618,7 +618,7 @@ If VOCABULARY.md doesn't exist (during `--import`): refuse with `No VOCABULARY.m ## `vocab undo` -24-hour soft-stage reversal of the last *standalone* `vocab add` or `vocab ingest` (an invocation that wasn't part of a tutorial generation). Tutorial-time vocab adds are reverted by the broader session-log undo (`/skill tutorial-creator undo`); see `SKILL.md` § Recovery for that path. +24-hour soft-stage reversal of the last *standalone* `vocab add` or `vocab ingest` (an invocation that wasn't part of a tutorial generation). Tutorial-time vocab adds are reverted by the broader session-log undo (` undo`); see `SKILL.md` § Recovery for that path. ### Marker file shape @@ -628,7 +628,7 @@ A `vocab add` marker contains one term name (single-term add). A `vocab ingest` 1. List soft-stage markers: `/vocabulary.yaml.add-` files. 2. Filter to those within 24 hours of now. -3. **No markers in window:** `No vocab add or vocab ingest to undo within the last 24 hours. (For tutorial-time adds, use /skill tutorial-creator undo instead.)` +3. **No markers in window:** `No vocab add or vocab ingest to undo within the last 24 hours. (For tutorial-time adds, use undo instead.)` Render `` for the current runtime before showing the message. 4. **One marker:** show details — term name (single-add) or the full term list + count (ingest batch) — and when added; prompt confirm. On yes, remove the term(s) from vocabulary.yaml + delete the marker; regenerate VOCABULARY.md. 5. **Multiple markers:** show a numbered list — each row labeled `` for a single add or ` terms from vocab ingest ()` for a batch — user picks which to undo (or `cancel`). Only one marker is undone per invocation; run `vocab undo` again for another. @@ -636,7 +636,7 @@ Markers older than 24h are silently pruned at the start of any vocab subcommand. ### Why two undo paths -Tutorial generation is reversible as a unit: snapshots of vocabulary.yaml + PROGRESS.md + VOCABULARY.md + tutorial-config.yaml are taken before the generation runs, and `/skill tutorial-creator undo` restores them. Standalone vocab adds don't get a snapshot (they're a single-line yaml change with no ripple effect), so the 24h sentinel is the simpler approach. Both surfaces are user-facing; the skill chooses which one applies based on whether a session yaml exists for the change. +Tutorial generation is reversible as a unit: snapshots of vocabulary.yaml + PROGRESS.md + VOCABULARY.md + tutorial-config.yaml are taken before the generation runs, and ` undo` restores them. Standalone vocab adds don't get a snapshot (they're a single-line yaml change with no ripple effect), so the 24h sentinel is the simpler approach. Both surfaces are user-facing; the skill chooses which one applies based on whether a session yaml exists for the change. --- @@ -700,7 +700,7 @@ Compare user's answer to the stored definition. Result is one of: - OR the answer is correct but for a *related* concept, not the term being tested - **`wrong`** — doesn't capture the concept, or contradicts it -The grading is performed by Claude (the runtime LLM) at test time. When in doubt between `correct` and `partial`, prefer `partial`. When in doubt between `partial` and `wrong`, prefer `partial` (the user gets credit for trying). +The grading is performed by the runtime LLM at test time. When in doubt between `correct` and `partial`, prefer `partial`. When in doubt between `partial` and `wrong`, prefer `partial` (the user gets credit for trying). ### Strict grading diff --git a/skills/tutorial-creator/agents/openai.yaml b/skills/tutorial-creator/agents/openai.yaml new file mode 100644 index 0000000..71f844a --- /dev/null +++ b/skills/tutorial-creator/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Tutorial Creator" + short_description: "Learn from code in your current project" + default_prompt: "Use $tutorial-creator to turn code from this project into a personalized lesson."