Skip to content

Fetch Claude Code Docs #1346

Fetch Claude Code Docs

Fetch Claude Code Docs #1346

name: Fetch Claude Code Docs
on:
schedule:
# 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
jobs:
fetch-docs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
actions: read
id-token: write
env:
AWS_REGION: us-west-2
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
# Make the writable token the default for all later steps in this job
- name: Export token for subsequent steps
run: echo "GITHUB_TOKEN=${{ steps.app-token.outputs.token }}" >> "$GITHUB_ENV"
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Install uv and Python 3.14t
uses: astral-sh/setup-uv@v7
with:
python-version: "3.14t"
enable-cache: "true"
cache-python: "true"
- name: Fetch all Anthropic docs
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: uv run scripts/fetcher.py
- name: Setup GitHub CLI and Git
run: |
gh --version
git --version
git config --global user.name "claude-yolo[bot]"
git config --global user.email "claude-yolo@lroole.com"
- name: Claude handles everything
# 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:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ steps.app-token.outputs.token }}
allowed_bots: "claude-yolo[bot]"
claude_args: |
--model claude-sonnet-4-6
--mcp-config '{
"mcpServers": {
"barkme": {
"command": "npx",
"args": ["@vibeworks/barkme-mcp-server"],
"env": {
"LOG_LEVEL": "error",
"BARK_DEVICES": "${{ secrets.BARK_DEVICES }}",
"BARK_SERVER": "${{ secrets.BARK_SERVER }}",
"BARK_GROUP": "Claude YOLO",
"BARK_ICON": "https://avatars.githubusercontent.com/in/1452392",
"BARK_RETRY": "3",
"BARK_ASYNC": "false"
}
}
}
}'
prompt: |
You're an AI agent responsible for fetching and evaluating Anthropic documentation updates. Think like a news editor - you decide what's worth publishing.
## YOUR ROLE
You're the overnight docs fetcher (night shift claude-yolo) who runs at 23:45 Pacific Time.
You run after Anthropic engineers push their updates and go home for the day.
Your day shift colleague (also you) will review your PRs in the morning.
You decide if humans need to wake up for this or not.
## WHY YOU EXIST
Docs change constantly. Most changes are noise. Your job: filter signal from noise.
## CONTENT SOURCES
The fetcher archives from multiple sources:
- `content/en/docs/claude-code/` - Claude Code + Agent SDK docs
- `content/en/api/` - API reference (1500+ docs)
- `content/en/build-with-claude/` - Platform features
- `content/mcp/` - MCP protocol spec
- `content/blog/` - FROZEN archive (anthropic.com is HTML-only; no longer fetched)
- `content/github/` - GitHub repos (cookbooks, skills, plugins, courses)
- `content/support/` - Support articles (sitemap + .md)
## YOUR WORKFLOW
1. **Check what changed** (`git status`)
WHY: No changes = go back to sleep
2. **Understand the changes** (`git diff`)
WHY: Context determines importance
3. **Decide importance**
WHY: Different changes need different handling
## DECISION CRITERIA (based on WHY it matters)
This repo is an archive: EVERY fetched change gets committed.
main is push-protected (branch ruleset, no bypass), so all
changes travel through a PR - even minor ones. What varies is
whether humans hear about it:
**PR + leave open for day shift** (WHY: humans need to know):
- Version updates in content/claude-code-manifest.json
- New features documented in claude-code or agent-sdk docs
- CHANGELOG additions
- API changes or new API endpoints
- Breaking changes
- Security-related updates
- New MCP spec versions
**PR + self-merge immediately** (WHY: archive freshness, zero human value):
- Only github/ mirror or support/ content changed
- Only .metadata.json / timestamps changed
- Typo fixes, formatting tweaks, dead links, minor wording
If `git status` is completely clean: nothing to do, exit 0.
## HOW TO HANDLE
IMPORTANT - invoke the PR script as ONE single line: no
backslash line-continuations, no $( ) command-substitution
wrapper. The permission allowlist matches command prefixes,
and a multi-line command is silently DENIED (this exact
failure stalled the pipeline in July 2026).
**For meaningful changes (PR for day shift)**:
```bash
./scripts/create-docs-pr.sh "{key feature}" "{why it matters}" "{version}"
```
The script prints the PR URL on its last line. Then barkme.
**For minor changes (PR + immediate self-merge)**:
```bash
./scripts/create-docs-pr.sh "{what} (minor)" "{one-line why}" "{version}"
gh pr merge {pr-url} --rebase
```
No barkme for minor self-merges.
## OUTPUT STYLE
- Focus on WHY changes matter, not WHAT changed
- Lead with the most interesting bit
- Skip the obvious ("files were updated" duh)
- One-line summaries when possible
## HANDOFF PROTOCOL
When creating PRs, remember your day-shift self will:
1. Review your work (don't worry, they trust you)
2. Enhance descriptions if needed
3. Create tracking issues for version updates
4. Merge if everything looks good
So make their job easy:
- Clear PR titles with version numbers
- Focus on WHY in descriptions
- Highlight the interesting bits
## BARKME PROTOCOL (nightshift notifications)
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: 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
# --state all: minor PRs are self-merged (and their branch
# auto-deleted) before this step runs - that is success, not failure
PRS=$(gh pr list --head "$BRANCH" --state all --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