[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C2T5BWKCJDPS82F8W2VACQ":3,"skill-same:01M6C2T5BWKCJDPS82F8W2VACQ":53},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":14,"categories":15,"keywords":21,"publishedAt":27,"linkOnly":28,"markdownContent":29,"markdownBody":30,"frontMatter":31,"refName":32,"commitSha":33,"skillDirectory":34,"forksCount":35,"repositoryHtmlUrl":36,"repositoryHomepageUrl":6,"ownerHtmlUrl":37,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":38,"install":39,"resources":52},"01M6C2T5BWKCJDPS82F8W2VACQ","video-edit-letterbox-caption",null,"jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills_archive\u002F2026-08-27-historical-zero-use\u002Fvideo-edit-letterbox-caption\u002FSKILL.md",[16],{"categoryNo":17,"categoryName":18,"taxonomyType":19,"taxonomyTypeDesc":20},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[22,23,24,25,26],"Video","edit","video edit letterbox caption","video edit","letterbox","2026-11-10 10:12:30",false,"---\nname: video-edit-letterbox-caption\ndescription: Add burned-in captions to a screen-recording \u002F gameplay video WITHOUT blocking the video content. Use when the user wants captions ABOVE the gameplay (e.g. \"put captions above\", \"don't block the video\", \"letterbox the captions\", \"extend the video vertically with a black bar at the top\"). Combines two techniques: (a) trim static 5+ second segments via ffmpeg scene-change detection so the final video is tighter, and (b) render letterbox caption PNGs and burn them into a black bar at the top of the video so the game\u002Fscreen area is 100% unobstructed. Use INSTEAD of the video-caption skill when the user explicitly objects to captions blocking the video.\n---\n\n# Video Edit: Letterbox Captions + Static Trim\n\n## When to use this skill (not the basic `video-caption` skill)\n\nUse this skill when the user wants ALL of:\n\n1. **Captions above the video** — explicitly says \"above\", \"letterbox\", \"black bar at top\", \"don't block\", \"extend the video vertically\", or otherwise rejects top-overlay captions.\n2. **Static 5+ second segments trimmed out** — says \"remove the boring parts\", \"trim where the character isn't moving\", \"5-second freeze\", \"cut the static moments\".\n\nIf only one of the two is needed, prefer the simpler skill:\n\n- Captions only (top overlay OK) → use `~\u002F.claude\u002Fskills\u002Fvideo-caption\u002FSKILL.md`\n- Trim only, no captions → just run `ffmpeg -vf \"select=...,setpts=...\"` directly, no skill needed\n\n## Provenance (why this skill exists)\n\nThis pattern was first used by the user on **2026-05-16 in Slack `#all-$USER-ai`** for a YouTube walkthrough: *\"Lets extend the video vertically by adding a black bar at the top for the new captions so they dont block the video.\"* It was re-used **2026-07-11** for the `worldai_claw_v60` gameplay capture (Slack thread 1778907665.216479), where the user also added *\"lets remove parts of the video where the character isnt moving for 5 seconds or trim\"* — hence combining the two into one skill.\n\n## The two-pass workflow\n\n### Pass 1 — Detect static segments\n\nGoal: rank minutes by activity so you can pick which minutes to trim.\n\n```bash\n# Per-frame scene-change scores (0.0 = identical, 1.0 = totally different)\nffmpeg -y -i INPUT.mp4 \\\n  -vf \"select='gte(scene\\,0)',metadata=print:file=\u002Ftmp\u002Fscene_scores.txt\" \\\n  -an -vsync vfr -f null - 2>&1 | tail -3\n\n# Parse scores, compute per-second mean, rank minutes by activity\npython3 \u003C\u003C 'PY'\nimport re, statistics, json\nwith open('\u002Ftmp\u002Fscene_scores.txt') as f:\n    pat = re.compile(r'frame:(\\d+)\\s+pts:\\d+\\s+pts_time:([\\d.]+)\\s*\\n\\s*lavfi\\.scene_score=([\\d.]+)')\n    scores = [{'t': float(m[1]), 's': float(m[2])} for m in pat.findall(f.read())]\n\n# Per-second mean\nseconds = {}\nfor r in scores:\n    seconds.setdefault(int(r['t']), []).append(r['s'])\nper_sec = [{'sec': k, 'mean': statistics.mean(v), 'max': max(v)} for k, v in seconds.items()]\n\n# Per-minute activity\nfor start in range(0, 600, 60):\n    chunk = [p for p in per_sec if start \u003C= p['sec'] \u003C start+60]\n    active = sum(1 for p in chunk if p['mean'] > 0.003 or p['max'] > 0.02)\n    avg_mean = statistics.mean(p['mean'] for p in chunk) if chunk else 0\n    print(f\"min {start\u002F\u002F60+1:2d} ({start:3d}-{start+60}s): active={active:2d}\u002F60  mean={avg_mean:.4f}\")\nPY\n```\n\n**Thresholds** (calibrated on the 2026-07-11 `worldai_claw_v60` capture, 30 fps):\n\n| Per-second mean | Verdict |\n|---|---|\n| `\u003C 0.001` AND no frame > 0.02 | idle \u002F no movement |\n| `0.001 – 0.005` | light motion (walking, dialog spinner) |\n| `> 0.005` OR frame > 0.02 | active (UI change, scene transition) |\n\nA minute with **\u003C 10 active seconds** out of 60 is a candidate to trim.\n\n### Pass 2 — Trim static minutes\n\nFor the boring minutes identified in Pass 1 (e.g. `t=120-180` and `t=420-480`):\n\n```bash\nffmpeg -y -i INPUT.mp4 \\\n  -vf \"select='not(between(t,120,180)+between(t,420,480))',setpts=N\u002F(30*TB)\" \\\n  -an -c:v libx264 -crf 18 -preset fast \\\n  -movflags +faststart \\\n  OUTPUT_trimcut.mp4\n```\n\nThe `setpts=N\u002F(30*TB)` resets timestamps so the output is a contiguous 0-to-(N-1)\u002F30 timeline.\n\n**Always renumber captions for the trimmed timeline** — never carry the original minute numbers over, because they no longer correspond to wall-clock minutes.\n\n### Pass 3 — Render letterbox caption PNGs\n\nEach caption is a 1280×200 opaque black PNG with white 26-pt Helvetica text, vertically centered in the 200px bar. The width matches the source video (1280); height matches the black bar.\n\n```python\nfrom PIL import Image, ImageDraw, ImageFont\nimport textwrap\n\nVIDEO_W, CAP_H = 1280, 200\nfont = ImageFont.truetype('\u002FSystem\u002FLibrary\u002FFonts\u002FHelvetica.ttc', 26)\navg_char_w = 26 * 0.55\nmax_chars = int((VIDEO_W - 2*24) \u002F avg_char_w)  # 48px padding\n\nfor idx, (start, end, text) in enumerate(captions):\n    lines = textwrap.wrap(text, width=max_chars)\n    line_h = 26 + 6\n    img = Image.new('RGBA', (VIDEO_W, CAP_H), (0, 0, 0, 255))  # opaque black\n    draw = ImageDraw.Draw(img)\n    total_h = line_h * len(lines)\n    y = (CAP_H - total_h) \u002F\u002F 2  # vertical center\n    for line in lines:\n        draw.text((24, y), line, font=font, fill=(255, 255, 255, 255))\n        y += line_h\n    img.save(f'\u002Ftmp\u002Fcaps\u002Fcap_{idx:02d}.png')\n```\n\n### Pass 4 — Pad + overlay (the actual \"letterbox\")\n\n```bash\n# Pad source 1280x900 → 1280x1100 (200px black bar at top), then chain overlays\nffmpeg -y -i TRIMMED.mp4 \\\n  -i cap_00.png -i cap_01.png -i cap_02.png ... -i cap_07.png \\\n  -filter_complex \"\n    [0:v]scale=1280:900,pad=1280:1100:0:200:black[padded];\n    [1:v]scale=1280:200[c1];\n    [2:v]scale=1280:200[c2];\n    ...\n    [padded][c1]overlay=0:0:enable='between(t,0,60)'[v1];\n    [v1][c2]overlay=0:0:enable='between(t,60,120)'[v2];\n    ...\n    [v7][c8]overlay=0:0:enable='between(t,420,480)'[vout]\n  \" \\\n  -map '[vout]' \\\n  -c:v libx264 -crf 20 -preset medium -an \\\n  -movflags +faststart \\\n  OUTPUT_letterbox.mp4\n```\n\n**Critical filter-graph gotchas:**\n\n1. **`enable='...'` MUST be in single quotes** — the commas inside `between(t,A,B)` are parsed as filter-chain separators unless quoted. Symptom: `Error: No such filter: '0'`.\n2. **`pad=1280:1100:0:200:black`** — args are `output_w:output_h:x:y:color`. `x=0, y=200` means \"place the original video in the bottom 900px, leaving 200px black at top\".\n3. **Each caption PNG needs an explicit `scale=1280:200`** before overlay — ffmpeg doesn't auto-scale PNG inputs.\n\n## Working example\n\nCaptured **2026-07-11** for `$HOME\u002FDownloads\u002Fworldai_claw_v60_gameplay_20260711.mp4` (58 min, 1280×900, 30 fps, no audio):\n\n1. Identified 35:00–45:00 as the most-engaging 10-min window (engagement peaks at 39:00 quest hook and 15:00 Dain Fletcher smithy).\n2. Extracted 600 frames at 1 fps for 35:00–45:00.\n3. Dispatched 10 parallel agents (1 per minute) for chunk descriptions + burn captions.\n4. Ran scene-change detection — minute 3 (120–180s, 2 active sec\u002F60) and minute 8 (420–480s, 0 active sec\u002F60) were the most static.\n5. Trimmed those 2 minutes → 480 s output.\n6. Renumbered captions: old minutes 1, 2, 4, 5, 6, 7, 9, 10 → new minutes 1–8.\n7. Rendered 8 letterbox caption PNGs (1280×200 each).\n8. Pad+overlay → 1280×1100, 8 min, captions ABOVE the game area.\n\nFinal outputs (in `~\u002FDocuments\u002F`):\n- `worldai_v60_35-45_letterbox.mp4` (37 MB) — captions above, game unobstructed\n- `worldai_v60_35-45_trimcut.mp4` (39 MB) — trimmed, no captions\n\n## Quick reference\n\n| Step | Tool | Key detail |\n|---|---|---|\n| Scene scores | `ffmpeg -vf \"select='gte(scene\\\\,0)',metadata=print\"` | per-frame 0–1 score; aggregate to per-second mean |\n| Rank minutes | Python `statistics.mean` | active_sec > 0.003 mean OR > 0.02 max = active |\n| Trim | `select='not(between(t,A,B)+...)',setpts=N\u002F(30*TB)` | renumber captions after trim |\n| Render captions | PIL `Image.new('RGBA', (W, H), (0,0,0,255))` | opaque black, vertical-center text |\n| Letterbox pad | `pad=1280:1100:0:200:black` | args: out_w:out_h:x:y:color |\n| Overlay chain | `[prev][cap]overlay=0:0:enable='between(t,A,B)'` | **single-quote the enable expression** |\n\n## Common mistakes\n\n- **Putting captions in a transparent overlay on top of the video** — that's the `video-caption` skill. Don't use it here; the user has explicitly rejected that.\n- **Forgetting `setpts=N\u002F(30*TB)` after `select=`** — output plays at wrong speed; ffmpeg tries to fill the original duration with fewer frames.\n- **Unquoted commas in `between(t,A,B)`** — `[AVFilterGraph] No such filter: '0'`. Always wrap the enable expression in single quotes.\n- **Pad x\u002Fy wrong direction** — `pad=1280:1100:0:200:black` puts video at the BOTTOM. `pad=1280:1100:0:0:black` would put it at the top with black at bottom. Always make `y = CAP_H` so video stays put.\n- **Caption PNG not scaled** — overlay draws at the PNG's native size. If your PNG is 640×200 but the bar is 1280×200, text fills only half the bar. Always `scale=1280:200` before `overlay=`.\n\n## Files & references\n\n- `scripts\u002Frender_and_burn.py` — full Python pipeline that does passes 2–4 in one shot. Adapted from `\u002Ftmp\u002Fwai_v60_caps\u002Fcaptions_v2.py`.\n- `references\u002Fstatic-detection.md` — deeper notes on the scene-change threshold calibration, including the per-second analysis table from the 2026-07-11 run.\n- See also: `~\u002F.claude\u002Fskills\u002Fvideo-caption\u002FSKILL.md` (overlay-on-top variant, use when blocking is OK).","# Video Edit: Letterbox Captions + Static Trim\n\n## When to use this skill (not the basic `video-caption` skill)\n\nUse this skill when the user wants ALL of:\n\n1. **Captions above the video** — explicitly says \"above\", \"letterbox\", \"black bar at top\", \"don't block\", \"extend the video vertically\", or otherwise rejects top-overlay captions.\n2. **Static 5+ second segments trimmed out** — says \"remove the boring parts\", \"trim where the character isn't moving\", \"5-second freeze\", \"cut the static moments\".\n\nIf only one of the two is needed, prefer the simpler skill:\n\n- Captions only (top overlay OK) → use `~\u002F.claude\u002Fskills\u002Fvideo-caption\u002FSKILL.md`\n- Trim only, no captions → just run `ffmpeg -vf \"select=...,setpts=...\"` directly, no skill needed\n\n## Provenance (why this skill exists)\n\nThis pattern was first used by the user on **2026-05-16 in Slack `#all-$USER-ai`** for a YouTube walkthrough: *\"Lets extend the video vertically by adding a black bar at the top for the new captions so they dont block the video.\"* It was re-used **2026-07-11** for the `worldai_claw_v60` gameplay capture (Slack thread 1778907665.216479), where the user also added *\"lets remove parts of the video where the character isnt moving for 5 seconds or trim\"* — hence combining the two into one skill.\n\n## The two-pass workflow\n\n### Pass 1 — Detect static segments\n\nGoal: rank minutes by activity so you can pick which minutes to trim.\n\n```bash\n# Per-frame scene-change scores (0.0 = identical, 1.0 = totally different)\nffmpeg -y -i INPUT.mp4 \\\n  -vf \"select='gte(scene\\,0)',metadata=print:file=\u002Ftmp\u002Fscene_scores.txt\" \\\n  -an -vsync vfr -f null - 2>&1 | tail -3\n\n# Parse scores, compute per-second mean, rank minutes by activity\npython3 \u003C\u003C 'PY'\nimport re, statistics, json\nwith open('\u002Ftmp\u002Fscene_scores.txt') as f:\n    pat = re.compile(r'frame:(\\d+)\\s+pts:\\d+\\s+pts_time:([\\d.]+)\\s*\\n\\s*lavfi\\.scene_score=([\\d.]+)')\n    scores = [{'t': float(m[1]), 's': float(m[2])} for m in pat.findall(f.read())]\n\n# Per-second mean\nseconds = {}\nfor r in scores:\n    seconds.setdefault(int(r['t']), []).append(r['s'])\nper_sec = [{'sec': k, 'mean': statistics.mean(v), 'max': max(v)} for k, v in seconds.items()]\n\n# Per-minute activity\nfor start in range(0, 600, 60):\n    chunk = [p for p in per_sec if start \u003C= p['sec'] \u003C start+60]\n    active = sum(1 for p in chunk if p['mean'] > 0.003 or p['max'] > 0.02)\n    avg_mean = statistics.mean(p['mean'] for p in chunk) if chunk else 0\n    print(f\"min {start\u002F\u002F60+1:2d} ({start:3d}-{start+60}s): active={active:2d}\u002F60  mean={avg_mean:.4f}\")\nPY\n```\n\n**Thresholds** (calibrated on the 2026-07-11 `worldai_claw_v60` capture, 30 fps):\n\n| Per-second mean | Verdict |\n|---|---|\n| `\u003C 0.001` AND no frame > 0.02 | idle \u002F no movement |\n| `0.001 – 0.005` | light motion (walking, dialog spinner) |\n| `> 0.005` OR frame > 0.02 | active (UI change, scene transition) |\n\nA minute with **\u003C 10 active seconds** out of 60 is a candidate to trim.\n\n### Pass 2 — Trim static minutes\n\nFor the boring minutes identified in Pass 1 (e.g. `t=120-180` and `t=420-480`):\n\n```bash\nffmpeg -y -i INPUT.mp4 \\\n  -vf \"select='not(between(t,120,180)+between(t,420,480))',setpts=N\u002F(30*TB)\" \\\n  -an -c:v libx264 -crf 18 -preset fast \\\n  -movflags +faststart \\\n  OUTPUT_trimcut.mp4\n```\n\nThe `setpts=N\u002F(30*TB)` resets timestamps so the output is a contiguous 0-to-(N-1)\u002F30 timeline.\n\n**Always renumber captions for the trimmed timeline** — never carry the original minute numbers over, because they no longer correspond to wall-clock minutes.\n\n### Pass 3 — Render letterbox caption PNGs\n\nEach caption is a 1280×200 opaque black PNG with white 26-pt Helvetica text, vertically centered in the 200px bar. The width matches the source video (1280); height matches the black bar.\n\n```python\nfrom PIL import Image, ImageDraw, ImageFont\nimport textwrap\n\nVIDEO_W, CAP_H = 1280, 200\nfont = ImageFont.truetype('\u002FSystem\u002FLibrary\u002FFonts\u002FHelvetica.ttc', 26)\navg_char_w = 26 * 0.55\nmax_chars = int((VIDEO_W - 2*24) \u002F avg_char_w)  # 48px padding\n\nfor idx, (start, end, text) in enumerate(captions):\n    lines = textwrap.wrap(text, width=max_chars)\n    line_h = 26 + 6\n    img = Image.new('RGBA', (VIDEO_W, CAP_H), (0, 0, 0, 255))  # opaque black\n    draw = ImageDraw.Draw(img)\n    total_h = line_h * len(lines)\n    y = (CAP_H - total_h) \u002F\u002F 2  # vertical center\n    for line in lines:\n        draw.text((24, y), line, font=font, fill=(255, 255, 255, 255))\n        y += line_h\n    img.save(f'\u002Ftmp\u002Fcaps\u002Fcap_{idx:02d}.png')\n```\n\n### Pass 4 — Pad + overlay (the actual \"letterbox\")\n\n```bash\n# Pad source 1280x900 → 1280x1100 (200px black bar at top), then chain overlays\nffmpeg -y -i TRIMMED.mp4 \\\n  -i cap_00.png -i cap_01.png -i cap_02.png ... -i cap_07.png \\\n  -filter_complex \"\n    [0:v]scale=1280:900,pad=1280:1100:0:200:black[padded];\n    [1:v]scale=1280:200[c1];\n    [2:v]scale=1280:200[c2];\n    ...\n    [padded][c1]overlay=0:0:enable='between(t,0,60)'[v1];\n    [v1][c2]overlay=0:0:enable='between(t,60,120)'[v2];\n    ...\n    [v7][c8]overlay=0:0:enable='between(t,420,480)'[vout]\n  \" \\\n  -map '[vout]' \\\n  -c:v libx264 -crf 20 -preset medium -an \\\n  -movflags +faststart \\\n  OUTPUT_letterbox.mp4\n```\n\n**Critical filter-graph gotchas:**\n\n1. **`enable='...'` MUST be in single quotes** — the commas inside `between(t,A,B)` are parsed as filter-chain separators unless quoted. Symptom: `Error: No such filter: '0'`.\n2. **`pad=1280:1100:0:200:black`** — args are `output_w:output_h:x:y:color`. `x=0, y=200` means \"place the original video in the bottom 900px, leaving 200px black at top\".\n3. **Each caption PNG needs an explicit `scale=1280:200`** before overlay — ffmpeg doesn't auto-scale PNG inputs.\n\n## Working example\n\nCaptured **2026-07-11** for `$HOME\u002FDownloads\u002Fworldai_claw_v60_gameplay_20260711.mp4` (58 min, 1280×900, 30 fps, no audio):\n\n1. Identified 35:00–45:00 as the most-engaging 10-min window (engagement peaks at 39:00 quest hook and 15:00 Dain Fletcher smithy).\n2. Extracted 600 frames at 1 fps for 35:00–45:00.\n3. Dispatched 10 parallel agents (1 per minute) for chunk descriptions + burn captions.\n4. Ran scene-change detection — minute 3 (120–180s, 2 active sec\u002F60) and minute 8 (420–480s, 0 active sec\u002F60) were the most static.\n5. Trimmed those 2 minutes → 480 s output.\n6. Renumbered captions: old minutes 1, 2, 4, 5, 6, 7, 9, 10 → new minutes 1–8.\n7. Rendered 8 letterbox caption PNGs (1280×200 each).\n8. Pad+overlay → 1280×1100, 8 min, captions ABOVE the game area.\n\nFinal outputs (in `~\u002FDocuments\u002F`):\n- `worldai_v60_35-45_letterbox.mp4` (37 MB) — captions above, game unobstructed\n- `worldai_v60_35-45_trimcut.mp4` (39 MB) — trimmed, no captions\n\n## Quick reference\n\n| Step | Tool | Key detail |\n|---|---|---|\n| Scene scores | `ffmpeg -vf \"select='gte(scene\\\\,0)',metadata=print\"` | per-frame 0–1 score; aggregate to per-second mean |\n| Rank minutes | Python `statistics.mean` | active_sec > 0.003 mean OR > 0.02 max = active |\n| Trim | `select='not(between(t,A,B)+...)',setpts=N\u002F(30*TB)` | renumber captions after trim |\n| Render captions | PIL `Image.new('RGBA', (W, H), (0,0,0,255))` | opaque black, vertical-center text |\n| Letterbox pad | `pad=1280:1100:0:200:black` | args: out_w:out_h:x:y:color |\n| Overlay chain | `[prev][cap]overlay=0:0:enable='between(t,A,B)'` | **single-quote the enable expression** |\n\n## Common mistakes\n\n- **Putting captions in a transparent overlay on top of the video** — that's the `video-caption` skill. Don't use it here; the user has explicitly rejected that.\n- **Forgetting `setpts=N\u002F(30*TB)` after `select=`** — output plays at wrong speed; ffmpeg tries to fill the original duration with fewer frames.\n- **Unquoted commas in `between(t,A,B)`** — `[AVFilterGraph] No such filter: '0'`. Always wrap the enable expression in single quotes.\n- **Pad x\u002Fy wrong direction** — `pad=1280:1100:0:200:black` puts video at the BOTTOM. `pad=1280:1100:0:0:black` would put it at the top with black at bottom. Always make `y = CAP_H` so video stays put.\n- **Caption PNG not scaled** — overlay draws at the PNG's native size. If your PNG is 640×200 but the bar is 1280×200, text fills only half the bar. Always `scale=1280:200` before `overlay=`.\n\n## Files & references\n\n- `scripts\u002Frender_and_burn.py` — full Python pipeline that does passes 2–4 in one shot. Adapted from `\u002Ftmp\u002Fwai_v60_caps\u002Fcaptions_v2.py`.\n- `references\u002Fstatic-detection.md` — deeper notes on the scene-change threshold calibration, including the per-second analysis table from the 2026-07-11 run.\n- See also: `~\u002F.claude\u002Fskills\u002Fvideo-caption\u002FSKILL.md` (overlay-on-top variant, use when blocking is OK).",{},"main","42ccd02cbf5e8e47839dc3eab6fc754dc6b339cf",".claude\u002Fskills_archive\u002F2026-08-27-historical-zero-use\u002Fvideo-edit-letterbox-caption",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-11 22:19:36",{"source":7,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill video-edit-letterbox-caption",{"tool":45,"command":46},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill video-edit-letterbox-caption",{"tool":48,"command":49},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill video-edit-letterbox-caption","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills_archive\u002F2026-08-27-historical-zero-use\u002Fvideo-edit-letterbox-caption\u002FSKILL.md",true,[],[54,72,94,108,122,138],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":27},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[56,61,62,63,64,65,66,67,68,69,70,71],"user","when","replies","check","use","identity","whatsapp","gmail","read","message","ask",{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":27},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[74,84,85,86,87,88,89,90,91,92,93],"resume","compatibility","provenance","for","history","produce","alias","briefing","state","fresh",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":101,"publishedAt":27},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[100],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},[88,84,102,103,61,104,91,105,87,106,107,92,93],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":27},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[110,115,116,117,87,118,90,119,120,121],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":13,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":128,"publishedAt":27},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[129,130,131,65,132,87,133,134,135,136,137],"codexa bench","work","split","default","duplicate","task","compare","normal","codex",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":6,"repositoryNo":11,"starsCount":12,"licenseSpdxId":142,"licenseFileUrl":143,"sourceHtmlUrl":144,"categories":145,"keywords":155,"publishedAt":27},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[146,149,152],{"categoryNo":147,"categoryName":148,"taxonomyType":19,"taxonomyTypeDesc":20},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":150,"categoryName":151,"taxonomyType":19,"taxonomyTypeDesc":20},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":153,"categoryName":154,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000032","设计师",[156,157,158,65,159,160,161,61,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,62,180],"frontend","design","frontend design","generic","ui design","react","html","components","code","artifacts","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]