[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JA6B6BAAFPGPFF8YX0FDKX":3,"skill-same:01M6JA6B6BAAFPGPFF8YX0FDKX":93},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":57,"linkOnly":58,"markdownContent":59,"markdownBody":60,"frontMatter":61,"refName":72,"commitSha":73,"skillDirectory":74,"forksCount":66,"repositoryHtmlUrl":75,"repositoryHomepageUrl":6,"ownerHtmlUrl":76,"ownerBlogUrl":77,"ownerDescription":78,"updatedAt":79,"install":80,"resources":92},"01M6JA6B6BAAFPGPFF8YX0FDKX","tapestry-learn-this",null,"Unified content extraction and action planning. Use when user says \"learn-this \u003CURL>\", \"learn this \u003CURL>\", \"weave \u003CURL>\", \"help me plan \u003CURL>\", \"extract and plan \u003CURL>\", \"make this actionable \u003CURL>\", 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.","Flissel\u002Fvibemind-os","Flissel","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F104565236?v=4","01M6J8Q88NWAJGKPC5TEG9YCNV","Felix Baumann","01M6J8Q8D7XAFY44P70XTJFZBW",1,"MIT","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fskills\u002Ftapestry\u002Flearn-this\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],"learn","tapestry learn this","learn this","article","2026","when","source","action","true","URL","make","actionable","PDF","imported","me","youtube","repo","weave","plan","Video","planning","create","2026-11-10 10:12:30",false,"---\nname: tapestry-learn-this\ndescription: Unified content extraction and action planning. Use when user says \"learn-this\n  \u003CURL>\", \"learn this \u003CURL>\", \"weave \u003CURL>\", \"help me plan \u003CURL>\", \"extract and plan\n  \u003CURL>\", \"make this actionable \u003CURL>\", or similar phrases indicating they want to\n  extract content and create an action plan. Automatically detects content type (YouTube\n  video, article, PDF) and processes accordingly.\napp: tapestry\nrequires_approval: true\nagents:\n- '*'\ninputs: []\nexpected_state:\n  description: Imported skill — behavior matches source repo\n  verification_tool: none\nconfidence: 1.0\nattempts: 0\nsuccesses: 0\nlast_adjusted: '2026-05-11T21:21:57+00:00'\n---\n\n# Tapestry: Unified Content Extraction + Action Planning\n\nThis is the **master skill** that orchestrates the entire Tapestry workflow:\n1. Detect content type from URL\n2. Extract content using appropriate skill\n3. Automatically create a Ship-Learn-Next action plan\n\n## When to Use This Skill\n\nActivate when the user:\n- Says \"learn-this [URL]\" or \"learn this [URL]\"\n- Says \"weave [URL]\"\n- Says \"help me plan [URL]\"\n- Says \"extract and plan [URL]\"\n- Says \"make this actionable [URL]\"\n- Says \"turn [URL] into a plan\"\n- Provides a URL and asks to \"learn and implement from this\"\n- Wants the full Tapestry workflow (extract → plan)\n\n**Keywords to watch for**: learn-this, learn this, weave, plan, actionable, extract and plan, make a plan, turn into action\n\n## How It Works\n\n### Complete Workflow:\n1. **Detect URL type** (YouTube, article, PDF)\n2. **Extract content** using appropriate skill:\n   - YouTube → youtube-transcript skill\n   - Article → article-extractor skill\n   - PDF → download and extract text\n3. **Create action plan** using ship-learn-next skill\n4. **Save both** content file and plan file\n5. **Present summary** to user\n\n## URL Detection Logic\n\n### YouTube Videos\n\n**Patterns to detect:**\n- `youtube.com\u002Fwatch?v=`\n- `youtu.be\u002F`\n- `youtube.com\u002Fshorts\u002F`\n- `m.youtube.com\u002Fwatch?v=`\n\n**Action:** Use youtube-transcript skill\n\n### Web Articles\u002FBlog Posts\n\n**Patterns to detect:**\n- `http:\u002F\u002F` or `https:\u002F\u002F`\n- NOT YouTube, NOT PDF\n- Common domains: medium.com, substack.com, dev.to, etc.\n- Any HTML page\n\n**Action:** Use article-extractor skill\n\n### PDF Documents\n\n**Patterns to detect:**\n- URL ends with `.pdf`\n- URL returns `Content-Type: application\u002Fpdf`\n\n**Action:** Download and extract text\n\n### Other Content\n\n**Fallback:**\n- Try article-extractor (works for most HTML)\n- If fails, inform user of unsupported type\n\n## Step-by-Step Workflow\n\n### Step 1: Detect Content Type\n\n```bash\nURL=\"$1\"\n\n# Check for YouTube\nif [[ \"$URL\" =~ youtube\\.com\u002Fwatch || \"$URL\" =~ youtu\\.be\u002F || \"$URL\" =~ youtube\\.com\u002Fshorts ]]; then\n    CONTENT_TYPE=\"youtube\"\n\n# Check for PDF\nelif [[ \"$URL\" =~ \\.pdf$ ]]; then\n    CONTENT_TYPE=\"pdf\"\n\n# Check if URL returns PDF\nelif curl -sI \"$URL\" | grep -i \"Content-Type: application\u002Fpdf\" > \u002Fdev\u002Fnull; then\n    CONTENT_TYPE=\"pdf\"\n\n# Default to article\nelse\n    CONTENT_TYPE=\"article\"\nfi\n\necho \"? Detected: $CONTENT_TYPE\"\n```\n\n### Step 2: Extract Content (by Type)\n\n#### YouTube Video\n\n```bash\n# Use youtube-transcript skill workflow\necho \"? Extracting YouTube transcript...\"\n\n# 1. Check for yt-dlp\nif ! command -v yt-dlp &> \u002Fdev\u002Fnull; then\n    echo \"Installing yt-dlp...\"\n    brew install yt-dlp\nfi\n\n# 2. Get video title\nVIDEO_TITLE=$(yt-dlp --print \"%(title)s\" \"$URL\" | tr '\u002F' '_' | tr ':' '-' | tr '?' '' | tr '\"' '')\n\n# 3. Download transcript\nyt-dlp --write-auto-sub --skip-download --sub-langs en --output \"temp_transcript\" \"$URL\"\n\n# 4. Convert to clean text (deduplicate)\npython3 -c \"\nimport sys, re\nseen = set()\nvtt_file = 'temp_transcript.en.vtt'\ntry:\n    with open(vtt_file, 'r') as f:\n        for line in f:\n            line = line.strip()\n            if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:\n                clean = re.sub('\u003C[^>]*>', '', line)\n                clean = clean.replace('&amp;', '&').replace('&gt;', '>').replace('&lt;', '\u003C')\n                if clean and clean not in seen:\n                    print(clean)\n                    seen.add(clean)\nexcept FileNotFoundError:\n    print('Error: Could not find transcript file', file=sys.stderr)\n    sys.exit(1)\n\" > \"${VIDEO_TITLE}.txt\"\n\n# 5. Cleanup\nrm -f temp_transcript.en.vtt\n\nCONTENT_FILE=\"${VIDEO_TITLE}.txt\"\necho \"✓ Saved transcript: $CONTENT_FILE\"\n```\n\n#### Article\u002FBlog Post\n\n```bash\n# Use article-extractor skill workflow\necho \"? Extracting article content...\"\n\n# 1. Check for extraction tools\nif command -v reader &> \u002Fdev\u002Fnull; then\n    TOOL=\"reader\"\nelif command -v trafilatura &> \u002Fdev\u002Fnull; then\n    TOOL=\"trafilatura\"\nelse\n    TOOL=\"fallback\"\nfi\n\necho \"Using: $TOOL\"\n\n# 2. Extract based on tool\ncase $TOOL in\n    reader)\n        reader \"$URL\" > temp_article.txt\n        ARTICLE_TITLE=$(head -n 1 temp_article.txt | sed 's\u002F^# \u002F\u002F')\n        ;;\n\n    trafilatura)\n        METADATA=$(trafilatura --URL \"$URL\" --json)\n        ARTICLE_TITLE=$(echo \"$METADATA\" | python3 -c \"import json, sys; print(json.load(sys.stdin).get('title', 'Article'))\")\n        trafilatura --URL \"$URL\" --output-format txt --no-comments > temp_article.txt\n        ;;\n\n    fallback)\n        ARTICLE_TITLE=$(curl -s \"$URL\" | grep -oP '\u003Ctitle>\\K[^\u003C]+' | head -n 1)\n        ARTICLE_TITLE=${ARTICLE_TITLE%% - *}\n        curl -s \"$URL\" | python3 -c \"\nfrom html.parser import HTMLParser\nimport sys\n\nclass ArticleExtractor(HTMLParser):\n    def __init__(self):\n        super().__init__()\n        self.content = []\n        self.skip_tags = {'script', 'style', 'nav', 'header', 'footer', 'aside', 'form'}\n        self.in_content = False\n\n    def handle_starttag(self, tag, attrs):\n        if tag not in self.skip_tags and tag in {'p', 'article', 'main'}:\n            self.in_content = True\n\n    def handle_data(self, data):\n        if self.in_content and data.strip():\n            self.content.append(data.strip())\n\n    def get_content(self):\n        return '\\n\\n'.join(self.content)\n\nparser = ArticleExtractor()\nparser.feed(sys.stdin.read())\nprint(parser.get_content())\n\" > temp_article.txt\n        ;;\nesac\n\n# 3. Clean filename\nFILENAME=$(echo \"$ARTICLE_TITLE\" | tr '\u002F' '-' | tr ':' '-' | tr '?' '' | tr '\"' '' | cut -c 1-80 | sed 's\u002F *$\u002F\u002F')\nCONTENT_FILE=\"${FILENAME}.txt\"\nmv temp_article.txt \"$CONTENT_FILE\"\n\necho \"✓ Saved article: $CONTENT_FILE\"\n```\n\n#### PDF Document\n\n```bash\n# Download and extract PDF\necho \"? Downloading PDF...\"\n\n# 1. Download PDF\nPDF_FILENAME=$(basename \"$URL\")\ncurl -L -o \"$PDF_FILENAME\" \"$URL\"\n\n# 2. Extract text using pdftotext (if available)\nif command -v pdftotext &> \u002Fdev\u002Fnull; then\n    pdftotext \"$PDF_FILENAME\" temp_pdf.txt\n    CONTENT_FILE=\"${PDF_FILENAME%.pdf}.txt\"\n    mv temp_pdf.txt \"$CONTENT_FILE\"\n    echo \"✓ Extracted text from PDF: $CONTENT_FILE\"\n\n    # Optionally keep PDF\n    echo \"Keep original PDF? (y\u002Fn)\"\n    read -r KEEP_PDF\n    if [[ ! \"$KEEP_PDF\" =~ ^[Yy]$ ]]; then\n        rm \"$PDF_FILENAME\"\n    fi\nelse\n    # No pdftotext available\n    echo \"⚠️  pdftotext not found. PDF downloaded but not extracted.\"\n    echo \"   Install with: brew install poppler\"\n    CONTENT_FILE=\"$PDF_FILENAME\"\nfi\n```\n\n### Step 3: Create Ship-Learn-Next Action Plan\n\n**IMPORTANT**: Always create an action plan after extracting content.\n\n```bash\n# Read the extracted content\nCONTENT_FILE=\"[from previous step]\"\n\n# Invoke ship-learn-next skill logic:\n# 1. Read the content file\n# 2. Extract core actionable lessons\n# 3. Create 5-rep progression plan\n# 4. Save as: Ship-Learn-Next Plan - [Quest Title].md\n\n# See ship-learn-next\u002FSKILL.md for full details\n```\n\n**Key points for plan creation:**\n- Extract actionable lessons (not just summaries)\n- Define a specific 4-8 week quest\n- Create Rep 1 (shippable this week)\n- Design Reps 2-5 (progressive iterations)\n- Save plan to markdown file\n- Use format: `Ship-Learn-Next Plan - [Brief Quest Title].md`\n\n### Step 4: Present Results\n\nShow user:\n```\n✅ Tapestry Workflow Complete!\n\n? Content Extracted:\n   ✓ [Content type]: [Title]\n   ✓ Saved to: [filename.txt]\n   ✓ [X] words extracted\n\n? Action Plan Created:\n   ✓ Quest: [Quest title]\n   ✓ Saved to: Ship-Learn-Next Plan - [Title].md\n\n? Your Quest: [One-line summary]\n\n? Rep 1 (This Week): [Rep 1 goal]\n\nWhen will you ship Rep 1?\n```\n\n## Complete Tapestry Workflow Script\n\n```bash\n#!\u002Fbin\u002Fbash\n\n# Tapestry: Extract content + create action plan\n# Usage: tapestry \u003CURL>\n\nURL=\"$1\"\n\nif [ -z \"$URL\" ]; then\n    echo \"Usage: tapestry \u003CURL>\"\n    exit 1\nfi\n\necho \"? Tapestry Workflow Starting...\"\necho \"URL: $URL\"\necho \"\"\n\n# Step 1: Detect content type\nif [[ \"$URL\" =~ youtube\\.com\u002Fwatch || \"$URL\" =~ youtu\\.be\u002F || \"$URL\" =~ youtube\\.com\u002Fshorts ]]; then\n    CONTENT_TYPE=\"youtube\"\nelif [[ \"$URL\" =~ \\.pdf$ ]] || curl -sI \"$URL\" | grep -iq \"Content-Type: application\u002Fpdf\"; then\n    CONTENT_TYPE=\"pdf\"\nelse\n    CONTENT_TYPE=\"article\"\nfi\n\necho \"? Detected: $CONTENT_TYPE\"\necho \"\"\n\n# Step 2: Extract content\ncase $CONTENT_TYPE in\n    youtube)\n        echo \"? Extracting YouTube transcript...\"\n        # [YouTube extraction code from above]\n        ;;\n\n    article)\n        echo \"? Extracting article...\"\n        # [Article extraction code from above]\n        ;;\n\n    pdf)\n        echo \"? Downloading PDF...\"\n        # [PDF extraction code from above]\n        ;;\nesac\n\necho \"\"\n\n# Step 3: Create action plan\necho \"? Creating Ship-Learn-Next action plan...\"\n# [Plan creation using ship-learn-next skill]\n\necho \"\"\necho \"✅ Tapestry Workflow Complete!\"\necho \"\"\necho \"? Content: $CONTENT_FILE\"\necho \"? Plan: Ship-Learn-Next Plan - [title].md\"\necho \"\"\necho \"? Next: Review your action plan and ship Rep 1!\"\n```\n\n## Error Handling\n\n### Common Issues:\n\n**1. Unsupported URL type**\n- Try article extraction as fallback\n- If fails: \"Could not extract content from this URL type\"\n\n**2. No content extracted**\n- Check if URL is accessible\n- Try alternate extraction method\n- Inform user: \"Extraction failed. URL may require authentication.\"\n\n**3. Tools not installed**\n- Auto-install when possible (yt-dlp, reader, trafilatura)\n- Provide install instructions if auto-install fails\n- Use fallback methods when available\n\n**4. Empty or invalid content**\n- Verify file has content before creating plan\n- Don't create plan if extraction failed\n- Show preview to user before planning\n\n## Best Practices\n\n- ✅ Always show what was detected (\"? Detected: youtube\")\n- ✅ Display progress for each step\n- ✅ Save both content file AND plan file\n- ✅ Show preview of extracted content (first 10 lines)\n- ✅ Create plan automatically (don't ask)\n- ✅ Present clear summary at end\n- ✅ Ask commitment question: \"When will you ship Rep 1?\"\n\n## Usage Examples\n\n### Example 1: YouTube Video (using \"learn-this\")\n\n```\nUser: learn-this https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=dQw4w9WgXcQ\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: youtube\n? Extracting YouTube transcript...\n✓ Saved transcript: Never Gonna Give You Up.txt\n\n? Creating action plan...\n✓ Quest: Master Video Production\n✓ Saved plan: Ship-Learn-Next Plan - Master Video Production.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n### Example 2: Article (using \"weave\")\n\n```\nUser: weave https:\u002F\u002Fexample.com\u002Fhow-to-build-saas\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: article\n? Extracting article...\n✓ Using reader (Mozilla Readability)\n✓ Saved article: How to Build a SaaS.txt\n\n? Creating action plan...\n✓ Quest: Build a SaaS MVP\n✓ Saved plan: Ship-Learn-Next Plan - Build a SaaS MVP.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n### Example 3: PDF (using \"help me plan\")\n\n```\nUser: help me plan https:\u002F\u002Fexample.com\u002Fresearch-paper.pdf\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: pdf\n? Downloading PDF...\n✓ Downloaded: research-paper.pdf\n✓ Extracted text: research-paper.txt\n\n? Creating action plan...\n✓ Quest: Apply Research Findings\n✓ Saved plan: Ship-Learn-Next Plan - Apply Research Findings.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n## Dependencies\n\nThis skill orchestrates the other skills, so requires:\n\n**For YouTube:**\n- yt-dlp (auto-installed)\n- Python 3 (for deduplication)\n\n**For Articles:**\n- reader (npm) OR trafilatura (pip)\n- Falls back to basic curl if neither available\n\n**For PDFs:**\n- curl (built-in)\n- pdftotext (optional - from poppler package)\n  - Install: `brew install poppler` (macOS)\n  - Install: `apt install poppler-utils` (Linux)\n\n**For Planning:**\n- No additional requirements (uses built-in tools)\n\n## Philosophy\n\n**Tapestry weaves learning content into action.**\n\nThe unified workflow ensures you never just consume content - you always create an implementation plan. This transforms passive learning into active building.\n\nExtract → Plan → Ship → Learn → Next.\n\nThat's the Tapestry way.\n","# Tapestry: Unified Content Extraction + Action Planning\n\nThis is the **master skill** that orchestrates the entire Tapestry workflow:\n1. Detect content type from URL\n2. Extract content using appropriate skill\n3. Automatically create a Ship-Learn-Next action plan\n\n## When to Use This Skill\n\nActivate when the user:\n- Says \"learn-this [URL]\" or \"learn this [URL]\"\n- Says \"weave [URL]\"\n- Says \"help me plan [URL]\"\n- Says \"extract and plan [URL]\"\n- Says \"make this actionable [URL]\"\n- Says \"turn [URL] into a plan\"\n- Provides a URL and asks to \"learn and implement from this\"\n- Wants the full Tapestry workflow (extract → plan)\n\n**Keywords to watch for**: learn-this, learn this, weave, plan, actionable, extract and plan, make a plan, turn into action\n\n## How It Works\n\n### Complete Workflow:\n1. **Detect URL type** (YouTube, article, PDF)\n2. **Extract content** using appropriate skill:\n   - YouTube → youtube-transcript skill\n   - Article → article-extractor skill\n   - PDF → download and extract text\n3. **Create action plan** using ship-learn-next skill\n4. **Save both** content file and plan file\n5. **Present summary** to user\n\n## URL Detection Logic\n\n### YouTube Videos\n\n**Patterns to detect:**\n- `youtube.com\u002Fwatch?v=`\n- `youtu.be\u002F`\n- `youtube.com\u002Fshorts\u002F`\n- `m.youtube.com\u002Fwatch?v=`\n\n**Action:** Use youtube-transcript skill\n\n### Web Articles\u002FBlog Posts\n\n**Patterns to detect:**\n- `http:\u002F\u002F` or `https:\u002F\u002F`\n- NOT YouTube, NOT PDF\n- Common domains: medium.com, substack.com, dev.to, etc.\n- Any HTML page\n\n**Action:** Use article-extractor skill\n\n### PDF Documents\n\n**Patterns to detect:**\n- URL ends with `.pdf`\n- URL returns `Content-Type: application\u002Fpdf`\n\n**Action:** Download and extract text\n\n### Other Content\n\n**Fallback:**\n- Try article-extractor (works for most HTML)\n- If fails, inform user of unsupported type\n\n## Step-by-Step Workflow\n\n### Step 1: Detect Content Type\n\n```bash\nURL=\"$1\"\n\n# Check for YouTube\nif [[ \"$URL\" =~ youtube\\.com\u002Fwatch || \"$URL\" =~ youtu\\.be\u002F || \"$URL\" =~ youtube\\.com\u002Fshorts ]]; then\n    CONTENT_TYPE=\"youtube\"\n\n# Check for PDF\nelif [[ \"$URL\" =~ \\.pdf$ ]]; then\n    CONTENT_TYPE=\"pdf\"\n\n# Check if URL returns PDF\nelif curl -sI \"$URL\" | grep -i \"Content-Type: application\u002Fpdf\" > \u002Fdev\u002Fnull; then\n    CONTENT_TYPE=\"pdf\"\n\n# Default to article\nelse\n    CONTENT_TYPE=\"article\"\nfi\n\necho \"? Detected: $CONTENT_TYPE\"\n```\n\n### Step 2: Extract Content (by Type)\n\n#### YouTube Video\n\n```bash\n# Use youtube-transcript skill workflow\necho \"? Extracting YouTube transcript...\"\n\n# 1. Check for yt-dlp\nif ! command -v yt-dlp &> \u002Fdev\u002Fnull; then\n    echo \"Installing yt-dlp...\"\n    brew install yt-dlp\nfi\n\n# 2. Get video title\nVIDEO_TITLE=$(yt-dlp --print \"%(title)s\" \"$URL\" | tr '\u002F' '_' | tr ':' '-' | tr '?' '' | tr '\"' '')\n\n# 3. Download transcript\nyt-dlp --write-auto-sub --skip-download --sub-langs en --output \"temp_transcript\" \"$URL\"\n\n# 4. Convert to clean text (deduplicate)\npython3 -c \"\nimport sys, re\nseen = set()\nvtt_file = 'temp_transcript.en.vtt'\ntry:\n    with open(vtt_file, 'r') as f:\n        for line in f:\n            line = line.strip()\n            if line and not line.startswith('WEBVTT') and not line.startswith('Kind:') and not line.startswith('Language:') and '-->' not in line:\n                clean = re.sub('\u003C[^>]*>', '', line)\n                clean = clean.replace('&amp;', '&').replace('&gt;', '>').replace('&lt;', '\u003C')\n                if clean and clean not in seen:\n                    print(clean)\n                    seen.add(clean)\nexcept FileNotFoundError:\n    print('Error: Could not find transcript file', file=sys.stderr)\n    sys.exit(1)\n\" > \"${VIDEO_TITLE}.txt\"\n\n# 5. Cleanup\nrm -f temp_transcript.en.vtt\n\nCONTENT_FILE=\"${VIDEO_TITLE}.txt\"\necho \"✓ Saved transcript: $CONTENT_FILE\"\n```\n\n#### Article\u002FBlog Post\n\n```bash\n# Use article-extractor skill workflow\necho \"? Extracting article content...\"\n\n# 1. Check for extraction tools\nif command -v reader &> \u002Fdev\u002Fnull; then\n    TOOL=\"reader\"\nelif command -v trafilatura &> \u002Fdev\u002Fnull; then\n    TOOL=\"trafilatura\"\nelse\n    TOOL=\"fallback\"\nfi\n\necho \"Using: $TOOL\"\n\n# 2. Extract based on tool\ncase $TOOL in\n    reader)\n        reader \"$URL\" > temp_article.txt\n        ARTICLE_TITLE=$(head -n 1 temp_article.txt | sed 's\u002F^# \u002F\u002F')\n        ;;\n\n    trafilatura)\n        METADATA=$(trafilatura --URL \"$URL\" --json)\n        ARTICLE_TITLE=$(echo \"$METADATA\" | python3 -c \"import json, sys; print(json.load(sys.stdin).get('title', 'Article'))\")\n        trafilatura --URL \"$URL\" --output-format txt --no-comments > temp_article.txt\n        ;;\n\n    fallback)\n        ARTICLE_TITLE=$(curl -s \"$URL\" | grep -oP '\u003Ctitle>\\K[^\u003C]+' | head -n 1)\n        ARTICLE_TITLE=${ARTICLE_TITLE%% - *}\n        curl -s \"$URL\" | python3 -c \"\nfrom html.parser import HTMLParser\nimport sys\n\nclass ArticleExtractor(HTMLParser):\n    def __init__(self):\n        super().__init__()\n        self.content = []\n        self.skip_tags = {'script', 'style', 'nav', 'header', 'footer', 'aside', 'form'}\n        self.in_content = False\n\n    def handle_starttag(self, tag, attrs):\n        if tag not in self.skip_tags and tag in {'p', 'article', 'main'}:\n            self.in_content = True\n\n    def handle_data(self, data):\n        if self.in_content and data.strip():\n            self.content.append(data.strip())\n\n    def get_content(self):\n        return '\\n\\n'.join(self.content)\n\nparser = ArticleExtractor()\nparser.feed(sys.stdin.read())\nprint(parser.get_content())\n\" > temp_article.txt\n        ;;\nesac\n\n# 3. Clean filename\nFILENAME=$(echo \"$ARTICLE_TITLE\" | tr '\u002F' '-' | tr ':' '-' | tr '?' '' | tr '\"' '' | cut -c 1-80 | sed 's\u002F *$\u002F\u002F')\nCONTENT_FILE=\"${FILENAME}.txt\"\nmv temp_article.txt \"$CONTENT_FILE\"\n\necho \"✓ Saved article: $CONTENT_FILE\"\n```\n\n#### PDF Document\n\n```bash\n# Download and extract PDF\necho \"? Downloading PDF...\"\n\n# 1. Download PDF\nPDF_FILENAME=$(basename \"$URL\")\ncurl -L -o \"$PDF_FILENAME\" \"$URL\"\n\n# 2. Extract text using pdftotext (if available)\nif command -v pdftotext &> \u002Fdev\u002Fnull; then\n    pdftotext \"$PDF_FILENAME\" temp_pdf.txt\n    CONTENT_FILE=\"${PDF_FILENAME%.pdf}.txt\"\n    mv temp_pdf.txt \"$CONTENT_FILE\"\n    echo \"✓ Extracted text from PDF: $CONTENT_FILE\"\n\n    # Optionally keep PDF\n    echo \"Keep original PDF? (y\u002Fn)\"\n    read -r KEEP_PDF\n    if [[ ! \"$KEEP_PDF\" =~ ^[Yy]$ ]]; then\n        rm \"$PDF_FILENAME\"\n    fi\nelse\n    # No pdftotext available\n    echo \"⚠️  pdftotext not found. PDF downloaded but not extracted.\"\n    echo \"   Install with: brew install poppler\"\n    CONTENT_FILE=\"$PDF_FILENAME\"\nfi\n```\n\n### Step 3: Create Ship-Learn-Next Action Plan\n\n**IMPORTANT**: Always create an action plan after extracting content.\n\n```bash\n# Read the extracted content\nCONTENT_FILE=\"[from previous step]\"\n\n# Invoke ship-learn-next skill logic:\n# 1. Read the content file\n# 2. Extract core actionable lessons\n# 3. Create 5-rep progression plan\n# 4. Save as: Ship-Learn-Next Plan - [Quest Title].md\n\n# See ship-learn-next\u002FSKILL.md for full details\n```\n\n**Key points for plan creation:**\n- Extract actionable lessons (not just summaries)\n- Define a specific 4-8 week quest\n- Create Rep 1 (shippable this week)\n- Design Reps 2-5 (progressive iterations)\n- Save plan to markdown file\n- Use format: `Ship-Learn-Next Plan - [Brief Quest Title].md`\n\n### Step 4: Present Results\n\nShow user:\n```\n✅ Tapestry Workflow Complete!\n\n? Content Extracted:\n   ✓ [Content type]: [Title]\n   ✓ Saved to: [filename.txt]\n   ✓ [X] words extracted\n\n? Action Plan Created:\n   ✓ Quest: [Quest title]\n   ✓ Saved to: Ship-Learn-Next Plan - [Title].md\n\n? Your Quest: [One-line summary]\n\n? Rep 1 (This Week): [Rep 1 goal]\n\nWhen will you ship Rep 1?\n```\n\n## Complete Tapestry Workflow Script\n\n```bash\n#!\u002Fbin\u002Fbash\n\n# Tapestry: Extract content + create action plan\n# Usage: tapestry \u003CURL>\n\nURL=\"$1\"\n\nif [ -z \"$URL\" ]; then\n    echo \"Usage: tapestry \u003CURL>\"\n    exit 1\nfi\n\necho \"? Tapestry Workflow Starting...\"\necho \"URL: $URL\"\necho \"\"\n\n# Step 1: Detect content type\nif [[ \"$URL\" =~ youtube\\.com\u002Fwatch || \"$URL\" =~ youtu\\.be\u002F || \"$URL\" =~ youtube\\.com\u002Fshorts ]]; then\n    CONTENT_TYPE=\"youtube\"\nelif [[ \"$URL\" =~ \\.pdf$ ]] || curl -sI \"$URL\" | grep -iq \"Content-Type: application\u002Fpdf\"; then\n    CONTENT_TYPE=\"pdf\"\nelse\n    CONTENT_TYPE=\"article\"\nfi\n\necho \"? Detected: $CONTENT_TYPE\"\necho \"\"\n\n# Step 2: Extract content\ncase $CONTENT_TYPE in\n    youtube)\n        echo \"? Extracting YouTube transcript...\"\n        # [YouTube extraction code from above]\n        ;;\n\n    article)\n        echo \"? Extracting article...\"\n        # [Article extraction code from above]\n        ;;\n\n    pdf)\n        echo \"? Downloading PDF...\"\n        # [PDF extraction code from above]\n        ;;\nesac\n\necho \"\"\n\n# Step 3: Create action plan\necho \"? Creating Ship-Learn-Next action plan...\"\n# [Plan creation using ship-learn-next skill]\n\necho \"\"\necho \"✅ Tapestry Workflow Complete!\"\necho \"\"\necho \"? Content: $CONTENT_FILE\"\necho \"? Plan: Ship-Learn-Next Plan - [title].md\"\necho \"\"\necho \"? Next: Review your action plan and ship Rep 1!\"\n```\n\n## Error Handling\n\n### Common Issues:\n\n**1. Unsupported URL type**\n- Try article extraction as fallback\n- If fails: \"Could not extract content from this URL type\"\n\n**2. No content extracted**\n- Check if URL is accessible\n- Try alternate extraction method\n- Inform user: \"Extraction failed. URL may require authentication.\"\n\n**3. Tools not installed**\n- Auto-install when possible (yt-dlp, reader, trafilatura)\n- Provide install instructions if auto-install fails\n- Use fallback methods when available\n\n**4. Empty or invalid content**\n- Verify file has content before creating plan\n- Don't create plan if extraction failed\n- Show preview to user before planning\n\n## Best Practices\n\n- ✅ Always show what was detected (\"? Detected: youtube\")\n- ✅ Display progress for each step\n- ✅ Save both content file AND plan file\n- ✅ Show preview of extracted content (first 10 lines)\n- ✅ Create plan automatically (don't ask)\n- ✅ Present clear summary at end\n- ✅ Ask commitment question: \"When will you ship Rep 1?\"\n\n## Usage Examples\n\n### Example 1: YouTube Video (using \"learn-this\")\n\n```\nUser: learn-this https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=dQw4w9WgXcQ\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: youtube\n? Extracting YouTube transcript...\n✓ Saved transcript: Never Gonna Give You Up.txt\n\n? Creating action plan...\n✓ Quest: Master Video Production\n✓ Saved plan: Ship-Learn-Next Plan - Master Video Production.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n### Example 2: Article (using \"weave\")\n\n```\nUser: weave https:\u002F\u002Fexample.com\u002Fhow-to-build-saas\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: article\n? Extracting article...\n✓ Using reader (Mozilla Readability)\n✓ Saved article: How to Build a SaaS.txt\n\n? Creating action plan...\n✓ Quest: Build a SaaS MVP\n✓ Saved plan: Ship-Learn-Next Plan - Build a SaaS MVP.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n### Example 3: PDF (using \"help me plan\")\n\n```\nUser: help me plan https:\u002F\u002Fexample.com\u002Fresearch-paper.pdf\n\nClaude:\n? Tapestry Workflow Starting...\n? Detected: pdf\n? Downloading PDF...\n✓ Downloaded: research-paper.pdf\n✓ Extracted text: research-paper.txt\n\n? Creating action plan...\n✓ Quest: Apply Research Findings\n✓ Saved plan: Ship-Learn-Next Plan - Apply Research Findings.md\n\n✅ Complete! When will you ship Rep 1?\n```\n\n## Dependencies\n\nThis skill orchestrates the other skills, so requires:\n\n**For YouTube:**\n- yt-dlp (auto-installed)\n- Python 3 (for deduplication)\n\n**For Articles:**\n- reader (npm) OR trafilatura (pip)\n- Falls back to basic curl if neither available\n\n**For PDFs:**\n- curl (built-in)\n- pdftotext (optional - from poppler package)\n  - Install: `brew install poppler` (macOS)\n  - Install: `apt install poppler-utils` (Linux)\n\n**For Planning:**\n- No additional requirements (uses built-in tools)\n\n## Philosophy\n\n**Tapestry weaves learning content into action.**\n\nThe unified workflow ensures you never just consume content - you always create an implementation plan. This transforms passive learning into active building.\n\nExtract → Plan → Ship → Learn → Next.\n\nThat's the Tapestry way.\n",{"app":62,"name":5,"agents":63,"inputs":65,"attempts":66,"successes":66,"confidence":14,"description":7,"last_adjusted":67,"expected_state":68,"requires_approval":71},"tapestry",[64],"*",[],0,"2026-05-11T21:21:57+00:00",{"description":69,"verification_tool":70},"Imported skill — behavior matches source repo","none",true,"master","5f13b5d2b532c0ab6f847e3aa24d4bfe66f7d461","skills\u002Ftapestry\u002Flearn-this","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os","https:\u002F\u002Fgithub.com\u002FFlissel","https:\u002F\u002Fvibemind.space","Co-founder & CTO, VibeMind - a voice-first agentic OS for non-technical founders. Agents that do the work, not describe it.","2026-11-12 01:01:00",{"source":8,"skillName":5,"commands":81,"prompt":91,"zipAvailable":71},[82,85,88],{"tool":83,"command":84},"npx","npx skills add Flissel\u002Fvibemind-os --skill tapestry-learn-this",{"tool":86,"command":87},"bunx","bunx skills add Flissel\u002Fvibemind-os --skill tapestry-learn-this",{"tool":89,"command":90},"pnpm","pnpm dlx skills add Flissel\u002Fvibemind-os --skill tapestry-learn-this","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fskills\u002Ftapestry\u002Flearn-this\u002FSKILL.md",[],[94,102,109,136,144,158],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":57},"01M6JAA67M92TRE7GWDJDBTA9T","review","Review a change.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Frowboat\u002Frowboat\u002Fpackages\u002Fopenai-plugin-runtime\u002Ftest\u002Ffixtures\u002Fcomplete-plugin\u002Fskills\u002Freview\u002FSKILL.md",[],[96,101],"change",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":57},"01M6JAA3DZR55G8ZY493BE9NBB","triage","Triage a change.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Frowboat\u002Frowboat\u002Fpackages\u002Fopenai-plugin-runtime\u002Ftest\u002Ffixtures\u002Fcomplete-plugin\u002Fskills\u002Fgroup\u002Ftriage\u002FSKILL.md",[],[104,101],{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":57},"01M6JA9XPVHENK0FQN7HBK54NV","zentrale-werkzeuge","Werkzeuge der Zentrale – nutzen bei GitHub-Fragen (Projekte updaten, Repos, Issues, PRs, Commits, CI\u002FActions-Status, README), bei Fragen zum eigenen Gitea (Sicherung\u002FSpiegel, Repos, Issues, Commits), wenn neueste Docs\u002FDoku zu einer Bibliothek oder einem Dienst geholt werden sollen, wenn ein Dashboard aus meinen Daten gebaut werden soll und wenn ich sage 'auf meinem PC suchen' oder 'such auf dem Rechner nach …'.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Frowboat\u002Fdeploy\u002Fheadless\u002Fskills\u002Fzentrale-werkzeuge\u002FSKILL.md",[],[116,117,118,119,120,121,122,123,124,44,125,126,127,128,129,130,131,132,133,134,135],"zentrale werkzeuge","grep","file","README","list","fetch","todo","gitea","add","mkdir","prs","commits","ci","actions","issues","status","repos","dashboard","github","docs",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":142,"publishedAt":57},"01M6JA9SQPX187CVC148SQT1SP","wissen-suchen","Bedeutungssuche im Rowboat-Wissen – IMMER zuerst nutzen, wenn nach Kunden, Kontakten, Themen, Interessen, Notizen oder 'was wissen wir über …' gefragt wird, besonders wenn die genauen Wörter unklar sind.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Frowboat\u002Fdeploy\u002Fheadless\u002Fskills\u002Fwissen-suchen\u002FSKILL.md",[],[143],"wissen suchen",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":150,"publishedAt":57},"01M6JA9P6GNFPE21101SDZS3BT","reel-aus-material","Reel aus vorhandenen Laura-Videos: passende Stellen im Transkript finden; spricht dort eine Person, bleibt ihr Originalton (mit Untertiteln aus dem Transkript), sonst trägt ein eingesprochener Satz den Clip. Bei Aufträgen der Art 'material'.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Fmarketing\u002Fvideo_claw\u002Fskills\u002Freel-aus-material\u002FSKILL.md",[],[151,152,153,154,155,156,157],"material","reel","reel aus material","person","videos","Art","clip",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":164,"publishedAt":57},"01M6JA9KSATRT42ACWT66514ZP","reel-aus-bildern","Reel ohne Filmmaterial: Titelkarte, 3–5 Markenbilder mit wechselnder Bewegung, Schlusskarte mit Handlung; Farben und Logo der Firma. Bei Aufträgen der Art 'bilder'.","https:\u002F\u002Fgithub.com\u002FFlissel\u002Fvibemind-os\u002Fblob\u002Fmaster\u002Fspaces\u002Fmarketing\u002Fvideo_claw\u002Fskills\u002Freel-aus-bildern\u002FSKILL.md",[],[152,165,166,156],"reel aus bildern","logo"]