diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..16fb664b8 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,13 @@ +{ + "permissions": { + "allow": [ + "Bash(gh pr:*)", + "Bash(git:*)", + "Bash(npm:*)", + "Bash(jq:*)", + "Bash(date:*)", + "Bash(./scripts/create-docs-pr.sh:*)", + "mcp__barkme__notify" + ] + } +} diff --git a/.github/workflows/fetch-claude-docs.yml b/.github/workflows/fetch-claude-docs.yml index 545a9aa2f..4ecbfd9c4 100644 --- a/.github/workflows/fetch-claude-docs.yml +++ b/.github/workflows/fetch-claude-docs.yml @@ -2,7 +2,7 @@ name: Fetch Claude Code Docs on: schedule: - # Every 6 hours: 00:00, 06:00, 12:00, 18:00 UTC + # Four times daily: 01:00, 06:00, 11:00, 16:00 UTC (aligned with hn-digest) - cron: "0 1,6,11,16 * * *" workflow_dispatch: # Allow manual trigger @@ -55,7 +55,11 @@ jobs: git config --global user.email "claude-yolo@lroole.com" - name: Claude handles everything - uses: anthropics/claude-code-action@main + # Pinned: @main changed claude_args parsing in June 2026 and silently + # broke 'Bash(gh pr:*)' (split on the space into two invalid rules) + # -> 3 weeks of pushed branches with no PRs. Tool permissions now live + # in .claude/settings.json, which survives arg-parsing changes. + uses: anthropics/claude-code-action@v1.0.168 env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} with: @@ -64,7 +68,6 @@ jobs: allowed_bots: "claude-yolo[bot]" claude_args: | --model claude-sonnet-4-6 - --allowedTools Bash(gh pr:*),Bash(git:*),Bash(npm:*),Bash(jq:*),Bash(date:*),mcp__barkme__notify --mcp-config '{ "mcpServers": { "barkme": { @@ -100,11 +103,9 @@ jobs: - `content/en/api/` - API reference (1500+ docs) - `content/en/build-with-claude/` - Platform features - `content/mcp/` - MCP protocol spec - - `content/blog/engineering/` - Anthropic engineering posts - - `content/blog/research/` - Research papers - - `content/blog/news/` - Model releases, announcements + - `content/blog/` - FROZEN archive (anthropic.com is HTML-only; no longer fetched) - `content/github/` - GitHub repos (cookbooks, skills, plugins, courses) - - `content/support/` - Support articles + - `content/support/` - Support articles (sitemap + .md) ## YOUR WORKFLOW @@ -178,13 +179,39 @@ jobs: - Highlight the interesting bits ## BARKME PROTOCOL (nightshift notifications) - Always barkme when creating PR (one simple notification): + Bark AFTER the PR exists, never before: + - Only notify once gh pr create / create-docs-pr.sh returned a real PR URL - Title: "📦 Claude Code v{version}" - Body: "{key feature}" - - URL: Link to PR + - URL: the actual PR link (verify it is non-empty before barking) + + If push or PR creation fails: bark a failure alert instead + ("🚨 docs pipeline: {step} failed - needs human") and exit non-zero. + A notification without a PR behind it is worse than no notification. Keep it SHORT - day shift will do detailed analysis later. Remember: You're not a changelog generator. You're a smart filter that understands WHY changes matter to humans using Claude Code. [>be me >11:45pm Pacific docs checker >Anthropic devs are asleep >catching their fresh updates >day shift will handle the rest] + + # Tripwire: a pushed branch without a PR, or changes left uncommitted, + # means the agent step silently failed. Fail loudly instead of lying green. + # (June 2026 incident: 31 orphan branches, zero PRs, all runs green.) + - name: Verify outcome + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + BRANCH=$(git branch --show-current) + if [ -n "$(git status --porcelain)" ]; then + echo "::error::Workspace has uncommitted changes after agent step" + git status --short | head -20 + exit 1 + fi + if [ "$BRANCH" != "main" ] && [ -n "$BRANCH" ]; then + PRS=$(gh pr list --head "$BRANCH" --json number --jq 'length') + if [ "$PRS" = "0" ]; then + echo "::error::Branch $BRANCH pushed but no PR exists - PR creation silently failed" + exit 1 + fi + fi diff --git a/.gitignore b/.gitignore index 55cf2d919..ce3a51723 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,11 @@ dist/ # Claude Code .claude-trace/ -# Local development -.claude/ +# Local development (root only; keep settings.json tracked: CI reads tool +# permissions from it via settingSources=project. Note: content/github/** +# mirrors still ship .claude/ dirs we currently do not archive.) +/.claude/* +!/.claude/settings.json worktree/ WIP/ references/ diff --git a/CLAUDE.md b/CLAUDE.md index 33f96060f..9119f9ee9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,15 +5,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Repository Purpose Comprehensive archive of everything Anthropic publishes for building with -Claude. 2,900+ docs from 11 sources, auto-updated every 6 hours. +Claude. 2,900+ docs from 11 sources; active sources auto-updated four +times daily (blog archive frozen, see Fetcher). ## Fetcher `scripts/fetcher.py` -- single-file multi-source fetcher. Sources: code.claude.com, platform.claude.com, modelcontextprotocol.io, -anthropic.com (engineering/research/news), support.claude.com, -github.com/anthropics/* (10 repos). +support.claude.com (sitemap + .md), github.com/anthropics/* (10 repos). +anthropic.com blog (engineering/research/news) is a FROZEN archive as of +2026-07: the site is HTML-only and the jina.ai proxy path was removed. ```bash uv run scripts/fetcher.py # Fetch everything @@ -22,8 +24,7 @@ uv run scripts/fetcher.py --tree # Show sources uv run scripts/fetcher.py --discover # Probe for new sources ``` -Sections: `claude-code`, `api`, `platform`, `mcp`, `blog`, `engineering`, -`research`, `news`, `github`, `support`, `all` +Sections: `claude-code`, `api`, `platform`, `mcp`, `github`, `support`, `all` Source registry: `sources.json` Architecture: `REFACTOR.md` @@ -105,7 +106,7 @@ Use these paths to reference documentation when helping users: - `content/mcp/seps/` - Specification Enhancement Proposals - `content/mcp/community/` - Governance, working groups -#### Engineering & Research (from anthropic.com) +#### Engineering & Research (from anthropic.com) — FROZEN archive, not auto-updated - `content/blog/engineering/` - "Building Effective Agents", tool use, harness design - `content/blog/research/` - Research papers - `content/blog/news/` - Model releases, announcements diff --git a/scripts/fetcher.py b/scripts/fetcher.py index 85caf9e30..a45e772f0 100755 --- a/scripts/fetcher.py +++ b/scripts/fetcher.py @@ -6,8 +6,9 @@ - platform.claude.com -> API/platform docs (sitemap + .md suffix) - code.claude.com -> Claude Code + Agent SDK (llms.txt + .md suffix) - modelcontextprotocol.io -> MCP spec (sitemap + .md suffix) - - anthropic.com -> Engineering, research, news (jina.ai proxy) - - support.claude.com -> Help articles (jina.ai proxy) + - support.claude.com -> Help articles (sitemap + .md suffix) + - anthropic.com blog -> FROZEN 2026-07 (HTML-only, no .md variant; + the jina.ai proxy path was removed) - github.com/anthropics/* -> Repos (raw.githubusercontent.com) Usage: @@ -57,12 +58,6 @@ ("anthropics/anthropic-sdk-typescript","main", [".md"]), ] -NEWS_KEYWORDS = [ - "claude", "model", "api", "agent", "mcp", "sdk", "opus", "sonnet", - "haiku", "code", "bedrock", "vertex", "foundry", "tool", "safety", - "computer-use", -] - DISCOVER_DOMAINS = [ ("anthropic.com", "Main site"), ("platform.claude.com", "API platform docs"), @@ -89,7 +84,6 @@ def __init__( self.platform_sitemap_url = "https://platform.claude.com/sitemap.xml" self.claude_code_llms_url = "https://code.claude.com/docs/llms.txt" - self.anthropic_sitemap_url = "https://www.anthropic.com/sitemap.xml" self.mcp_sitemap_url = "https://modelcontextprotocol.io/sitemap.xml" self.support_sitemap_url = "https://support.claude.com/sitemap.xml" @@ -130,26 +124,9 @@ async def fetch_claude_code_urls(self, session: aiohttp.ClientSession) -> List[s urls.append(match[1:-4]) # strip parens and .md return urls - def filter_blog_urls(self, sitemap_xml: str) -> Dict[str, List[str]]: - result = {"engineering": [], "research": [], "news": [], "product": []} - for line in sitemap_xml.split("\n"): - if "" not in line: - continue - url = line.split("")[1].split("")[0] - if "/engineering/" in url and url != "https://www.anthropic.com/engineering": - result["engineering"].append(url) - elif "/product/" in url: - result["product"].append(url) - elif "/news/" in url and url != "https://www.anthropic.com/news": - slug = url.rsplit("/", 1)[-1].lower() - if any(kw in slug for kw in NEWS_KEYWORDS): - result["news"].append(url) - elif "/research/" in url and url != "https://www.anthropic.com/research": - if "/research/team/" not in url: - result["research"].append(url) - return result - def extract_support_urls(self, sitemap_xml: str) -> List[str]: + # Articles serve a .md variant directly (since ~2026-07), so plain + # download_doc applies; sitemap covers more articles than llms.txt. return [ url for url in self.extract_sitemap_urls(sitemap_xml) if "/en/articles/" in url @@ -201,53 +178,6 @@ async def download_doc(self, session, url, semaphore) -> Dict: self.stats["failed"] += 1 return {"url": url, "status": "failed", "error": str(e)} - async def download_via_jina(self, session, url, output_subdir, semaphore) -> Dict: - async with semaphore: - slug = url.split("anthropic.com/")[1] if "anthropic.com" in url else url.rsplit("/", 1)[-1] - output_path = self.output_dir / "blog" / f"{slug}.md" - if output_subdir: - output_path = self.output_dir / output_subdir / f"{slug}.md" - if self.incremental and output_path.exists(): - self.stats["skipped"] += 1 - return {"url": url, "status": "skipped"} - try: - content = await self.fetch_bytes(session, f"https://r.jina.ai/{url}") - output_path.parent.mkdir(parents=True, exist_ok=True) - async with aiofiles.open(output_path, "wb") as f: - await f.write(content) - self.stats["downloaded"] += 1 - return { - "url": url, "status": "success", - "path": str(output_path.relative_to(self.output_dir)), - "sha256": hashlib.sha256(content).hexdigest(), - "size": len(content), - } - except Exception as e: - self.stats["failed"] += 1 - return {"url": url, "status": "failed", "error": str(e)} - - async def download_support_article(self, session, url, semaphore) -> Dict: - async with semaphore: - output_path = self.get_output_path(url) - if self.incremental and output_path.exists(): - self.stats["skipped"] += 1 - return {"url": url, "status": "skipped"} - try: - content = await self.fetch_bytes(session, f"https://r.jina.ai/{url}") - output_path.parent.mkdir(parents=True, exist_ok=True) - async with aiofiles.open(output_path, "wb") as f: - await f.write(content) - self.stats["downloaded"] += 1 - return { - "url": url, "status": "success", - "path": str(output_path.relative_to(self.output_dir)), - "sha256": hashlib.sha256(content).hexdigest(), - "size": len(content), - } - except Exception as e: - self.stats["failed"] += 1 - return {"url": url, "status": "failed", "error": str(e)} - async def download_github_file(self, session, repo, branch, filepath, semaphore) -> Dict: async with semaphore: repo_short = repo.split("/")[1] @@ -334,7 +264,6 @@ async def fetch_all(self): tasks = [] semaphore = asyncio.Semaphore(self.jobs) - jina_semaphore = asyncio.Semaphore(min(self.jobs, 10)) counts = {} # -- Platform docs -- @@ -342,8 +271,13 @@ async def fetch_all(self): print("Source: platform.claude.com/sitemap.xml") xml = await self.fetch_text(session, self.platform_sitemap_url) urls = self.extract_sitemap_urls(xml, "/docs/en/") + # Terraform provider reference serves no .md variant (404s) + terraform = [u for u in urls if "/api/terraform/" in u] + urls = [u for u in urls if "/api/terraform/" not in u] counts["platform"] = len(urls) - print(f" {len(urls)} docs") + print(f" {len(urls)} docs" + + (f" ({len(terraform)} terraform pages skipped, no .md)" + if terraform else "")) for url in urls: tasks.append(self.download_doc(session, url, semaphore)) @@ -366,20 +300,9 @@ async def fetch_all(self): for url in urls: tasks.append(self.download_doc(session, url, semaphore)) - # -- Blog: engineering, research, news, product -- - if self.want("blog", "engineering", "research", "news"): - print("Source: anthropic.com/sitemap.xml") - xml = await self.fetch_text(session, self.anthropic_sitemap_url) - blog = self.filter_blog_urls(xml) - - for category, urls in blog.items(): - if not self.want("blog", category): - continue - counts[f"blog/{category}"] = len(urls) - print(f" {len(urls)} {category}") - for url in urls: - tasks.append(self.download_via_jina( - session, url, None, jina_semaphore)) + # -- Blog (anthropic.com): FROZEN 2026-07 -- + # HTML-only upstream (no llms.txt / .md variant); the jina.ai + # proxy path was removed. content/blog/ stays as a static archive. # -- Support articles -- if self.want("support"): @@ -389,8 +312,7 @@ async def fetch_all(self): counts["support"] = len(urls) print(f" {len(urls)} articles") for url in urls: - tasks.append(self.download_support_article( - session, url, jina_semaphore)) + tasks.append(self.download_doc(session, url, semaphore)) # -- GitHub repos -- if self.want("github"): @@ -413,9 +335,24 @@ async def fetch_all(self): if tasks: results = await tqdm_asyncio.gather(*tasks, desc="Fetching", unit="file") await self._save_metadata(results) + self._print_failures(results) self._print_summary() + def _print_failures(self, results: List[Dict]): + failed = [r for r in results if r.get("status") == "failed"] + if not failed: + return + by_host = defaultdict(int) + for r in failed: + by_host[r["url"].split("/")[2]] += 1 + print("\nFailed by host:") + for host, n in sorted(by_host.items(), key=lambda kv: -kv[1]): + print(f" {host}: {n}") + print("Sample errors:") + for r in failed[:3]: + print(f" {r['url']}: {str(r.get('error', ''))[:120]}") + async def _fetch_meta(self, session): print("Meta: NPM manifest + CHANGELOG") try: @@ -446,6 +383,10 @@ async def _save_metadata(self, results: List[Dict]): "section": self.section or "all", }, "items": [r for r in results if r.get("status") == "success"], + "failures": [ + {"url": r["url"], "error": str(r.get("error", ""))[:200]} + for r in results if r.get("status") == "failed" + ], "summary": { "total": self.stats["total"], "downloaded": self.stats["downloaded"], @@ -523,10 +464,8 @@ async def show_tree(self): cc_urls = await self.fetch_claude_code_urls(session) mcp_urls = self.extract_sitemap_urls( await self.fetch_text(session, self.mcp_sitemap_url)) - anthropic_xml = await self.fetch_text(session, self.anthropic_sitemap_url) - blog = self.filter_blog_urls(anthropic_xml) - support_xml = await self.fetch_text(session, self.support_sitemap_url) - support_urls = self.extract_support_urls(support_xml) + support_urls = self.extract_support_urls( + await self.fetch_text(session, self.support_sitemap_url)) def show_grouped(title, urls, strip_prefix): print(f"{title} ({len(urls)})") @@ -544,16 +483,12 @@ def show_grouped(title, urls, strip_prefix): show_grouped("platform.claude.com", platform_urls, "https://platform.claude.com/docs/en/") show_grouped("modelcontextprotocol.io", mcp_urls, "https://modelcontextprotocol.io/") - print(f"anthropic.com blog") - print("-" * 50) - for cat, urls in blog.items(): - print(f" {cat}: {len(urls)}") - print() print(f"support.claude.com: {len(support_urls)} articles") + print("anthropic.com blog: frozen archive (not fetched)") print(f"GitHub repos: {len(GITHUB_REPOS)} repos configured") print() - total = len(cc_urls) + len(platform_urls) + len(mcp_urls) + sum(len(v) for v in blog.values()) + len(support_urls) + total = len(cc_urls) + len(platform_urls) + len(mcp_urls) + len(support_urls) print(f"Total fetchable: {total}+ (excludes GitHub repos)") # -- Discovery --------------------------------------------------------- @@ -667,19 +602,18 @@ async def main(): claude-code Claude Code + Agent SDK docs (code.claude.com) api/platform API and platform docs (platform.claude.com) mcp MCP protocol spec (modelcontextprotocol.io) - blog All blog content (engineering + research + news + product) - engineering Engineering blog only - research Research posts only - news Filtered news (model releases, Claude updates) github All configured GitHub repos - support Support articles (support.claude.com) + support Support articles (support.claude.com, sitemap + .md) all Everything (default) +Note: content/blog/ (anthropic.com engineering/research/news) is a +frozen archive as of 2026-07 — the site is HTML-only and the jina.ai +proxy path was removed. + Examples: fetcher.py Fetch everything fetcher.py --section mcp MCP spec only fetcher.py --section github GitHub repos only - fetcher.py --section engineering Engineering blog only fetcher.py --tree Show all sources fetcher.py --discover Probe domains for new sources fetcher.py --incremental Skip existing files @@ -693,7 +627,6 @@ async def main(): "--section", "-s", choices=[ "claude-code", "api", "platform", "mcp", - "blog", "engineering", "research", "news", "github", "support", "all", ], ) diff --git a/sources.json b/sources.json index c4d6e144a..c7f16ebff 100644 --- a/sources.json +++ b/sources.json @@ -1,25 +1,58 @@ { "version": "2.0", - "updated": "2026-05-28", + "updated": "2026-07-08", "description": "Complete Anthropic content source registry. Discovered via robots.txt/sitemap/llms.txt probing across all known Anthropic domains, GitHub API enumeration, and package registry checks.", - "domains": { - "anthropic.com": {"robots": true, "sitemap": true, "llms_txt": false, "notes": "Main site: news, engineering, research"}, - "platform.claude.com": {"robots": true, "sitemap": true, "llms_txt": true, "llms_full": true, "notes": "API/platform docs (1541 en pages)"}, - "code.claude.com": {"robots": true, "sitemap": true, "llms_txt": true, "notes": "Claude Code + Agent SDK docs (141 en pages, 9 languages)"}, - "support.claude.com": {"robots": true, "sitemap": true, "llms_txt": false, "notes": "Help articles (343 en, Intercom-hosted)"}, - "modelcontextprotocol.io": {"robots": true, "sitemap": true, "llms_txt": true, "notes": "MCP spec + community (203 pages)"}, - "claude.ai": {"robots": true, "sitemap": "cf-blocked", "llms_txt": false, "notes": "Product app, Cloudflare-protected"}, - "claude.com": {"robots": true, "sitemap": "cf-blocked", "llms_txt": false, "notes": "Product landing, redirects to claude.ai"} + "anthropic.com": { + "robots": true, + "sitemap": true, + "llms_txt": false, + "notes": "Main site: news, engineering, research" + }, + "platform.claude.com": { + "robots": true, + "sitemap": true, + "llms_txt": true, + "llms_full": true, + "notes": "API/platform docs (1541 en pages)" + }, + "code.claude.com": { + "robots": true, + "sitemap": true, + "llms_txt": true, + "notes": "Claude Code + Agent SDK docs (141 en pages, 9 languages)" + }, + "support.claude.com": { + "robots": true, + "sitemap": true, + "llms_txt": true, + "notes": "Help articles (Intercom-hosted); llms.txt with direct .md links since ~2026-07" + }, + "modelcontextprotocol.io": { + "robots": true, + "sitemap": true, + "llms_txt": true, + "notes": "MCP spec + community (203 pages)" + }, + "claude.ai": { + "robots": true, + "sitemap": "cf-blocked", + "llms_txt": false, + "notes": "Product app, Cloudflare-protected" + }, + "claude.com": { + "robots": true, + "sitemap": "cf-blocked", + "llms_txt": false, + "notes": "Product landing, redirects to claude.ai" + } }, - "aliases": { "console.anthropic.com": "platform.claude.com", - "docs.anthropic.com": "platform.claude.com", + "docs.anthropic.com": "platform.claude.com", "support.anthropic.com": "support.claude.com", - "www.claude.com": "claude.com" + "www.claude.com": "claude.com" }, - "sources": [ { "name": "platform-docs", @@ -29,7 +62,10 @@ "output": "en/", "pages": 1541, "enabled": true, - "section": ["api", "platform"] + "section": [ + "api", + "platform" + ] }, { "name": "claude-code-docs", @@ -39,7 +75,9 @@ "output": "en/docs/claude-code/", "pages": 141, "enabled": true, - "section": ["claude-code"], + "section": [ + "claude-code" + ], "notes": "Sitemap has lastmod timestamps; llms.txt does not" }, { @@ -50,54 +88,94 @@ "output": "mcp/", "pages": 203, "enabled": true, - "section": ["mcp"], + "section": [ + "mcp" + ], "notes": "MCP spec, tutorials, SDK docs, governance, community charters" }, { "name": "support-articles", - "type": "sitemap-jina", - "sitemap": "https://support.claude.com/sitemap.xml", + "type": "sitemap-md", "filter": "/en/articles/", "output": "support/", "pages": 343, "enabled": true, - "section": ["support"], - "notes": "Intercom-hosted, needs jina.ai proxy. Multi-language." + "section": [ + "support" + ], + "notes": "Intercom-hosted; every article serves a .md variant directly (since ~2026-07), fetched sitemap + .md suffix. Previously jina.ai proxy. English-only filter.", + "sitemap": "https://support.claude.com/sitemap.xml" }, { "name": "engineering-blog", "type": "sitemap-jina", "sitemap": "https://www.anthropic.com/sitemap.xml", "filter": "/engineering/", - "exclude_exact": ["https://www.anthropic.com/engineering"], + "exclude_exact": [ + "https://www.anthropic.com/engineering" + ], "output": "blog/engineering/", "pages": 26, - "enabled": true, - "section": ["blog", "engineering"] + "enabled": false, + "section": [ + "blog", + "engineering" + ], + "notes": "FROZEN 2026-07-08: anthropic.com is HTML-only (no llms.txt/.md); jina.ai proxy dependency removed. content/blog/ kept as static archive." }, { "name": "research-posts", "type": "sitemap-jina", "sitemap": "https://www.anthropic.com/sitemap.xml", "filter": "/research/", - "exclude_exact": ["https://www.anthropic.com/research"], - "exclude_pattern": ["/research/team/"], + "exclude_exact": [ + "https://www.anthropic.com/research" + ], + "exclude_pattern": [ + "/research/team/" + ], "output": "blog/research/", "pages": 122, - "enabled": true, - "section": ["blog", "research"] + "enabled": false, + "section": [ + "blog", + "research" + ], + "notes": "FROZEN 2026-07-08: anthropic.com is HTML-only (no llms.txt/.md); jina.ai proxy dependency removed. content/blog/ kept as static archive." }, { "name": "news-posts", "type": "sitemap-jina-filtered", "sitemap": "https://www.anthropic.com/sitemap.xml", "filter": "/news/", - "exclude_exact": ["https://www.anthropic.com/news"], - "keywords": ["claude", "model", "api", "agent", "mcp", "sdk", "opus", "sonnet", "haiku", "code", "bedrock", "vertex", "foundry", "tool", "safety"], + "exclude_exact": [ + "https://www.anthropic.com/news" + ], + "keywords": [ + "claude", + "model", + "api", + "agent", + "mcp", + "sdk", + "opus", + "sonnet", + "haiku", + "code", + "bedrock", + "vertex", + "foundry", + "tool", + "safety" + ], "output": "blog/news/", "pages": "~100 (filtered from 217)", - "enabled": true, - "section": ["blog", "news"] + "enabled": false, + "section": [ + "blog", + "news" + ], + "notes": "FROZEN 2026-07-08: anthropic.com is HTML-only (no llms.txt/.md); jina.ai proxy dependency removed. content/blog/ kept as static archive." }, { "name": "product-pages", @@ -106,118 +184,165 @@ "filter": "/product/", "output": "blog/product/", "pages": 4, - "enabled": true, - "section": ["blog"] + "enabled": false, + "section": [ + "blog" + ], + "notes": "FROZEN 2026-07-08: anthropic.com is HTML-only (no llms.txt/.md); jina.ai proxy dependency removed. content/blog/ kept as static archive." }, { "name": "github-cookbooks", "type": "github-repo", "repo": "anthropics/claude-cookbooks", "branch": "main", - "extensions": [".md", ".ipynb"], + "extensions": [ + ".md", + ".ipynb" + ], "output": "github/cookbooks/", "pages": 164, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-skills", "type": "github-repo", "repo": "anthropics/skills", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/skills/", "pages": 90, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-plugins-official", "type": "github-repo", "repo": "anthropics/claude-plugins-official", "branch": "main", - "extensions": [".md", ".json"], + "extensions": [ + ".md", + ".json" + ], "output": "github/plugins-official/", "pages": 266, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-courses", "type": "github-repo", "repo": "anthropics/courses", "branch": "master", - "extensions": [".md", ".ipynb"], + "extensions": [ + ".md", + ".ipynb" + ], "output": "github/courses/", "pages": 80, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-quickstarts", "type": "github-repo", "repo": "anthropics/claude-quickstarts", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/quickstarts/", "pages": 17, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-code-action", "type": "github-repo", "repo": "anthropics/claude-code-action", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/code-action/", "pages": 32, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-workshops", "type": "github-repo", "repo": "anthropics/cwc-workshops", "branch": "main", - "extensions": [".md", ".ipynb"], + "extensions": [ + ".md", + ".ipynb" + ], "output": "github/workshops/", "pages": 36, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-long-running-agents", "type": "github-repo", "repo": "anthropics/cwc-long-running-agents", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/long-running-agents/", "pages": 4, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-sdk-python", "type": "github-repo", "repo": "anthropics/anthropic-sdk-python", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/sdk-python/", "pages": 10, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "github-sdk-typescript", "type": "github-repo", "repo": "anthropics/anthropic-sdk-typescript", "branch": "main", - "extensions": [".md"], + "extensions": [ + ".md" + ], "output": "github/sdk-typescript/", "pages": 20, "enabled": true, - "section": ["github"] + "section": [ + "github" + ] }, { "name": "npm-claude-code", @@ -225,7 +350,9 @@ "package": "@anthropic-ai/claude-code", "output": "claude-code-manifest.json", "enabled": true, - "section": ["meta"] + "section": [ + "meta" + ] }, { "name": "github-changelog", @@ -233,7 +360,9 @@ "url": "https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md", "output": "CHANGELOG.md", "enabled": true, - "section": ["meta"] + "section": [ + "meta" + ] } ] }