feat: add generate-briefs and audit-articles agents#2
Conversation
generate-briefs.mjs + generate-briefs.yml: - Keeps content queue full — runs daily at 08:00 UTC before article generation - Reads CONTENT_PLAN.md, counts ready topics - If < MIN_READY (default 5) — calls Claude Haiku to generate new briefs - Reads KEYWORD_RESEARCH.md and existing briefs to avoid duplicates - Writes brief files to docs/briefs/, updates CONTENT_PLAN.md - Supports --dry-run, --count=N flags - Sends Telegram notification when briefs added audit-articles.mjs + audit-articles.yml: - Weekly audit of all published articles — runs Sundays at 07:00 UTC - Checks: required components present, broken internal links, missing OG images, blog-data.ts / llms.txt sync, duplicate slugs, stale year references, emoji violations - Opens GitHub Issue (label: audit) with categorized findings - Updates existing issue with new run instead of creating duplicates - Closes issue automatically when re-audit passes - Sends Telegram notification with link to issues on errors - Supports --blog-glob flag for custom blog directory path docs/gitattributes.template: - Template to copy to client repo root as .gitattributes - merge=union for llms.txt and CONTENT_PLAN.md prevents conflicts when multiple article PRs are open simultaneously README.md + CLAUDE.md: - Documented all new workflows and scripts - Updated commands reference - Updated workflow table
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
| updated = updated.replace( | ||
| /\n> Status values:/, | ||
| "\n" + newTopicLines.join("\n") + "\n\n> Status values:" | ||
| ); |
There was a problem hiding this comment.
New topic rows orphaned from table by blank line
High Severity
The replacement of \n> Status values: inserts new topic rows but always places \n\n (a blank line) before > Status values:. If CONTENT_PLAN.md already has a blank line before > Status values: (standard markdown), the new rows end up separated from the existing table by that blank line. The parseArticleIndex regex in content-plan-parser.mjs terminates table capture at the first \n\n, so the newly inserted rows become invisible to generate-article.mjs. Even starting without a blank line, the first run introduces \n\n, causing all subsequent runs to orphan their rows. The readyCount regex in this script still counts orphaned rows, so the queue appears full while no articles can actually be generated from them.
| description: 'Minimum number of ready topics to maintain (default: 5)' | ||
| required: false | ||
| default: 5 | ||
| type: number |
There was a problem hiding this comment.
Workflow min_ready input is silently ignored
Medium Severity
The workflow declares a min_ready input (default 5) but never passes it to the script. The script hardcodes MIN_READY = 5 and doesn't accept a --min-ready CLI argument. Any caller setting min_ready: 10 (or any other value) in workflow inputs will have it silently ignored, always using the hardcoded threshold of 5.
Additional Locations (1)
- Use /\n+> Status values:/ regex to collapse any blank lines before the legend, preventing new rows from being orphaned outside the table - Accept --min-ready=N CLI arg in generate-briefs.mjs - Pass inputs.min_ready from workflow to script via --min-ready flag


Summary
Two new agents + supporting docs, developed and battle-tested on the VAMI client blog.
generate-briefs agent
Keeps the content queue full automatically — no more manually writing briefs.
readytopics inCONTENT_PLAN.mdMIN_READY(default: 5) — calls Claude Haiku to generate new briefsdocs/KEYWORD_RESEARCH.mdfor keyword clusters (if present)docs/briefs/, updatesCONTENT_PLAN.mdReusable workflow inputs:
config_path,min_ready,force_count,dry_runClient setup:
audit-articles agent
Weekly automated QA pass over all published articles.
src/app/blog/*/page.tsxfor:/blog/<slug>pointing to non-existent article)opengraph-image.tsxdateprop on ArticleAuthorblog-data.ts— all slugs present, no duplicatesllms.txt— all articles listedauditon errors/warningsReusable workflow inputs:
config_path,blog_globdocs/gitattributes.template
Template to copy to
.gitattributesin the client repo. Prevents merge conflicts inllms.txtandCONTENT_PLAN.mdwhen multiple article PRs are open at the same time.Documentation
README.md— updated What it does section with new agentsCLAUDE.md— updated commands reference and workflow tableNote
Medium Risk
Adds new reusable GitHub Actions that can automatically commit to client repos and create/close labeled issues based on script results, so misconfiguration or script bugs could cause unexpected writes/noise. Changes also introduce new Claude API usage and repository-wide content scanning that may fail on edge-case repo layouts.
Overview
Adds two new reusable workflows:
generate-briefs.ymlto auto-generate new content briefs via Claude when theCONTENT_PLAN.mdready-queue is low (then commit/push updates and optionally notify via Telegram), andaudit-articles.ymlto scan all published articles and open/update/close a labeledauditGitHub Issue based on anaudit-report.mdoutput.Introduces
scripts/generate-briefs.mjs(Claude-driven brief creation +docs/briefs/+CONTENT_PLAN.mdupdates) andscripts/audit-articles.mjs(structure/link/sync/style checks with error/warn exit codes and a markdown report), plus updates toREADME.md/CLAUDE.mdand adocs/gitattributes.templateto reduce merge conflicts in append-only tracking files.Written by Cursor Bugbot for commit b63d98f. Configure here.