Skip to content

Smart Docs Monitor #326

Smart Docs Monitor

Smart Docs Monitor #326

name: Smart Docs Monitor
on:
schedule:
- cron: '0 0 * * *' # Run every 24 hours at midnight UTC
workflow_dispatch:
inputs:
hours_back:
description: 'Hours to look back for merged PRs'
required: false
default: '24'
permissions:
contents: read
issues: write
id-token: write
jobs:
monitor:
runs-on: ubuntu-latest
steps:
- name: Checkout docs repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch merged PRs and create review batch
id: batch
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const repos = fs.readFileSync('repos-to-monitor.txt', 'utf8')
.split('\n')
.filter(line => line.trim() && !line.startsWith('#'));
const hoursBack = parseInt('${{ github.event.inputs.hours_back || '24' }}');
const since = new Date(Date.now() - hoursBack * 60 * 60 * 1000).toISOString();
let batchSummary = '# Merged PRs to Review\n\n';
let prCount = 0;
for (const repo of repos) {
const [owner, repoName] = repo.split('/');
try {
const { data: pulls } = await github.rest.pulls.list({
owner,
repo: repoName,
state: 'closed',
sort: 'updated',
direction: 'desc',
per_page: 30
});
const merged = pulls.filter(pr =>
pr.merged_at &&
new Date(pr.merged_at) > new Date(since)
);
if (merged.length > 0) {
batchSummary += `## ${repo}\n\n`;
for (const pr of merged) {
batchSummary += `### PR #${pr.number}: ${pr.title}\n`;
batchSummary += `- **URL:** ${pr.html_url}\n`;
batchSummary += `- **Merged:** ${pr.merged_at}\n`;
batchSummary += `- **Diff:** ${pr.diff_url}\n`;
if (pr.body) {
batchSummary += `- **Description:** ${pr.body.substring(0, 200)}...\n`;
}
batchSummary += '\n';
prCount++;
}
batchSummary += '\n';
}
} catch (error) {
console.log(`Error with ${repo}:`, error.message);
}
}
fs.writeFileSync('pr-batch.md', batchSummary);
console.log(`Found ${prCount} merged PRs`);
core.setOutput('pr_count', prCount);
return prCount;
- name: Analyze PRs with Claude
if: steps.batch.outputs.pr_count > 0
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
Review the merged PRs listed in `pr-batch.md` and determine which ones require documentation updates, new documentation, or removal/deprecation of existing docs.
**Your Process:**
1. **Read pr-batch.md and CLAUDE.md**
- Follow CLAUDE.md's Review Process and "What Requires Documentation" guidelines
- See all merged PRs in pr-batch.md
2. **For each PR - Fetch and analyze the full diff:**
- Use the Diff URL from pr-batch.md to fetch the complete PR diff (use curl or gh api)
- Do NOT rely only on PR titles or summaries - read the actual code changes
- Extract user-facing changes: new/changed/removed public APIs, endpoints, CLIs, flags, config keys, setup instructions, breaking changes, renames
3. **Classify documentation impact** (may be multiple categories per PR):
a) **UPDATE** existing docs (content exists but is now incorrect/outdated)
b) **CREATE** new documentation (feature/API is not documented anywhere)
c) **REMOVE or DEPRECATE** documentation (feature/API was removed or deprecated)
4. **Thoroughly search our existing documentation:**
- Use Grep tool to search /concepts, /guides-and-tutorials, /reference, README.md for ALL relevant terms from the diff:
* Function/method names (e.g., "map-insert", "map_insert")
* API endpoints (e.g., "/v2/accounts", "accounts endpoint")
* CLI commands and flags (e.g., "stacks-node", "--config")
* Configuration keys (e.g., "peer_host", "miner.seed")
* Type/class names
- Try both case-sensitive and case-insensitive searches
- Try word variations (snake_case, kebab-case, camelCase)
**Search results determine the impact:**
- **If NOT found:** Propose new doc with specific path + outline/content
- **If found:** Identify exact files/sections that are incorrect and need updating
- **If PR removes/deprecates something:** List ALL references across docs and propose removal/deprecation action
5. **Look for detection keywords in the diff:**
- "deprecate", "remove", "delete", "drop" → Check for docs to remove/deprecate
- "add", "new", "introduce", "implement" → Check if docs exist; if not, flag as CREATE
- "breaking", "rename", "change" → Check existing docs need UPDATE
- "BREAKING CHANGE" in commit messages → High priority
6. **Output JSON for issues to create:**
For each PR needing documentation changes, create a JSON object with this structure:
{
"title": "[Docs Update] [repo-name] PR #123: Brief description",
"body": "## Source PR\n- Repository: [repo-name]\n- PR: #123 - [PR title]\n- URL: [PR URL]\n- Merged: [date]\n\n## What Changed\n[Clear user-impact summary based on the DIFF, not just the PR description]\n\n## Documentation Impact\n\n### Updates to Existing Docs\n- [ ] `/path/to/file.md` (Section: X) - [Precise change needed; e.g., update signature, add new flag, fix example]\n\n### New Docs to Create\n- [ ] `/proposed/path/new-doc.md` - Title: [Proposed H1 title]\n **Suggested content:**\n ```markdown\n [Outline or initial content with examples, signatures, usage]\n ```\n\n### Docs to Remove or Deprecate\n- [ ] `/path/to/obsolete.md` - Action: [Remove/Deprecate]\n **Replacement:** [Link to new doc if applicable]\n **Rationale:** [Why; cite specific diff changes]\n\n## Recommended Changes\n\n### In `/path/to/file.md`\n\n**Section: [Section name]**\n\n[Specific text to add/change with concrete examples]\n\n## Priority\n[High/Medium/Low] - [Reason]\n\n---\n*Auto-generated by docs sync monitor*",
"labels": ["documentation", "auto-generated", "sync-needed", "[repo-name]", "priority-[level]", "[docs-update|docs-new|docs-remove]"]
}
**Save the output as a JSON array to a file called `issues-to-create.json`**
Example:
[
{
"title": "[Docs Update] stacks-core PR #456: Add new Clarity function map-insert",
"body": "## Source PR\n...",
"labels": ["documentation", "auto-generated", "sync-needed", "stacks-core", "priority-high", "docs-new"]
}
]
7. **Optimization and Quality:**
- Skip PRs with only internal refactoring, tests, or CI changes (follow CLAUDE.md skip list)
- Group multiple PRs affecting the same doc section into one issue when it makes sense
- Prioritize user-facing changes (APIs, features, setup, breaking changes)
- Be specific with file paths and sections - don't create vague "update docs" issues
- When uncertain about removal, prefer "deprecate with redirect" over hard delete
- Include concrete examples, signatures, and suggested content in recommendations
**Important:**
- Only include PRs that genuinely need documentation updates/additions/removals
- Create GitHub issues DIRECTLY using the `gh issue create` command
- Do NOT create a JSON file - create issues immediately as you identify them
- Always fetch and read the actual PR diff - summaries are insufficient
**Creating Issues:**
For each PR that needs documentation, create an issue using:
```bash
gh issue create \
--repo stacks-network/docs \
--title "[Docs Update] [repo-name] PR #123: Brief description" \
--body "$(cat <<'EOF'
## Source PR
- Repository: [repo-name]
- PR: #123 - [PR title]
...
EOF
)" \
--label "documentation,auto-generated,sync-needed,[repo-name],priority-[level],[docs-update|docs-new|docs-remove]"
```
**Important:** Create issues in the stacks-network/docs repository.
After creating each issue, mark it as completed in your todo list before moving to the next one.
claude_args: |
--max-turns 40
--model claude-sonnet-4-20250514
--allowed-tools "Bash(curl*),Bash(gh*),Grep,Read,Write,glob"