lpm: Skill for Claude Code

.claude/skills/lesson-publish/SKILL.md

lesson-publish is a skill for Claude Code from gug007/lpm. It costs 102 tokens per session (1,743 once invoked), scanned A, original, MIT.

A publishing workflow for uploading a finished lesson video to a YouTube channel through YouTube Studio. It prepares the video, thumbnail, captions, description, tags and chapters before publishing it.

In plain words
What is it for?
Use it to publish a lesson to YouTube, set its title and description, add chapters and tags, choose a thumbnail and place it in the lesson playlist.
Why use it?
It checks that the lesson's recording checks passed before upload and keeps the files within the upload workflow's limits. It also gathers the video metadata in one place.

Skill for Claude Code

Written for Claude Code: argument-hint in frontmatter. Also seen: mentions Claude Code; mentions Codex.

This is gug007/lpm's own configuration. It tells Claude Code how to work on lpm itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything lpm configures →

Reuse

Borrowing it

Nothing to install: this file belongs to gug007/lpm. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/gug007/lpm/main/.claude/skills/lesson-publish/SKILL.md
Clone the repo
git clone --depth 1 https://github.com/gug007/lpm

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for lesson-publish

README.md
[![agentmods](https://agentmods.dev/badge/skills/gug007/lpm/lesson-publish/github.svg)](https://agentmods.dev/skills/gug007/lpm/lesson-publish)
Your own site
<a href="https://agentmods.dev/skills/gug007/lpm/lesson-publish"><img src="https://agentmods.dev/badge/skills/gug007/lpm/lesson-publish/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for lesson-publish

Your own site · 80×15
<a href="https://agentmods.dev/skills/gug007/lpm/lesson-publish"><img src="https://agentmods.dev/badge/skills/gug007/lpm/lesson-publish.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 102 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 1,743 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00102 $0.01743
Opus 5.5 $0.00041 $0.00697
Sonnet 5.5 $0.00020 $0.00349
Haiku 4.5 $0.00010 $0.00174

Measured 14d ago against content hash 8706168359ec, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

lesson-publish scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 14d ago.

The scan reads SKILL.md. This mod also ships 2 executable files (scripts/prepare.js, scripts/register.js), listed below but not scanned — reading those needs a real analyzer, not pattern matching.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.claude/skills/lesson-publish/SKILL.md · 22 lines

How it starts

The opening of the file, as written. The whole thing — 22 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Upload a lesson video to YouTube and publish it.

  • run node scripts/prepare.js <slug or lesson folder> <scratchpad-dir> first. It refuses a lesson whose checks failed or are older than the MP4 (qa/report.json, written by lesson's make.js); show the user the FAIL lines, and only with their go-ahead pass --accept "<their reason>". It copies the MP4 into the scratchpad under the video title (the file name becomes the initial title in Studio; it warns when that dropped a ":" to retype), the thumbnail (the opening card, rendered by make.js), the captions (<slug>.srt), and writes <slug>-description.txt and <slug>-tags.txt, and prints the chapters. Chrome's file_upload only accepts files inside the scratchpad and under 10,000,000 bytes; when the master is larger, prepare.js writes a 1080p HEVC two-pass copy that fits instead (H.264 at that bitrate smears terminal text). YouTube gets the smaller copy; the master stays in the lesson folder.
  • the description and tags come from lesson.json "youtube": { "hook": [two lines], "learn": [...], "sections": [...], "tags": [...], "hashtags": [...] }: write that block first when the lesson has none (prepare.js says so), then run prepare.js again, so a replacement upload reuses the same words.
  • captions: in the Details step's "Subtitles" (or later under Subtitles in Studio), Add language → English → Add subtitles → Upload file → With timing → the .srt from the scratchpad → Publish. They carry the script's own words (lpm, Claude Code, Codex), which YouTube's auto-captions get wrong. In the current dialog Subtitles sits under Video elements and its Add stays greyed until Details → Show more → Video language is set (English); after "With timing", do not press Continue (it opens the macOS file picker): file_upload the .srt into the #captions-file-loader input, then Done.
  • thumbnail: the lesson's own thumbnail.jpg, never YouTube's auto-pick: with a cover in lesson.json it is that cover (words beside a crop of the take on the card canvas, approved 2026-09-30), otherwise the opening title card; prepare.js copies it and it is uploaded in the Thumbnail step. A new channel gets a few custom thumbnails a day; past that the upload answers "Build your channel history" and nothing is set: leave the video a private draft (untick the playlist so no private row shows) and publish the next day with the thumbnail, unless the user says otherwise.
  • title: the lesson title from lesson.json, nothing appended (no "(Mac Tutorial)"), brand is lowercase lpm, 100 characters max.
  • description: prepare.js assembles it in this order: a two-line keyword hook (what the video shows, for whom), one line on what lpm is (starts, stops, duplicates and switches between local dev projects on a Mac, with a built-in terminal for AI coding agents such as Claude Code and Codex), the link https://lpm.cx (never the demo link lpm.cx/demo, user rule 2026-09-19), "What you'll learn" bullets, any sections ([{ "heading", "lines" }]: what a viewer needs first, what to do when a step doesn't match), "Chapters" (first at 0:00, at least three, each 10 s or longer: topic cards and "chapter" narration lines in lesson.json), one series line, 5–6 hashtags (#lpm #macOS #devtools …). No @ anywhere (it opens a mention popup) and no next-lesson teaser.
  • tags: 15–20 comma-separated (lpm, lpm.cx, the lesson's own verbs and nouns, Claude Code, Codex, mac dev tools, tutorial), under 500 characters. Category Science & Technology. Audience "No, it's not made for kids". Visibility Public. Playlist: the one in YOUTUBE_PLAYLIST.md (repo root: heading = playlist title, then its URL, then the lesson titles in series order).
  • browser (Claude in Chrome MCP on the user's logged-in Chrome; channel "LPM"): navigate https://www.youtube.com/upload → find the file input → file_upload the MP4 → wait ~5 s → find the title and description textboxes, click + type → Thumbnail "Upload file" input → file_upload the JPEG → Audience radio → "Show more" → Tags textbox (type a comma after every tag) → Category: open the menu, take a full-scale screenshot, click the option by coordinate and zoom to verify (a click by find ref lands on the hovered row) → Playlists box (coordinate click) → tick the playlist → Done → Next ×3 → Public radio → Publish → copy the link from the "Video published" dialog.
  • replacing a published lesson: YouTube cannot swap the file on an existing video, so upload the new cut as a new video (same title, description recipe and thumbnail), then set the old one to Private on studio.youtube.com/video/<id>/edit (Visibility box → Private → Done → Save; the Save button stays active until the change is saved). Deleting the old video is the user's call.
  • never press Escape inside the upload dialog: it closes the dialog. The upload is already saved as a private draft; reopen it with "Edit draft" on the row. Later edits go through studio.youtube.com/video/<id>/edit, then Save.
  • playlist, after Publish: the video must end up in the playlist from YOUTUBE_PLAYLIST.md, at the position its title has in that list. Preferred path is inside the upload dialog's Details step: the Playlists box ("Select") sits under the description; open it with a coordinate click (a ref click after scroll_to did not open it), tick the playlist, Done. If it was skipped, use studio.youtube.com/video/<id>/edit → Playlists → tick → Done → Save. The playlist is manually sorted and a new video is appended last, so uploading in series order needs nothing more; otherwise open https://www.youtube.com/playlist?list=<id> on the logged-in account, and use the row's ⋮ menu (Move to top / Move to bottom) or drag the ≡ handle until the order matches the file. Then run node scripts/register.js <slug> <youtu.be link>: it records the upload in the lesson folder (published.json), puts the link on the lesson's line in YOUTUBE_PLAYLIST.md (appending the line when it is missing; move it to its series position if needed) — that file is the order of record — and prints the entry for website/lib/youtube-lessons.ts; add it there and link it from the page about that feature. Studio's playlist page (studio.youtube.com/playlist/<id>/videos) lists and removes videos but cannot reorder them.
  • verify before reporting: the row in Channel content shows Public, the thumbnail is the beige title card, the title has no suffix, and the playlist page shows the video in the right position. Report the youtu.be link, the title, the description text and the playlist position. External links stay plain text until the channel completes YouTube's one-time verification (a phone step only the user can do); say so once.

Read the full file on GitHub · 22 lines

Files

What ships with it

2 files beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 14d ago Changed 8706168359ec
  2. 23d ago First seen · 22 lines · 102 tokens per session scan A 490def42c67a

Subscribe to this mod's changes

lesson-publish is a skill published in the GitHub repository gug007/lpm (145 stars, last pushed today), licensed MIT. It adds 102 tokens to every session and 1,743 once invoked, about $0.0004 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-01.

Related

Other skills, from other repositories

orca-emulator-android

Android device and emulator control from inside Orca over adb, with the live device view in Orca's emulator pane. Use when driving an adb-connected emulator or phone on Windows, Linux, or macOS: booting AVDs, taps, swipes, typing, hardware buttons, rotation, app install and launch, runtime permissions, the…

stablyai/orca · 102 tokens

ralplan

Consensus planning entrypoint that auto-gates vague ralph/autopilot/team requests before execution.

Yeachan-Heo/oh-my-claudecode · 21 tokens

remember

Review reusable project knowledge and decide what belongs in project memory, notepad, or durable docs.

Yeachan-Heo/oh-my-claudecode · 20 tokens

test-warp-ui

Guides testing Warp UI features and changes using the computer use tool. Use this skill only when computer-use testing was requested (explicit request or accepted offer) and the computeruse tool is available to the agent. Covers launching Warp and verifying UI behavior.

warpdotdev/warp · 55 tokens

tui-migrate-setup

Migrates the supported subset of an existing Warp GUI setup into Warp Agent CLI without exposing credentials or application state. Use in Warp Agent CLI when a user wants to copy or move compatible settings or global file-based MCP servers from the desktop app, set up Warp Agent CLI from an existing GUI installation…

warpdotdev/warp · 75 tokens

blueprint-cloudflare-scaffold

Lay out a Worker with D1 and static Vue assets, with tests that run inside the Workers runtime.

receptron/mulmoterminal · 28 tokens