feat(coding-tutor): restore coding-tutor plugin#7
Conversation
User-directed restoration; reverts 159cfee (plugin tree, marketplace entries across all three catalogs, release-please package + manifest entry at 1.3.0, release metadata/component code, test fixtures). Plugin content verified byte-identical to upstream/main current state. Cursor manifest homepage/repository and the marketplace entry homepage repointed to the fork, matching the manifest treatment in PR #6. Op: extend
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughThis pull request adds a new ChangesCoding Tutor Plugin Addition
🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces the coding-tutor plugin, which provides personalized coding tutorials based on the user's codebase and tracks progress via spaced repetition quizzes. The changes include adding plugin manifests, commands, a core skill, and Python helper scripts for tutorial creation, indexing, and quiz prioritization, alongside corresponding updates to release metadata and tests. The review feedback highlights several critical robustness and cross-platform issues in the Python scripts, such as handling Windows path backslashes, sanitizing filenames, preventing silent file overwrites, improving the custom YAML frontmatter parser to ignore comments/empty lines, and handling partially initialized tutorial directories.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if result.returncode == 0: | ||
| return result.stdout.strip().split('/')[-1] |
There was a problem hiding this comment.
On Windows, git rev-parse --show-toplevel may return paths with backslashes (\\), causing split('/')[-1] to return the entire absolute path instead of just the repository name. Using Path.name is a robust, cross-platform way to extract the directory name.
| if result.returncode == 0: | |
| return result.stdout.strip().split('/')[-1] | |
| if result.returncode == 0: | |
| return Path(result.stdout.strip()).name |
| def slugify(text): | ||
| """Convert text to URL-friendly slug.""" | ||
| return text.lower().replace(" ", "-").replace("_", "-") |
There was a problem hiding this comment.
If the topic contains characters that are invalid in Windows filenames (such as ?, :, *, etc.), creating the file will raise an OSError. Additionally, if the topic consists entirely of special characters, the slug will be empty. Cleaning the input to keep only alphanumeric characters and providing a fallback ensures cross-platform safety.
| def slugify(text): | |
| """Convert text to URL-friendly slug.""" | |
| return text.lower().replace(" ", "-").replace("_", "-") | |
| def slugify(text): | |
| """Convert text to URL-friendly slug.""" | |
| cleaned = "".join(c for c in text if c.isalnum() or c in " -_") | |
| slug = cleaned.lower().replace(" ", "-").replace("_", "-") | |
| return slug if slug else "tutorial" |
| filename = f"{date_str_filename}-{slug}.md" | ||
| filepath = output_dir / filename |
There was a problem hiding this comment.
If a tutorial with the same name is created on the same day, filepath.write_text(template) will silently overwrite the existing file, leading to potential data loss. Raising a FileExistsError prevents accidental overwrites.
| filename = f"{date_str_filename}-{slug}.md" | |
| filepath = output_dir / filename | |
| filename = f"{date_str_filename}-{slug}.md" | |
| filepath = output_dir / filename | |
| if filepath.exists(): | |
| raise FileExistsError(f"Tutorial already exists at {filepath}. Aborting to prevent overwriting your work.") |
| for line in frontmatter_text.split('\n'): | ||
| line = line.strip() | ||
| if ':' in line: |
There was a problem hiding this comment.
If the frontmatter contains empty lines or comments that happen to contain a colon (e.g., # Note: some comment), the simple parser will incorrectly treat them as key-value pairs. Skipping empty lines and comments starting with # makes the parser more robust.
| for line in frontmatter_text.split('\n'): | |
| line = line.strip() | |
| if ':' in line: | |
| for line in frontmatter_text.split('\n'): | |
| line = line.strip() | |
| if not line or line.startswith('#'): | |
| continue | |
| if ':' in line: |
| for line in frontmatter_text.split('\n'): | ||
| line = line.strip() | ||
| if ':' in line: |
There was a problem hiding this comment.
If the frontmatter contains empty lines or comments with colons, the parser will incorrectly treat them as key-value pairs. Skipping empty lines and comments starting with # prevents this.
| for line in frontmatter_text.split('\n'): | |
| line = line.strip() | |
| if ':' in line: | |
| for line in frontmatter_text.split('\n'): | |
| line = line.strip() | |
| if not line or line.startswith('#'): | |
| continue | |
| if ':' in line: |
| if repo_path.exists(): | ||
| return True, f"Tutorials repo already exists at {repo_path.resolve()}" | ||
|
|
||
| try: | ||
| # Create directory | ||
| repo_path.mkdir(parents=True) |
There was a problem hiding this comment.
If the directory ~/coding-tutor-tutorials/ already exists but is not a git repository (e.g., if it was created manually or partially set up), the script will currently return early without initializing git or creating the required files. If we bypass the early return when .git is missing, the subsequent repo_path.mkdir(parents=True) will raise a FileExistsError because exist_ok=True is not specified. Checking for .git and using exist_ok=True allows safe initialization of existing directories.
| if repo_path.exists(): | |
| return True, f"Tutorials repo already exists at {repo_path.resolve()}" | |
| try: | |
| # Create directory | |
| repo_path.mkdir(parents=True) | |
| if repo_path.exists() and (repo_path / ".git").exists(): | |
| return True, f"Tutorials repo already exists at {repo_path.resolve()}" | |
| try: | |
| # Create directory | |
| repo_path.mkdir(parents=True, exist_ok=True) |
There was a problem hiding this comment.
Pull request overview
Restores the coding-tutor plugin subtree (skills/commands/manifests) and re-integrates it into this fork’s release + marketplace wiring so it is versioned, validated, and shipped alongside the existing compound-engineering plugin.
Changes:
- Reintroduces
plugins/coding-tutor/**(skill content + helper scripts, commands, and plugin manifests for Claude/Cursor/Codex). - Extends release automation to treat
coding-tutoras a first-class release component (release preview overrides, release-please config/manifest, metadata sync). - Updates tests and marketplace catalogs to include/validate the restored plugin across supported surfaces.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/skill-shell-safety.test.ts | Expands shell-safety fixture coverage to include coding-tutor skills directory. |
| tests/release-preview.test.ts | Exercises release preview override behavior for the coding-tutor component. |
| tests/release-metadata.test.ts | Extends release metadata fixtures/parity tests to include coding-tutor manifests + marketplace entries. |
| tests/release-components.test.ts | Ensures component detection and scope parsing cover coding-tutor. |
| tests/pi-writer.test.ts | Adjusts multi-plugin namespacing test fixture to use coding-tutor as the secondary plugin name. |
| tests/opencode-writer.test.ts | Adjusts multi-plugin namespacing + legacy-migration fixtures to use coding-tutor. |
| tests/gemini-writer.test.ts | Adjusts multi-plugin namespacing fixtures to use coding-tutor. |
| tests/frontmatter.test.ts | Adds coding-tutor plugin root to frontmatter/YAML validity checks. |
| src/targets/managed-artifacts.ts | Updates inline documentation example for plugin-scoped managed paths. |
| src/release/types.ts | Adds coding-tutor to the ReleaseComponent union. |
| src/release/metadata.ts | Syncs coding-tutor plugin manifest versions and enforces Codex parity/skills checks. |
| src/release/components.ts | Adds coding-tutor component detection, scope mapping, and version loading. |
| plugins/coding-tutor/skills/coding-tutor/SKILL.md | Introduces the coding-tutor skill definition and operating instructions. |
| plugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py | Adds helper script to create/init the user’s tutorials repository. |
| plugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py | Adds helper script to prioritize quizzes via spaced repetition intervals. |
| plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py | Adds helper script to index tutorial frontmatter into JSON/human output. |
| plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py | Adds helper script to generate new tutorial templates with frontmatter. |
| plugins/coding-tutor/README.md | Adds plugin README covering purpose, install, features, commands, and storage. |
| plugins/coding-tutor/commands/teach-me.md | Adds teach-me command stub for the plugin. |
| plugins/coding-tutor/commands/sync-tutorials.md | Adds sync-tutorials command instructions for backing up tutorials via git/GitHub. |
| plugins/coding-tutor/commands/quiz-me.md | Adds quiz-me command stub for the plugin. |
| plugins/coding-tutor/CHANGELOG.md | Restores coding-tutor changelog entry (v1.3.0). |
| plugins/coding-tutor/.cursor-plugin/plugin.json | Restores Cursor plugin manifest for coding-tutor (v1.3.0). |
| plugins/coding-tutor/.codex-plugin/plugin.json | Restores Codex plugin manifest for coding-tutor (v1.3.0) including skills path. |
| plugins/coding-tutor/.claude-plugin/plugin.json | Restores Claude plugin manifest for coding-tutor (v1.3.0). |
| .github/workflows/release-preview.yml | Adds a coding-tutor bump override input to the release preview workflow. |
| .github/release-please-config.json | Adds release-please package config for plugins/coding-tutor + version extra-files. |
| .github/.release-please-manifest.json | Adds manifest entry for plugins/coding-tutor at 1.3.0. |
| .cursor-plugin/marketplace.json | Adds coding-tutor entry to the Cursor marketplace catalog. |
| .claude-plugin/marketplace.json | Adds coding-tutor entry to the Claude marketplace catalog (source points at restored plugin). |
| .agents/plugins/marketplace.json | Adds coding-tutor entry to the Codex .agents marketplace catalog. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,214 @@ | |||
| --- | |||
| name: coding-tutor | |||
| description: Personalized coding tutorials that build on your existing knowledge and use your actual codebase for examples. Creates a persistent learning trail that compounds over time using the power of AI, spaced repetition and quizes. | |||
|
|
||
| 3. **Who are you**: Tell me a bit about yourself - imagine we just met at a coworking space. - Get context that shapes how to teach them. | ||
|
|
||
| 4. **Optional**: Based on the above answers, you may ask upto one optional 4th question if it will make your understanding of the learner richer. |
|
|
||
| ## Teaching Philosophy | ||
|
|
||
| Our general goal is to take the user from newbie to a senior engineer in record time. One at par with engineers at companies like 37 Signals or Vercel. |
| description: One-paragraph summary of what this tutorial covers | ||
| understanding_score: null # null until quizzed, then 1-10 based on quiz performance | ||
| last_quizzed: null # null until first quiz, then DD-MM-YYYY | ||
| prerequisites: [~/coding-tutor-tutorials/tutorial_1_name.md, ~/coding-tutor-tutorials/tutorial_2_name.md, (upto 3 other existing tutorials)] |
| ## Install | ||
|
|
||
| ``` | ||
| /plugin install coding-tutor@claude-code-essentials | ||
| ``` |
|
|
||
| README_CONTENT = """# Coding Tutor - My Learning Journey | ||
|
|
||
| This repository contains my personalized coding tutorials created with the [coding-tutor](https://github.com/nityeshaga/claude-code-essentials) Claude Code plugin. |
| import argparse | ||
| import json | ||
| import re | ||
| import subprocess | ||
| import sys | ||
| from pathlib import Path |
| import argparse | ||
| import re | ||
| import subprocess | ||
| from datetime import datetime | ||
| from pathlib import Path |
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (1)
plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py (1)
25-78: ⚡ Quick winConsider extracting frontmatter parsing to a shared utility module.
The
extract_frontmatter()logic (regex matching, key:value parsing, null/list handling) is duplicated inquiz_priority.py(lines 39-78) with minor variations. This duplication increases maintenance burden and risks divergence.♻️ Suggested approach
Create a shared
frontmatter_parser.pymodule in thescripts/directory with a unifiedparse_frontmatter(filepath)function that both scripts can import. This centralizes the regex pattern, null-handling logic, and list-parsing conventions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py` around lines 25 - 78, The extract_frontmatter function duplicates parsing logic found in quiz_priority.py; refactor by creating a new shared utility (e.g., scripts/frontmatter_parser.py) that exposes a single parse_frontmatter(filepath) function implementing the YAML frontmatter regex, key:value parsing, null handling for understanding_score and last_quizzed, and list parsing for prerequisites, then replace the local extract_frontmatter implementations in both index_tutorials.py (extract_frontmatter) and quiz_priority.py with imports from parse_frontmatter to eliminate duplication and centralize behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/coding-tutor/README.md`:
- Around line 17-19: The fenced command block containing `/plugin install
coding-tutor@claude-code-essentials` should use a typed fence to satisfy
markdown linting; update the triple-backtick fence that wraps that command to
include a shell language tag (e.g., bash) so the block becomes a proper code
fence with a language identifier.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py`:
- Line 199: Remove the unnecessary f-string prefix on the print call that has no
placeholders: change the statement starting with print(f"Edit the file to add
content and update the frontmatter") to a plain string (remove the leading f) so
it reads print("Edit the file to add content and update the frontmatter");
update the same call in create_tutorial.py where that print occurs.
- Around line 51-53: The slugify function currently only replaces spaces and
underscores; update slugify to fully sanitize topic strings by normalizing
Unicode (e.g., NFKD) and then removing or replacing all non-alphanumeric
characters with hyphens using a regex, collapse consecutive hyphens into one,
and trim leading/trailing hyphens so outputs are lowercase, filesystem-safe
slugs (refer to the slugify function in create_tutorial.py).
- Around line 92-93: The frontmatter currently writes concepts as a raw comma
string via the template variable (template = f"""---\nconcepts:
{concepts}\n"""), which violates the skill contract; update the code that builds
the template in create_tutorial.py to render concepts as a bracketed,
comma-space separated list (e.g., transform the existing concepts value into
"[Redux, Context, State]" before injecting into the template), ensuring you
reference the same variable name (concepts) and the template string so
downstream parsers (index_tutorials.py, quiz_priority.py) receive the expected
bracketed list format.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py`:
- Line 139: The string passed to output.append currently uses an unnecessary
f-string: output.append(f" Understanding: not quizzed yet"); change it to a
plain string by removing the leading "f" so it reads output.append("
Understanding: not quizzed yet") to avoid the extraneous f-prefix.
In `@plugins/coding-tutor/skills/coding-tutor/SKILL.md`:
- Line 3: Fix the frontmatter typo in SKILL.md by updating the description
field: replace the word "quizes" with the correct spelling "quizzes" in the
description frontmatter line so the user-facing metadata is accurate (look for
the description key in plugins/coding-tutor/skills/coding-tutor/SKILL.md).
- Around line 207-212: The fenced code block showing the quiz history in
SKILL.md lacks a language tag; update the opening fence for the "### Quiz -
DD-MM-YYYY" block (the triple backticks before the quiz content) to include a
language such as markdown or text (e.g., change ``` to ```markdown) so the block
satisfies markdown lint rules.
- Around line 165-166: Replace the Unicode arrow characters "→" with ASCII "->"
in the example lines inside SKILL.md (specifically the examples showing
Explicit: "Quiz me on React hooks" → quiz that specific concept and Open: "Quiz
me on something" → run `python3
${CLAUDE_PLUGIN_ROOT}/skills/coding-tutor/scripts/quiz_priority.py`...), and
also update the other occurrence mentioned (line 211) so all terminal/example
arrows use ASCII -> to comply with the coding guideline; search the file for "→"
and replace with "->" within code/terminal/example blocks.
- Around line 38-39: The skill's guidance to "Ask these three questions, one at
a time" lacks explicit instruction to use the platform blocking question tool
and a fallback; update the skill text where questions are prompted (e.g., the
onboarding and quiz steps around the current "Ask these three questions, one at
a time" passage and the other instances at lines ~81-84 and ~183-184) to
instruct: call the platform blocking question API (AskUserQuestion /
request_user_input / ask_user) for each question and wait for the response, and
if the blocking tool is unavailable, present numbered options as a fallback and
parse the chosen number; mention the exact tool names (AskUserQuestion,
request_user_input, ask_user) so implementers know which runtime calls to use.
---
Nitpick comments:
In `@plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py`:
- Around line 25-78: The extract_frontmatter function duplicates parsing logic
found in quiz_priority.py; refactor by creating a new shared utility (e.g.,
scripts/frontmatter_parser.py) that exposes a single parse_frontmatter(filepath)
function implementing the YAML frontmatter regex, key:value parsing, null
handling for understanding_score and last_quizzed, and list parsing for
prerequisites, then replace the local extract_frontmatter implementations in
both index_tutorials.py (extract_frontmatter) and quiz_priority.py with imports
from parse_frontmatter to eliminate duplication and centralize behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2304ae4c-7dfc-415f-a793-42b5fda61a7f
📒 Files selected for processing (31)
.agents/plugins/marketplace.json.claude-plugin/marketplace.json.cursor-plugin/marketplace.json.github/.release-please-manifest.json.github/release-please-config.json.github/workflows/release-preview.ymlplugins/coding-tutor/.claude-plugin/plugin.jsonplugins/coding-tutor/.codex-plugin/plugin.jsonplugins/coding-tutor/.cursor-plugin/plugin.jsonplugins/coding-tutor/CHANGELOG.mdplugins/coding-tutor/README.mdplugins/coding-tutor/commands/quiz-me.mdplugins/coding-tutor/commands/sync-tutorials.mdplugins/coding-tutor/commands/teach-me.mdplugins/coding-tutor/skills/coding-tutor/SKILL.mdplugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.pyplugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.pyplugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.pyplugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.pysrc/release/components.tssrc/release/metadata.tssrc/release/types.tssrc/targets/managed-artifacts.tstests/frontmatter.test.tstests/gemini-writer.test.tstests/opencode-writer.test.tstests/pi-writer.test.tstests/release-components.test.tstests/release-metadata.test.tstests/release-preview.test.tstests/skill-shell-safety.test.ts
| ``` | ||
| /plugin install coding-tutor@claude-code-essentials | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced command block.
Line 17 should use a typed fence (for example bash) to satisfy markdown linting.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 17-17: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/README.md` around lines 17 - 19, The fenced command
block containing `/plugin install coding-tutor@claude-code-essentials` should
use a typed fence to satisfy markdown linting; update the triple-backtick fence
that wraps that command to include a shell language tag (e.g., bash) so the
block becomes a proper code fence with a language identifier.
Sources: Coding guidelines, Linters/SAST tools
| def slugify(text): | ||
| """Convert text to URL-friendly slug.""" | ||
| return text.lower().replace(" ", "-").replace("_", "-") |
There was a problem hiding this comment.
Harden slugify() to sanitize all special characters.
The current implementation only replaces spaces and underscores. Topic names with characters like :, /, (, ), &, or quotes will produce invalid filenames. For example, "React: Hooks & Effects" becomes "react:-hooks-&-effects.md", which may fail on some filesystems or cause shell-escaping issues.
🛡️ Proposed fix using regex to strip non-alphanumerics
def slugify(text):
"""Convert text to URL-friendly slug."""
- return text.lower().replace(" ", "-").replace("_", "-")
+ import re
+ text = text.lower()
+ text = re.sub(r'[^\w\s-]', '', text) # Remove non-alphanumeric except spaces/hyphens
+ text = re.sub(r'[-\s]+', '-', text) # Collapse spaces/hyphens
+ return text.strip('-')🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py` around
lines 51 - 53, The slugify function currently only replaces spaces and
underscores; update slugify to fully sanitize topic strings by normalizing
Unicode (e.g., NFKD) and then removing or replacing all non-alphanumeric
characters with hyphens using a regex, collapse consecutive hyphens into one,
and trim leading/trailing hyphens so outputs are lowercase, filesystem-safe
slugs (refer to the slugify function in create_tutorial.py).
| template = f"""--- | ||
| concepts: {concepts} |
There was a problem hiding this comment.
Fix concepts frontmatter format to match the skill contract.
Line 93 generates concepts: {concepts} which outputs a raw comma-separated string (e.g., concepts: Redux,Context,State). However, the skill specification (SKILL.md:85-98) and downstream scripts (index_tutorials.py, quiz_priority.py) expect bracketed list syntax: concepts: [Redux, Context, State]. This contract violation will cause parsing failures when indexing or prioritizing tutorials.
🐛 Proposed fix to emit bracketed list format
# Create tutorial template with YAML frontmatter and embedded guidance
+ # Format concepts as bracketed list for YAML compliance
+ if concepts:
+ concepts_formatted = f"[{concepts}]"
+ else:
+ concepts_formatted = "[]"
+
template = f"""---
-concepts: {concepts}
+concepts: {concepts_formatted}
source_repo: {repo_name}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| template = f"""--- | |
| concepts: {concepts} | |
| # Format concepts as bracketed list for YAML compliance | |
| if concepts: | |
| concepts_formatted = f"[{concepts}]" | |
| else: | |
| concepts_formatted = "[]" | |
| template = f"""--- | |
| concepts: {concepts_formatted} |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py` around
lines 92 - 93, The frontmatter currently writes concepts as a raw comma string
via the template variable (template = f"""---\nconcepts: {concepts}\n"""), which
violates the skill contract; update the code that builds the template in
create_tutorial.py to render concepts as a bracketed, comma-space separated list
(e.g., transform the existing concepts value into "[Redux, Context, State]"
before injecting into the template), ensuring you reference the same variable
name (concepts) and the template string so downstream parsers
(index_tutorials.py, quiz_priority.py) receive the expected bracketed list
format.
| try: | ||
| filepath = create_tutorial(args.topic, args.concepts, args.output_dir) | ||
| print(f"Created tutorial template: {filepath}") | ||
| print(f"Edit the file to add content and update the frontmatter") |
There was a problem hiding this comment.
Remove extraneous f prefix from string literal.
Line 199 uses an f-string with no placeholders.
♻️ Proposed fix
- print(f"Edit the file to add content and update the frontmatter")
+ print("Edit the file to add content and update the frontmatter")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| print(f"Edit the file to add content and update the frontmatter") | |
| print("Edit the file to add content and update the frontmatter") |
🧰 Tools
🪛 Ruff (0.15.15)
[error] 199-199: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py` at line
199, Remove the unnecessary f-string prefix on the print call that has no
placeholders: change the statement starting with print(f"Edit the file to add
content and update the frontmatter") to a plain string (remove the leading f) so
it reads print("Edit the file to add content and update the frontmatter");
update the same call in create_tutorial.py where that print occurs.
| output.append(f" Description: {tutorial['description']}") | ||
| score = tutorial['understanding_score'] | ||
| if score is None: | ||
| output.append(f" Understanding: not quizzed yet") |
There was a problem hiding this comment.
Remove extraneous f prefix from string literal.
Line 139 uses an f-string with no placeholders.
♻️ Proposed fix
- output.append(f" Understanding: not quizzed yet")
+ output.append(" Understanding: not quizzed yet")🧰 Tools
🪛 Ruff (0.15.15)
[error] 139-139: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py` at line
139, The string passed to output.append currently uses an unnecessary f-string:
output.append(f" Understanding: not quizzed yet"); change it to a plain string
by removing the leading "f" so it reads output.append(" Understanding: not
quizzed yet") to avoid the extraneous f-prefix.
| @@ -0,0 +1,214 @@ | |||
| --- | |||
| name: coding-tutor | |||
| description: Personalized coding tutorials that build on your existing knowledge and use your actual codebase for examples. Creates a persistent learning trail that compounds over time using the power of AI, spaced repetition and quizes. | |||
There was a problem hiding this comment.
Fix typo in frontmatter description (quizes -> quizzes).
This is user-facing metadata; correcting it avoids downstream copy drift in generated docs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/SKILL.md` at line 3, Fix the
frontmatter typo in SKILL.md by updating the description field: replace the word
"quizes" with the correct spelling "quizzes" in the description frontmatter line
so the user-facing metadata is accurate (look for the description key in
plugins/coding-tutor/skills/coding-tutor/SKILL.md).
| Ask these three questions, one at a time. Wait for each answer before asking the next. | ||
|
|
There was a problem hiding this comment.
Specify blocking question-tool usage wherever the skill asks questions.
The onboarding and quiz flows require sequential user responses, but the skill doesn’t instruct the runtime to use platform blocking question tools (and fallback behavior). Add explicit guidance for AskUserQuestion/request_user_input/ask_user plus numbered-option fallback when unavailable.
Based on learnings: “When a skill needs to ask the user a question, use the platform's blocking question tool … with numbered options as fallback when the blocking tool is unavailable.”
Also applies to: 81-84, 183-184
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/SKILL.md` around lines 38 - 39, The
skill's guidance to "Ask these three questions, one at a time" lacks explicit
instruction to use the platform blocking question tool and a fallback; update
the skill text where questions are prompted (e.g., the onboarding and quiz steps
around the current "Ask these three questions, one at a time" passage and the
other instances at lines ~81-84 and ~183-184) to instruct: call the platform
blocking question API (AskUserQuestion / request_user_input / ask_user) for each
question and wait for the response, and if the blocking tool is unavailable,
present numbered options as a fallback and parse the chosen number; mention the
exact tool names (AskUserQuestion, request_user_input, ask_user) so implementers
know which runtime calls to use.
Source: Learnings
| - Explicit: "Quiz me on React hooks" → quiz that specific concept | ||
| - Open: "Quiz me on something" → run `python3 ${CLAUDE_PLUGIN_ROOT}/skills/coding-tutor/scripts/quiz_priority.py` to get a prioritized list based on spaced repetition, then choose what to quiz |
There was a problem hiding this comment.
Replace Unicode arrows in examples with ASCII arrows.
Use ASCII -> instead of → in these terminal/example lines to match markdown guidance.
As per coding guidelines: “Prefer ASCII arrows (->-, <-) over Unicode arrows in code blocks and terminal examples.”
Also applies to: 211-211
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/SKILL.md` around lines 165 - 166,
Replace the Unicode arrow characters "→" with ASCII "->" in the example lines
inside SKILL.md (specifically the examples showing Explicit: "Quiz me on React
hooks" → quiz that specific concept and Open: "Quiz me on something" → run
`python3
${CLAUDE_PLUGIN_ROOT}/skills/coding-tutor/scripts/quiz_priority.py`...), and
also update the other occurrence mentioned (line 211) so all terminal/example
arrows use ASCII -> to comply with the coding guideline; search the file for "→"
and replace with "->" within code/terminal/example blocks.
Source: Coding guidelines
| ``` | ||
| ### Quiz - DD-MM-YYYY | ||
| **Q:** [Question asked] | ||
| **A:** [Brief summary of their response and what it revealed about understanding] | ||
| Score updated: 5 → 7 | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the quiz-history fenced block.
Line 207 should declare a fence language (for example markdown or text) to satisfy markdown lint rules.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 207-207: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@plugins/coding-tutor/skills/coding-tutor/SKILL.md` around lines 207 - 212,
The fenced code block showing the quiz history in SKILL.md lacks a language tag;
update the opening fence for the "### Quiz - DD-MM-YYYY" block (the triple
backticks before the quiz content) to include a language such as markdown or
text (e.g., change ``` to ```markdown) so the block satisfies markdown lint
rules.
Source: Linters/SAST tools
User-directed restoration of the coding-tutor plugin (reverts 159cfee).
git diff 159cfee^ upstream/main -- plugins/coding-tutoris empty; both at v1.3.0) — reverting the local removal and importing from upstream are the same change..agents), parity preserved.src/releasemetadata/component code, test fixtures (test count 885 -> 889).homepage/repositoryand its marketplace entry homepage point at this fork, matching the manifest treatment in fix(seo): repoint fork metadata and install docs, add SEO/GEO positioning #6. The compound-engineering entry is untouched here (owned by fix(seo): repoint fork metadata and install docs, add SEO/GEO positioning #6).Verification
bun test: 889 pass / 0 failbun run release:validate: in syncInteraction with #6
The SEO PR's README comparison table claims "bundled plugins: 1 (coding-tutor removed here)". If both PRs merge, that row is stale — a fixup on
seo-geo-loopremoves it.Summary by CodeRabbit
New Features
Documentation
/teach-me,/quiz-me,/sync-tutorials), onboarding workflows, and comprehensive tutorial management guidelines for optimal learning experience.