Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Unified content extraction and action planning. Use when user says "tapestry <URL>", "weave <URL>", "help me plan <URL>", "extract and plan <URL>", "make this actionable <URL>", or similar phrases indicating they want to extract content and create an action plan. Automatically detects content type (YouTube video, article, PDF) and processes accordingly.
.claude/skills/nicepkg-tapestry/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 175% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 226% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 65% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 97% | 0% |
This is the master skill that orchestrates the entire Tapestry workflow:
Activate when the user:
Keywords to watch for: tapestry, weave, plan, actionable, extract and plan, make a plan, turn into action
Patterns to detect:
youtube.com/watch?v=youtu.be/youtube.com/shorts/m.youtube.com/watch?v=Action: Use youtube-transcript skill
Patterns to detect:
http:// or https://Action: Use article-extractor skill
Patterns to detect:
.pdfContent-Type: application/pdfAction: Download and extract text
Fallback:
bashURL="$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"
bash# 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"
bash# 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"
bash# 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
IMPORTANT: Always create an action plan after extracting content.
bash# 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
Key points for plan creation:
Ship-Learn-Next Plan - [Brief Quest Title].mdShow user:
✅ 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?bash#!/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. Unsupported URL type
2. No content extracted
3. Tools not installed
4. Empty or invalid content
User: tapestry 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?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?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?This skill orchestrates the other skills, so requires:
For YouTube:
For Articles:
For PDFs:
brew install poppler (macOS)apt install poppler-utils (Linux)For Planning:
Tapestry weaves learning content into action.
The unified workflow ensures you never just consume content - you always create an implementation plan. This transforms passive learning into active building.
Extract → Plan → Ship → Learn → Next.
That's the Tapestry way.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 12,135 | 8,471 | -30% | 1 | 1 | 0% | 2,007 | 4,013 | +100% | 0 | 0 | — |
case-02 | fail→fail | 13,245 | 11,867 | -10% | 1 | 1 | 0% | 2,120 | 4,490 | +112% | 0 | 0 | — |
case-03 | fail→pass | 13,146 | 15,081 | +15% | 1 | 1 | 0% | 2,126 | 5,837 | +175% | 0 | 0 | — |
case-04 | pass→pass | 8,628 | 5,086 | -41% | 1 | 1 | 0% | 1,656 | 4,270 | +158% | 0 | 0 | — |
case-05 | pass→pass | 9,124 | 5,485 | -40% | 1 | 1 | 0% | 1,832 | 4,413 | +141% | 0 | 0 | — |
case-06 | pass→pass | 13,614 | 7,264 | -47% | 1 | 1 | 0% | 2,715 | 4,811 | +77% | 0 | 0 | — |
case-07 | pass→pass | 6,721 | 3,472 | -48% | 1 | 1 | 0% | 1,159 | 4,152 | +258% | 0 | 0 | — |
case-08 | fail→pass | 7,783 | 4,234 | -46% | 1 | 1 | 0% | 1,290 | 4,209 | +226% | 0 | 0 | — |
case-09 | fail→pass | 14,130 | 6,467 | -54% | 1 | 1 | 0% | 2,524 | 4,699 | +86% | 0 | 0 | — |
case-10 | pass→pass | 13,794 | 3,777 | -73% | 1 | 1 | 0% | 2,346 | 4,061 | +73% | 0 | 0 | — |
case-11 | pass→pass | 5,870 | 2,042 | -65% | 1 | 1 | 0% | 967 | 3,781 | +291% | 0 | 0 | — |
case-12 | fail→pass | 17,832 | 11,106 | -38% | 1 | 1 | 0% | 3,387 | 5,594 | +65% | 0 | 0 | — |
case-13 | fail→pass | 12,035 | 4,541 | -62% | 1 | 1 | 0% | 2,214 | 4,352 | +97% | 0 | 0 | — |
case-14 | fail→fail | 4,121 | 2,865 | -30% | 1 | 1 | 0% | 694 | 3,965 | +471% | 0 | 0 | — |
case-15 | pass→pass | 2,349 | 1,815 | -23% | 1 | 1 | 0% | 341 | 3,719 | +991% | 0 | 0 | — |
case-16 | fail→pass | 9,226 | 2,884 | -69% | 1 | 1 | 0% | 1,391 | 3,967 | +185% | 0 | 0 | — |
case-17 | pass→pass | 13,504 | 9,930 | -26% | 1 | 1 | 0% | 2,504 | 5,218 | +108% | 0 | 0 | — |
case-18 | pass→pass | 9,884 | 3,314 | -66% | 1 | 1 | 0% | 1,528 | 4,082 | +167% | 0 | 0 | — |
case-19 | pass→pass | 10,776 | 5,218 | -52% | 1 | 1 | 0% | 1,903 | 4,736 | +149% | 0 | 0 | — |
case-20 | pass→pass | 14,389 | 2,602 | -82% | 1 | 1 | 0% | 2,310 | 3,951 | +71% | 0 | 0 | — |
case-21 | fail→pass | 18,923 | 8,897 | -53% | 1 | 1 | 0% | 3,226 | 5,079 | +57% | 0 | 0 | — |
case-22 | pass→pass | 8,672 | 3,555 | -59% | 1 | 1 | 0% | 1,319 | 4,133 | +213% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +32 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.