learn-this について
TapestryはURLからのコンテンツ抽出と行動計画を一連の流れとして実行します。YouTube動画、ウェブ記事、PDFに応じた抽出手順を選び、抽出内容とShip-Learn-Next計画を作成して保存します。
主な機能
- 01YouTube、記事、PDFのURL判定
- 02コンテンツ種別に応じた抽出手順の選択
- 03Ship-Learn-Next行動計画の作成
- 04抽出内容と計画ファイルの保存
- 05抽出失敗時の代替手段
活用シーン
- 01動画URLから実行計画を作成
- 02記事を抽出して具体的な次の手順を計画
- 03PDF文書を学習クエストに変換
- 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 スキルを使います
Web 記事/ブログ記事
判定するパターン:
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 のやり方です。