关于 learn-this
Tapestry 协调整个 URL 内容提取与行动规划流程。它将 YouTube 视频、网页文章和 PDF 分流到相应的提取流程,然后生成并保存 Ship-Learn-Next 计划及提取内容。
主要功能
- 01识别 YouTube、文章和 PDF 链接
- 02按内容类型选择提取流程
- 03生成 Ship-Learn-Next 行动计划
- 04保存提取内容和计划文件
- 05提取失败时尝试备用方式
适用场景
- 01将视频链接转为实施计划
- 02提取文章并规划具体后续步骤
- 03把 PDF 文档转为学习目标
- 04收集资料后生成行动计划
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ michalparkola/ tapestry-skills --skill learn-this安装后在 Claude Code 中输入/learn-this确认已加载。
详细介绍
Tapestry:统一内容提取与行动规划
这是用于协调整个 Tapestry 工作流的主技能:
- 根据 URL 检测内容类型
- 使用相应技能提取内容
- 自动创建 Ship-Learn-Next 行动计划
何时使用此技能
在用户执行以下操作时启用:
- 说“learn-this [URL]”或“learn this [URL]”
- 说“weave [URL]”
- 说“help me plan [URL]”
- 说“extract and plan [URL]”
- 说“make this actionable [URL]”
- 说“turn [URL] into a plan”
- 提供 URL 并要求“从中学习并实施”
- 想要运行完整的 Tapestry 工作流(提取 → 规划)
需要留意的关键词:learn-this、learn this、weave、plan、actionable、extract and plan、make a plan、turn into action
工作原理
完整工作流:
- 检测 URL 类型(YouTube、文章、PDF)
- 使用相应技能提取内容:
- YouTube → youtube-transcript 技能
- 文章 → article-extractor 技能
- PDF → 下载并提取文本
- 使用 ship-learn-next 技能创建行动计划
- 保存内容文件和计划文件
- 向用户展示摘要
URL 检测逻辑
YouTube 视频
需要检测的模式:
youtube.com/watch?v=youtu.be/youtube.com/shorts/m.youtube.com/watch?v=
**操作:**使用 youtube-transcript 技能
网页文章/博客文章
需要检测的模式:
http://或https://- 不是 YouTube,也不是 PDF
- 常见域名:medium.com、substack.com、dev.to 等
- 任何 HTML 页面
**操作:**使用 article-extractor 技能
PDF 文档
需要检测的模式:
- URL 以
.pdf结尾 - URL 返回
Content-Type: application/pdf
**操作:**下载并提取文本
其他内容
回退方案:
- 尝试使用 article-extractor(适用于大多数 HTML 内容)
- 如果失败,告知用户不支持该类型
分步工作流
步骤 1:检测内容类型
URL="$1"
# Check for YouTube
if [[ "$URL" =~ youtube\.com/watch || "$URL" =~ youtu\.be/ || "$URL" =~ youtube\.com/shorts ]]; then
CONTENT_TYPE="youtube"
# Check for PDF
elif [[ "$URL" =~ \.pdf$ ]]; then
CONTENT_TYPE="pdf"
# Check if URL returns PDF
elif curl -sI "$URL" | grep -i "Content-Type: application/pdf" > /dev/null; then
CONTENT_TYPE="pdf"
# Default to article
else
CONTENT_TYPE="article"
fi
echo "📍 Detected: $CONTENT_TYPE"
步骤 2:提取内容(按类型)
YouTube 视频
# Use youtube-transcript skill workflow
echo "📺 Extracting YouTube transcript..."
# 1. Check for yt-dlp
if ! command -v yt-dlp &> /dev/null; then
echo "Installing yt-dlp..."
brew install yt-dlp
fi
# 2. Get video title
VIDEO_TITLE=$(yt-dlp --print "%(title)s" "$URL" | tr '/' '_' | tr ':' '-' | tr '?' '' | tr '"' '')
# 3. Download transcript
yt-dlp --write-auto-sub --skip-download --sub-langs en --output "temp_transcript" "$URL"
# 4. Convert to clean text (deduplicate)
python3 -c "
import sys, re
seen = set()
vtt_file = 'temp_transcript.en.vtt'
try:
with open(vtt_file, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:
clean = re.sub('<[^>]*>', '', line)
clean = clean.replace('&', '&').replace('>', '>').replace('<', '<')
if clean and clean not in seen:
print(clean)
seen.add(clean)
except FileNotFoundError:
print('Error: Could not find transcript file', file=sys.stderr)
sys.exit(1)
" > "${VIDEO_TITLE}.txt"
# 5. Cleanup
rm -f temp_transcript.en.vtt
CONTENT_FILE="${VIDEO_TITLE}.txt"
echo "✓ Saved transcript: $CONTENT_FILE"
文章/博客文章
# Use article-extractor skill workflow
echo "📄 Extracting article content..."
# 1. Check for extraction tools
if command -v reader &> /dev/null; then
TOOL="reader"
elif command -v trafilatura &> /dev/null; then
TOOL="trafilatura"
else
TOOL="fallback"
fi
echo "Using: $TOOL"
# 2. Extract based on tool
case $TOOL in
reader)
reader "$URL" > temp_article.txt
ARTICLE_TITLE=$(head -n 1 temp_article.txt | sed 's/^# //')
;;
trafilatura)
METADATA=$(trafilatura --URL "$URL" --json)
ARTICLE_TITLE=$(echo "$METADATA" | python3 -c "import json, sys; print(json.load(sys.stdin).get('title', 'Article'))")
trafilatura --URL "$URL" --output-format txt --no-comments > temp_article.txt
;;
fallback)
ARTICLE_TITLE=$(curl -s "$URL" | grep -oP '<title>\K[^<]+' | head -n 1)
ARTICLE_TITLE=${ARTICLE_TITLE%% - *}
curl -s "$URL" | python3 -c "
from html.parser import HTMLParser
import sys
class ArticleExtractor(HTMLParser):
def __init__(self):
super().__init__()
self.content = []
self.skip_tags = {'script', 'style', 'nav', 'header', 'footer', 'aside', 'form'}
self.in_content = False
def handle_starttag(self, tag, attrs):
if tag not in self.skip_tags and tag in {'p', 'article', 'main'}:
self.in_content = True
def handle_data(self, data):
if self.in_content and data.strip():
self.content.append(data.strip())
def get_content(self):
return '\n\n'.join(self.content)
parser = ArticleExtractor()
parser.feed(sys.stdin.read())
print(parser.get_content())
" > temp_article.txt
;;
esac
# 3. Clean filename
FILENAME=$(echo "$ARTICLE_TITLE" | tr '/' '-' | tr ':' '-' | tr '?' '' | tr '"' '' | cut -c 1-80 | sed 's/ *$//')
CONTENT_FILE="${FILENAME}.txt"
mv temp_article.txt "$CONTENT_FILE"
echo "✓ Saved article: $CONTENT_FILE"
PDF 文档
# Download and extract PDF
echo "📑 Downloading PDF..."
# 1. Download PDF
PDF_FILENAME=$(basename "$URL")
curl -L -o "$PDF_FILENAME" "$URL"
# 2. Extract text using pdftotext (if available)
if command -v pdftotext &> /dev/null; then
pdftotext "$PDF_FILENAME" temp_pdf.txt
CONTENT_FILE="${PDF_FILENAME%.pdf}.txt"
mv temp_pdf.txt "$CONTENT_FILE"
echo "✓ Extracted text from PDF: $CONTENT_FILE"
# Optionally keep PDF
echo "Keep original PDF? (y/n)"
read -r KEEP_PDF
if [[ ! "$KEEP_PDF" =~ ^[Yy]$ ]]; then
rm "$PDF_FILENAME"
fi
else
# No pdftotext available
echo "⚠️ pdftotext not found. PDF downloaded but not extracted."
echo " Install with: brew install poppler"
CONTENT_FILE="$PDF_FILENAME"
fi
步骤 3:创建 Ship-Learn-Next 行动计划
重要:提取内容后务必创建行动计划。
# Read the extracted content
CONTENT_FILE="[from previous step]"
# Invoke ship-learn-next skill logic:
# 1. Read the content file
# 2. Extract core actionable lessons
# 3. Create 5-rep progression plan
# 4. Save as: Ship-Learn-Next Plan - [Quest Title].md
# See ship-learn-next/SKILL.md for full details
创建计划的要点:
- 提取可付诸行动的经验教训(不只是摘要)
- 定义一个具体的 4-8 周探索任务
- 创建 Rep 1(本周即可交付)
- 设计 Rep 2-5(逐步迭代)
- 将计划保存为 Markdown 文件
- 使用格式:
Ship-Learn-Next Plan - [Brief Quest Title].md
步骤 4:展示结果
向用户展示:
✅ Tapestry Workflow Complete!
📥 Content Extracted:
✓ [Content type]: [Title]
✓ Saved to: [filename.txt]
✓ [X] words extracted
📋 Action Plan Created:
✓ Quest: [Quest title]
✓ Saved to: Ship-Learn-Next Plan - [Title].md
🎯 Your Quest: [One-line summary]
📍 Rep 1 (This Week): [Rep 1 goal]
When will you ship Rep 1?
完整的 Tapestry 工作流脚本
#!/bin/bash
# Tapestry: Extract content + create action plan
# Usage: tapestry <URL>
URL="$1"
if [ -z "$URL" ]; then
echo "Usage: tapestry <URL>"
exit 1
fi
echo "🧵 Tapestry Workflow Starting..."
echo "URL: $URL"
echo ""
# Step 1: Detect content type
if [[ "$URL" =~ youtube\.com/watch || "$URL" =~ youtu\.be/ || "$URL" =~ youtube\.com/shorts ]]; then
CONTENT_TYPE="youtube"
elif [[ "$URL" =~ \.pdf$ ]] || curl -sI "$URL" | grep -iq "Content-Type: application/pdf"; then
CONTENT_TYPE="pdf"
else
CONTENT_TYPE="article"
fi
echo "📍 Detected: $CONTENT_TYPE"
echo ""
# Step 2: Extract content
case $CONTENT_TYPE in
youtube)
echo "📺 Extracting YouTube transcript..."
# [YouTube extraction code from above]
;;
article)
echo "📄 Extracting article..."
# [Article extraction code from above]
;;
pdf)
echo "📑 Downloading PDF..."
# [PDF extraction code from above]
;;
esac
echo ""
# Step 3: Create action plan
echo "🚀 Creating Ship-Learn-Next action plan..."
# [Plan creation using ship-learn-next skill]
echo ""
echo "✅ Tapestry Workflow Complete!"
echo ""
echo "📥 Content: $CONTENT_FILE"
echo "📋 Plan: Ship-Learn-Next Plan - [title].md"
echo ""
echo "🎯 Next: Review your action plan and ship Rep 1!"
错误处理
常见问题:
1. 不支持的 URL 类型
- 尝试使用内容提取作为回退方案
- 如果失败:“无法从此 URL 类型提取内容”
2. 未提取到内容
- 检查 URL 是否可访问
- 尝试其他提取方法
- 告知用户:“提取失败。URL 可能需要身份验证。”
3. 未安装工具
- 尽可能自动安装(yt-dlp、reader、trafilatura)
- 如果自动安装失败,提供安装说明
- 有可用的回退方法时使用这些方法
4. 内容为空或无效
- 创建计划前,确认文件中有内容
- 如果提取失败,不要创建计划
- 规划前向用户展示预览
最佳实践
- ✅ 始终展示检测结果(“📍 已检测到:youtube”)
- ✅ 展示每个步骤的进度
- ✅ 同时保存内容文件和计划文件
- ✅ 展示提取内容的预览(前 10 行)
- ✅ 自动创建计划(不要询问)
- ✅ 最后提供清晰的摘要
- ✅ 询问承诺问题:“你打算什么时候交付 Rep 1?”
使用示例
示例 1:YouTube 视频(使用“learn-this”)
User: learn-this https://www.youtube.com/watch?v=dQw4w9WgXcQ
Claude:
🧵 Tapestry Workflow Starting...
📍 Detected: youtube
📺 Extracting YouTube transcript...
✓ Saved transcript: Never Gonna Give You Up.txt
🚀 Creating action plan...
✓ Quest: Master Video Production
✓ Saved plan: Ship-Learn-Next Plan - Master Video Production.md
✅ Complete! When will you ship Rep 1?
示例 2:文章(使用“weave”)
User: weave https://example.com/how-to-build-saas
Claude:
🧵 Tapestry Workflow Starting...
📍 Detected: article
📄 Extracting article...
✓ Using reader (Mozilla Readability)
✓ Saved article: How to Build a SaaS.txt
🚀 Creating action plan...
✓ Quest: Build a SaaS MVP
✓ Saved plan: Ship-Learn-Next Plan - Build a SaaS MVP.md
✅ Complete! When will you ship Rep 1?
示例 3:PDF(使用“help me plan”)
User: help me plan https://example.com/research-paper.pdf
Claude:
🧵 Tapestry Workflow Starting...
📍 Detected: pdf
📑 Downloading PDF...
✓ Downloaded: research-paper.pdf
✓ Extracted text: research-paper.txt
🚀 Creating action plan...
✓ Quest: Apply Research Findings
✓ Saved plan: Ship-Learn-Next Plan - Apply Research Findings.md
✅ Complete! When will you ship Rep 1?
依赖项
此技能会协调其他技能,因此需要:
对于 YouTube:
- yt-dlp(自动安装)
- Python 3(用于去重)
对于文章:
- reader(npm)或 trafilatura(pip)
- 如果两者都不可用,则回退到基本的 curl
对于 PDF:
- curl(内置)
- pdftotext(可选,来自 poppler 软件包)
- 安装:
brew install poppler(macOS) - 安装:
apt install poppler-utils(Linux)
- 安装:
对于规划:
- 无额外要求(使用内置工具)
理念
Tapestry 将学习内容编织成行动。
统一工作流确保你不会只是消费内容,而是始终制定实施计划。这会将被动学习转变为主动实践。
提取 → 规划 → 交付 → 学习 → 下一步。
这就是 Tapestry 之道。
评论
支持 Markdown