[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CCJP3EMYBZNAF0BMY89FSZ":3,"skill-same:01M6CCJP3EMYBZNAF0BMY89FSZ":92},{"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":26,"publishedAt":51,"linkOnly":52,"markdownContent":53,"markdownBody":54,"frontMatter":55,"refName":56,"commitSha":57,"skillDirectory":58,"forksCount":59,"repositoryHtmlUrl":60,"repositoryHomepageUrl":61,"ownerHtmlUrl":62,"ownerBlogUrl":61,"ownerDescription":6,"updatedAt":63,"install":64,"resources":77},"01M6CCJP3EMYBZNAF0BMY89FSZ","web-scraping",null,"Web scraping: scrape_page \u002F scrape_pages MCP tools for fetching pages as markdown, HTML, or text (fast HTTP, browser rendering, anti-bot stealth), plus the direct Scrapling Python API for selectors, sessions, and spiders","ginlix-ai\u002FLangAlpha","ginlix-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F255505137?v=4","01M6CCJK39A1C27GHF9AP4XWY0","Ginlix AI","01M6CCJK7GR7P1AWNRTPZYDJZY",2297,"MIT","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Fplugins\u002Falternative_data\u002Fskills\u002Fweb-scraping\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],"web","scraping","web scraping","markdown","for","rendering","as","pages","scrapling","html","page","direct","text","MCP","scrape","api","Tools","fast","mcp tools","browser","http","sessions","python","bot","2026-11-10 10:12:30",false,"---\nname: web-scraping\ndescription: \"Web scraping: scrape_page \u002F scrape_pages MCP tools for fetching pages as markdown, HTML, or text (fast HTTP, browser rendering, anti-bot stealth), plus the direct Scrapling Python API for selectors, sessions, and spiders\"\nlicense: MIT\n---\n\n# Web Scraping\n\n## Overview\n\nTwo ways to scrape in the sandbox:\n\n1. **MCP tools** (`scrape_page`, `scrape_pages`) — recommended for straight \"give me this page's content\". Synchronous, return dicts.\n2. **Direct Scrapling Python API** — for CSS\u002FXPath selectors, sessions, logins, and multi-page spiders. Async, returns Page objects with `.css()` \u002F `.xpath()`.\n\nQuick fetches can run inline via `ExecuteCode`. For spiders, multi-URL crawls, or anything you'll iterate on, write the scraper to `\u003Ctask_name>\u002Fscraper.py` and run it via `Bash` — edit-and-rerun beats resubmitting code.\n\n## MCP Tools\n\nImport from `tools.scrape`. **Synchronous** — no `await`.\n\n```python\nfrom tools.scrape import scrape_page, scrape_pages\n```\n\n### Signatures\n\n```python\nscrape_page(url: str, mode: str = \"fast\", extraction: str = \"markdown\",\n            timeout: float = 30.0, solve_cloudflare: bool = False) -> dict\n\nscrape_pages(urls: list[str], mode: str = \"fast\", extraction: str = \"markdown\",\n             timeout: float = 30.0, solve_cloudflare: bool = False) -> dict\n```\n\n### Parameters\n\n| Param | Default | Notes |\n|---|---|---|\n| `mode` | `\"fast\"` | `\"fast\"` plain HTTP · `\"browser\"` JS rendering · `\"stealth\"` bot-protected sites |\n| `extraction` | `\"markdown\"` | `\"markdown\"` (article text, cleaned) · `\"html\"` (raw) · `\"text\"` (plain) |\n| `timeout` | `30.0` | Per-fetch **seconds**, 1–60 — seconds in every mode, not ms |\n| `solve_cloudflare` | `False` | Only meaningful with `mode=\"stealth\"` |\n| `urls` | — | `scrape_pages` only; **max 10** per call |\n\nEscalate modes only as needed: start `fast`, go to `browser` when the page needs JavaScript, `stealth` when you're getting blocked, and add `solve_cloudflare=True` only if `stealth` still returns a challenge page.\n\n### Return shape\n\n`scrape_page` returns a flat dict:\n\n```python\n{\n    \"url\": \"https:\u002F\u002Fexample.com\",\n    \"status\": 200,\n    \"title\": \"Example Domain\",\n    \"content\": \"# Example Domain\\n\\nThis domain is for use in...\",  # str\n    \"extraction\": \"markdown\",\n    \"mode\": \"fast\",\n}\n```\n\n- **`content` is a plain string**, not a list — use it directly, never `content[0]` (that yields a single character).\n- `content` is truncated to **400,000 chars**.\n- No `.css()` \u002F `.xpath()` \u002F `.body` \u002F `.headers` \u002F `.cookies` — for selectors use the direct Python API below, or parse `extraction=\"html\"` with BeautifulSoup.\n\n`scrape_pages` wraps them:\n\n```python\n{\n    \"results\": [ ... ],  # one entry per input URL, in input order\n    \"count\": 3,\n}\n```\n\n### Errors\n\nErrors are returned, never raised. **Always check for `\"error\"` before reading `content`.**\n\n```python\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\")\nif \"error\" in res:\n    print(res[\"error\"], res[\"detail\"])\nelse:\n    print(res[\"content\"])\n```\n\nPer-URL errors — appear as `{\"error\", \"detail\", \"url\"}` entries inside `scrape_pages[\"results\"]`, or as the whole return of `scrape_page`:\n\n| Code | Meaning |\n|---|---|\n| `invalid_url` | Not an `http:\u002F\u002F` \u002F `https:\u002F\u002F` URL |\n| `fetch_failed` | Network, DNS, timeout, or browser failure |\n| `extract_failed` | Page fetched but the extractor failed on the markup; the entry still carries `status` |\n| `scrape_failed` | Unexpected internal failure for that one URL |\n\nWhole-call errors — the entire return is `{\"error\", \"detail\"}`, no `results`:\n\n| Code | Meaning |\n|---|---|\n| `invalid_mode` \u002F `invalid_extraction` \u002F `invalid_timeout` | Bad argument value |\n| `invalid_urls` | `scrape_pages` got an empty list or more than 10 URLs |\n\n**One bad URL never sinks a batch.** `scrape_pages` always returns one entry per input URL, in input order — failures come back as error entries alongside the successes.\n\n### Examples\n\n```python\nfrom tools.scrape import scrape_page, scrape_pages\n\n# Single page → markdown\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\")\nif \"error\" not in res:\n    print(res[\"title\"], res[\"status\"], len(res[\"content\"]))\n\n# JS-rendered page\nres = scrape_page(url=\"https:\u002F\u002Fspa-site.com\", mode=\"browser\", timeout=60)\n\n# Bot-protected page\nres = scrape_page(url=\"https:\u002F\u002Fprotected-site.com\", mode=\"stealth\", solve_cloudflare=True)\n\n# Batch — split successes from failures\nbatch = scrape_pages(urls=[...], mode=\"fast\")   # \u003C= 10 URLs\npages = [r for r in batch[\"results\"] if \"error\" not in r]\nfailed = [(r[\"url\"], r[\"error\"]) for r in batch[\"results\"] if \"error\" in r]\n\n# Raw HTML when you need to parse structure yourself\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\", extraction=\"html\")\nfrom bs4 import BeautifulSoup\nsoup = BeautifulSoup(res[\"content\"], \"html.parser\")\ntitles = [h1.get_text() for h1 in soup.find_all(\"h1\")]\n```\n\nBatches run concurrently — 8 at a time in `fast` mode, 2 at a time in `browser` \u002F `stealth` (browser sessions are memory-heavy). More than 10 URLs means more than one call.\n\n---\n\n## Direct Python API (Advanced)\n\nFor selectors, sessions, spiders, or when you need the full Page object. **Requires imports. Async.**\n\n### Fetcher (Fast HTTP — Tier 1)\n\n```python\nfrom scrapling.fetchers import AsyncFetcher\n\npage = await AsyncFetcher.get(\"https:\u002F\u002Fexample.com\", stealthy_headers=True)\nprint(page.status)       # 200\nprint(page.body)         # Raw bytes\nprint(page.headers)      # Response headers\n\n# CSS selectors (Scrapy-style pseudo-elements)\ntitles = page.css(\"h1::text\").getall()\nlinks = page.css(\"a::attr(href)\").getall()\n\n# XPath\nitems = page.xpath(\"\u002F\u002Fdiv[@class='item']\u002Ftext()\").getall()\n\n# BeautifulSoup-style\ndivs = page.find_all(\"div\", class_=\"content\")\n```\n\n### DynamicFetcher (Browser — Tier 2)\n\n```python\nfrom scrapling.fetchers import DynamicFetcher\n\npage = await DynamicFetcher.async_fetch(\n    \"https:\u002F\u002Fspa-website.com\",\n    headless=True,\n    network_idle=True,\n    disable_resources=True,\n    timeout=30000,          # milliseconds here, unlike the MCP tools\n    wait_selector=\".data-table\",\n)\nrows = page.css(\"table.data-table tr\")\nfor row in rows:\n    cells = row.css(\"td::text\").getall()\n```\n\n### StealthyFetcher (Anti-Bot — Tier 3)\n\n```python\nfrom scrapling.fetchers import StealthyFetcher\n\npage = await StealthyFetcher.async_fetch(\n    \"https:\u002F\u002Fprotected-site.com\",\n    headless=True,\n    solve_cloudflare=True,\n    network_idle=True,\n)\n```\n\n### Sessions (Persistent Connections)\n\n```python\nfrom scrapling.fetchers import FetcherSession\n\nwith FetcherSession(impersonate=\"chrome\") as session:\n    login_page = session.post(\"https:\u002F\u002Fsite.com\u002Flogin\", data={...})\n    dashboard = session.get(\"https:\u002F\u002Fsite.com\u002Fdashboard\")\n    data = dashboard.css(\".user-data::text\").getall()\n```\n\n### Spider (Multi-Page Crawl)\n\n```python\nfrom scrapling.spiders import Spider, Request, Response\n\nclass PriceScraper(Spider):\n    name = \"prices\"\n    start_urls = [\"https:\u002F\u002Fexample.com\u002Fproducts\"]\n    concurrent_requests = 5\n\n    async def parse(self, response: Response):\n        for product in response.css(\".product\"):\n            yield {\n                \"name\": product.css(\".name::text\").get(),\n                \"price\": product.css(\".price::text\").get(),\n            }\n        next_page = response.css(\"a.next::attr(href)\").get()\n        if next_page:\n            yield Request(next_page)\n\nspider = PriceScraper()\nresult = spider.start()\nresult.items.to_json(\"\u003Ctask_name>\u002Fdata\u002Fprices.json\")\n```\n\n## Converting HTML to Markdown\n\nOnly needed when you fetched HTML yourself — `scrape_page(extraction=\"markdown\")` already does this.\n\n```python\nimport html_to_markdown\n\nmarkdown = html_to_markdown.convert(\n    html_string, html_to_markdown.ConversionOptions(extract_metadata=False)\n).content\n\n# Article-only extraction (strips nav\u002Fads\u002Fboilerplate)\nimport trafilatura\n\narticle = trafilatura.extract(html_string, output_format=\"markdown\", favor_recall=True)\n```\n\n## When to Use Which\n\n| Need | Use |\n|------|-----|\n| Quick page content as markdown | `scrape_page()` |\n| Several known URLs at once | `scrape_pages()` (≤10 per call) |\n| Extract specific elements (CSS\u002FXPath) | Direct Python API with selectors |\n| Login + scrape authenticated pages | Direct Python API with sessions |\n| Crawl many pages with pagination | Direct Python API with Spider |\n| Bypass Cloudflare | `scrape_page(mode=\"stealth\", solve_cloudflare=True)` or direct `StealthyFetcher` |\n| Save results to file | Direct Python API (spider `.to_json()`) |\n","# Web Scraping\n\n## Overview\n\nTwo ways to scrape in the sandbox:\n\n1. **MCP tools** (`scrape_page`, `scrape_pages`) — recommended for straight \"give me this page's content\". Synchronous, return dicts.\n2. **Direct Scrapling Python API** — for CSS\u002FXPath selectors, sessions, logins, and multi-page spiders. Async, returns Page objects with `.css()` \u002F `.xpath()`.\n\nQuick fetches can run inline via `ExecuteCode`. For spiders, multi-URL crawls, or anything you'll iterate on, write the scraper to `\u003Ctask_name>\u002Fscraper.py` and run it via `Bash` — edit-and-rerun beats resubmitting code.\n\n## MCP Tools\n\nImport from `tools.scrape`. **Synchronous** — no `await`.\n\n```python\nfrom tools.scrape import scrape_page, scrape_pages\n```\n\n### Signatures\n\n```python\nscrape_page(url: str, mode: str = \"fast\", extraction: str = \"markdown\",\n            timeout: float = 30.0, solve_cloudflare: bool = False) -> dict\n\nscrape_pages(urls: list[str], mode: str = \"fast\", extraction: str = \"markdown\",\n             timeout: float = 30.0, solve_cloudflare: bool = False) -> dict\n```\n\n### Parameters\n\n| Param | Default | Notes |\n|---|---|---|\n| `mode` | `\"fast\"` | `\"fast\"` plain HTTP · `\"browser\"` JS rendering · `\"stealth\"` bot-protected sites |\n| `extraction` | `\"markdown\"` | `\"markdown\"` (article text, cleaned) · `\"html\"` (raw) · `\"text\"` (plain) |\n| `timeout` | `30.0` | Per-fetch **seconds**, 1–60 — seconds in every mode, not ms |\n| `solve_cloudflare` | `False` | Only meaningful with `mode=\"stealth\"` |\n| `urls` | — | `scrape_pages` only; **max 10** per call |\n\nEscalate modes only as needed: start `fast`, go to `browser` when the page needs JavaScript, `stealth` when you're getting blocked, and add `solve_cloudflare=True` only if `stealth` still returns a challenge page.\n\n### Return shape\n\n`scrape_page` returns a flat dict:\n\n```python\n{\n    \"url\": \"https:\u002F\u002Fexample.com\",\n    \"status\": 200,\n    \"title\": \"Example Domain\",\n    \"content\": \"# Example Domain\\n\\nThis domain is for use in...\",  # str\n    \"extraction\": \"markdown\",\n    \"mode\": \"fast\",\n}\n```\n\n- **`content` is a plain string**, not a list — use it directly, never `content[0]` (that yields a single character).\n- `content` is truncated to **400,000 chars**.\n- No `.css()` \u002F `.xpath()` \u002F `.body` \u002F `.headers` \u002F `.cookies` — for selectors use the direct Python API below, or parse `extraction=\"html\"` with BeautifulSoup.\n\n`scrape_pages` wraps them:\n\n```python\n{\n    \"results\": [ ... ],  # one entry per input URL, in input order\n    \"count\": 3,\n}\n```\n\n### Errors\n\nErrors are returned, never raised. **Always check for `\"error\"` before reading `content`.**\n\n```python\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\")\nif \"error\" in res:\n    print(res[\"error\"], res[\"detail\"])\nelse:\n    print(res[\"content\"])\n```\n\nPer-URL errors — appear as `{\"error\", \"detail\", \"url\"}` entries inside `scrape_pages[\"results\"]`, or as the whole return of `scrape_page`:\n\n| Code | Meaning |\n|---|---|\n| `invalid_url` | Not an `http:\u002F\u002F` \u002F `https:\u002F\u002F` URL |\n| `fetch_failed` | Network, DNS, timeout, or browser failure |\n| `extract_failed` | Page fetched but the extractor failed on the markup; the entry still carries `status` |\n| `scrape_failed` | Unexpected internal failure for that one URL |\n\nWhole-call errors — the entire return is `{\"error\", \"detail\"}`, no `results`:\n\n| Code | Meaning |\n|---|---|\n| `invalid_mode` \u002F `invalid_extraction` \u002F `invalid_timeout` | Bad argument value |\n| `invalid_urls` | `scrape_pages` got an empty list or more than 10 URLs |\n\n**One bad URL never sinks a batch.** `scrape_pages` always returns one entry per input URL, in input order — failures come back as error entries alongside the successes.\n\n### Examples\n\n```python\nfrom tools.scrape import scrape_page, scrape_pages\n\n# Single page → markdown\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\")\nif \"error\" not in res:\n    print(res[\"title\"], res[\"status\"], len(res[\"content\"]))\n\n# JS-rendered page\nres = scrape_page(url=\"https:\u002F\u002Fspa-site.com\", mode=\"browser\", timeout=60)\n\n# Bot-protected page\nres = scrape_page(url=\"https:\u002F\u002Fprotected-site.com\", mode=\"stealth\", solve_cloudflare=True)\n\n# Batch — split successes from failures\nbatch = scrape_pages(urls=[...], mode=\"fast\")   # \u003C= 10 URLs\npages = [r for r in batch[\"results\"] if \"error\" not in r]\nfailed = [(r[\"url\"], r[\"error\"]) for r in batch[\"results\"] if \"error\" in r]\n\n# Raw HTML when you need to parse structure yourself\nres = scrape_page(url=\"https:\u002F\u002Fexample.com\", extraction=\"html\")\nfrom bs4 import BeautifulSoup\nsoup = BeautifulSoup(res[\"content\"], \"html.parser\")\ntitles = [h1.get_text() for h1 in soup.find_all(\"h1\")]\n```\n\nBatches run concurrently — 8 at a time in `fast` mode, 2 at a time in `browser` \u002F `stealth` (browser sessions are memory-heavy). More than 10 URLs means more than one call.\n\n---\n\n## Direct Python API (Advanced)\n\nFor selectors, sessions, spiders, or when you need the full Page object. **Requires imports. Async.**\n\n### Fetcher (Fast HTTP — Tier 1)\n\n```python\nfrom scrapling.fetchers import AsyncFetcher\n\npage = await AsyncFetcher.get(\"https:\u002F\u002Fexample.com\", stealthy_headers=True)\nprint(page.status)       # 200\nprint(page.body)         # Raw bytes\nprint(page.headers)      # Response headers\n\n# CSS selectors (Scrapy-style pseudo-elements)\ntitles = page.css(\"h1::text\").getall()\nlinks = page.css(\"a::attr(href)\").getall()\n\n# XPath\nitems = page.xpath(\"\u002F\u002Fdiv[@class='item']\u002Ftext()\").getall()\n\n# BeautifulSoup-style\ndivs = page.find_all(\"div\", class_=\"content\")\n```\n\n### DynamicFetcher (Browser — Tier 2)\n\n```python\nfrom scrapling.fetchers import DynamicFetcher\n\npage = await DynamicFetcher.async_fetch(\n    \"https:\u002F\u002Fspa-website.com\",\n    headless=True,\n    network_idle=True,\n    disable_resources=True,\n    timeout=30000,          # milliseconds here, unlike the MCP tools\n    wait_selector=\".data-table\",\n)\nrows = page.css(\"table.data-table tr\")\nfor row in rows:\n    cells = row.css(\"td::text\").getall()\n```\n\n### StealthyFetcher (Anti-Bot — Tier 3)\n\n```python\nfrom scrapling.fetchers import StealthyFetcher\n\npage = await StealthyFetcher.async_fetch(\n    \"https:\u002F\u002Fprotected-site.com\",\n    headless=True,\n    solve_cloudflare=True,\n    network_idle=True,\n)\n```\n\n### Sessions (Persistent Connections)\n\n```python\nfrom scrapling.fetchers import FetcherSession\n\nwith FetcherSession(impersonate=\"chrome\") as session:\n    login_page = session.post(\"https:\u002F\u002Fsite.com\u002Flogin\", data={...})\n    dashboard = session.get(\"https:\u002F\u002Fsite.com\u002Fdashboard\")\n    data = dashboard.css(\".user-data::text\").getall()\n```\n\n### Spider (Multi-Page Crawl)\n\n```python\nfrom scrapling.spiders import Spider, Request, Response\n\nclass PriceScraper(Spider):\n    name = \"prices\"\n    start_urls = [\"https:\u002F\u002Fexample.com\u002Fproducts\"]\n    concurrent_requests = 5\n\n    async def parse(self, response: Response):\n        for product in response.css(\".product\"):\n            yield {\n                \"name\": product.css(\".name::text\").get(),\n                \"price\": product.css(\".price::text\").get(),\n            }\n        next_page = response.css(\"a.next::attr(href)\").get()\n        if next_page:\n            yield Request(next_page)\n\nspider = PriceScraper()\nresult = spider.start()\nresult.items.to_json(\"\u003Ctask_name>\u002Fdata\u002Fprices.json\")\n```\n\n## Converting HTML to Markdown\n\nOnly needed when you fetched HTML yourself — `scrape_page(extraction=\"markdown\")` already does this.\n\n```python\nimport html_to_markdown\n\nmarkdown = html_to_markdown.convert(\n    html_string, html_to_markdown.ConversionOptions(extract_metadata=False)\n).content\n\n# Article-only extraction (strips nav\u002Fads\u002Fboilerplate)\nimport trafilatura\n\narticle = trafilatura.extract(html_string, output_format=\"markdown\", favor_recall=True)\n```\n\n## When to Use Which\n\n| Need | Use |\n|------|-----|\n| Quick page content as markdown | `scrape_page()` |\n| Several known URLs at once | `scrape_pages()` (≤10 per call) |\n| Extract specific elements (CSS\u002FXPath) | Direct Python API with selectors |\n| Login + scrape authenticated pages | Direct Python API with sessions |\n| Crawl many pages with pagination | Direct Python API with Spider |\n| Bypass Cloudflare | `scrape_page(mode=\"stealth\", solve_cloudflare=True)` or direct `StealthyFetcher` |\n| Save results to file | Direct Python API (spider `.to_json()`) |\n",{"name":5,"license":15,"description":7},"main","f5d250aa1bedbf685a23b5220f50f9192f76289a","plugins\u002Falternative_data\u002Fskills\u002Fweb-scraping",387,"https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha","https:\u002F\u002Flangalpha.ai","https:\u002F\u002Fgithub.com\u002Fginlix-ai","2026-11-14 01:05:14",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add ginlix-ai\u002FLangAlpha --skill web-scraping",{"tool":70,"command":71},"bunx","bunx skills add ginlix-ai\u002FLangAlpha --skill web-scraping",{"tool":73,"command":74},"pnpm","pnpm dlx skills add ginlix-ai\u002FLangAlpha --skill web-scraping","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Fplugins\u002Falternative_data\u002Fskills\u002Fweb-scraping\u002FSKILL.md",true,[78,84,88],{"path":79,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":82,"sourceHtmlUrl":83},"references\u002Fapi-reference.md","REFERENCE","参考文档",8923,"https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Fplugins\u002Falternative_data\u002Fskills\u002Fweb-scraping\u002Freferences\u002Fapi-reference.md",{"path":85,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":86,"sourceHtmlUrl":87},"SOURCE.md",187,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fsaucaiii\u002FSOURCE.md",{"path":89,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":90,"sourceHtmlUrl":91},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fsaucaiii\u002FTRUST.auto.yaml",[93,107,116,124,134,147],{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":101,"publishedAt":51},"01M6CCP2R7FYQ1DHW1D59NR7CR","fx-notes","Fixture skill fx-notes","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fplugins\u002Fvalid-full\u002Fskills\u002Ffx-notes\u002FSKILL.md",[100],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[102,103,104,105,106],"fx","notes","fx notes","fixture skill","fixture",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":114,"publishedAt":51},"01M6CCP16MF4A5J06320JAV03Z","good","Fixture skill good","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fplugins\u002Fskill-defects\u002Fskills\u002Fgood\u002FSKILL.md",[113],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[109,115,105,106],"skill good",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":51},"01M6CCNZAYQT0RT73XFTFPTJC0","survivor","Fixture skill survivor","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fplugins\u002Fmcp-doc-invalid\u002Fskills\u002Fsurvivor\u002FSKILL.md",[122],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[118,106,105],{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":51},"01M6CCNX73ZH4DY2W1K0CH5BNP","alpha-notes","Notes on alpha things.","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fplugins\u002Fmarketplace-mixed\u002Fplugins\u002Falpha\u002Fskills\u002Falpha-notes\u002FSKILL.md",[],[103,131,132,133],"alpha","alpha notes","things",{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":51},"01M6CCNVK5ZV4CZ2T0M6SH8QB9","cli-tips","Tips for the command line.","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fplugins\u002Fdialect-cursor\u002Fskills\u002Fcli-tips\u002FSKILL.md",[],[141,142,143,31,144,145,146],"tips","cli tips","cli","command","line","command line",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":97,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":154,"publishedAt":51},"01M6CCNSA684PA7S3NSET4022S","run-workflow","Orchestrate parallel subagent pipelines from a JavaScript workflow script. Fan out work across many items (tickers, filings, findings) then synthesize, or run a saved workflow by name. Unlocks the RunWorkflow tool.","https:\u002F\u002Fgithub.com\u002Fginlix-ai\u002FLangAlpha\u002Fblob\u002Fmain\u002Fplugins\u002Flangalpha_service\u002Fskills\u002Frun-workflow\u002FSKILL.md",[153],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172],"workflow","run workflow","run","across","javascript","orchestrate","subagent","tool","parallel","work","pipelines","synthesize","name","filings","script","saved","fan out","by name"]