From 2463affbacf4005efcfe0f0d6108874cf865aa3b Mon Sep 17 00:00:00 2001 From: sickn33 Date: Sat, 21 Mar 2026 11:02:36 +0100 Subject: [PATCH] feat(repo): Automate repo hygiene and release sync Unify main-branch maintenance around repo-state and release-state commands so generated docs, contributor acknowledgements, tracked web assets, and canonical artifacts stay aligned across CI and scheduled hygiene runs. Harden release publication by reusing deterministic sync commands, adding package dry-run verification, and covering the new workflow contract with regression tests. --- .github/MAINTENANCE.md | 5 +- .github/workflows/ci.yml | 22 +- .github/workflows/publish-npm.yml | 32 ++ .github/workflows/repo-hygiene.yml | 62 ++++ CHANGELOG.md | 2 +- apps/web-app/public/sitemap.xml | 164 ++++----- apps/web-app/public/skills.json.backup | 314 +++++++++++++++++- docs/maintainers/release-process.md | 3 + package.json | 4 +- tools/config/generated-files.json | 18 +- tools/scripts/release_workflow.js | 4 +- .../tests/automation_workflows.test.js | 130 ++++++++ tools/scripts/tests/run-test-suite.js | 1 + walkthrough.md | 1 + 14 files changed, 656 insertions(+), 106 deletions(-) create mode 100644 .github/workflows/repo-hygiene.yml create mode 100644 tools/scripts/tests/automation_workflows.test.js diff --git a/.github/MAINTENANCE.md b/.github/MAINTENANCE.md index 9030daf1..aaccf57f 100644 --- a/.github/MAINTENANCE.md +++ b/.github/MAINTENANCE.md @@ -84,7 +84,8 @@ Before ANY commit that adds/modifies skills, run the chain: ```bash npm run sync:repo-state ``` - This wraps `chain + catalog + sync:contributors + audit:consistency` for a full local repo-state refresh. + This wraps `chain + catalog + sync:web-assets + sync:contributors + audit:consistency` for a full local repo-state refresh. + The scheduled GitHub Actions workflow `Repo Hygiene` runs this same sweep weekly to catch slow drift on `main`. When you need the live GitHub repo metadata updated too, run: @@ -305,6 +306,7 @@ Preflight verification → Changelog → `npm run release:prepare -- X.Y.Z` → ```bash npm run release:preflight ``` + This now runs the deterministic `sync:release-state` path, refreshes tracked web assets, executes the local test suite, runs the web-app build, and performs `npm pack --dry-run --json` before a release is considered healthy. Optional diagnostic pass: ```bash npm run validate:strict @@ -326,6 +328,7 @@ Preflight verification → Changelog → `npm run release:prepare -- X.Y.Z` → ``` **Important:** The release tag must match `package.json`'s version. The [Publish to npm](workflows/publish-npm.yml) workflow runs on **Release published** and will run `npm publish`; npm rejects republishing the same version. + Before publishing, that workflow re-runs `sync:release-state`, checks for canonical drift with `git diff --exit-code`, runs tests/docs security/web build, and performs `npm pack --dry-run --json`. _Or create the release manually via GitHub UI > Releases > Draft a new release, then publish._ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcd9af9c..3220297b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -174,6 +174,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + env: + GH_TOKEN: ${{ github.token }} steps: - uses: actions/checkout@v4 @@ -202,17 +204,11 @@ jobs: test -f README.md test -f CONTRIBUTING.md - - name: Validate skills - run: npm run validate - - name: Validate references run: npm run validate:references - - name: Generate index - run: npm run index - - - name: Update README - run: npm run readme + - name: Run repo-state sync + run: npm run sync:repo-state - name: Audit npm dependencies run: npm audit --audit-level=high @@ -226,9 +222,6 @@ jobs: - name: Run docs security checks run: npm run security:docs - - name: Build catalog - run: npm run catalog - - name: Set up GitHub credentials if: github.event_name == 'push' && github.ref == 'refs/heads/main' run: | @@ -243,12 +236,12 @@ jobs: git diff --quiet && exit 0 - git pull origin main --rebase || true git add $managed_files || true git diff --cached --quiet && exit 0 - git commit -m "chore: sync generated registry files [ci skip]" + git commit -m "chore: sync repo state [ci skip]" + git pull origin main --rebase git push origin HEAD - name: Check for uncommitted drift @@ -260,8 +253,7 @@ jobs: echo "Main must be self-healing after the auto-sync step." echo "To fix locally, run the canonical maintainer flow:" echo " npm run release:preflight" - echo " npm run chain" - echo " npm run catalog" + echo " npm run sync:repo-state" echo " git status" exit 1 fi diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 55a1d05e..1c92a836 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -19,12 +19,44 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install Python dependencies + run: pip install pyyaml + - name: Setup Node uses: actions/setup-node@v4 with: node-version: "20" registry-url: "https://registry.npmjs.org" + - name: Install dependencies + run: npm ci + + - name: Validate references + run: npm run validate:references + + - name: Sync release state + run: npm run sync:release-state + + - name: Run tests + run: npm run test + + - name: Run docs security checks + run: npm run security:docs + + - name: Build web app + run: npm run app:build + + - name: Verify canonical release state + run: git diff --exit-code + + - name: Dry-run npm package + run: npm pack --dry-run --json + - name: Publish run: npm publish env: diff --git a/.github/workflows/repo-hygiene.yml b/.github/workflows/repo-hygiene.yml new file mode 100644 index 00000000..3d17a850 --- /dev/null +++ b/.github/workflows/repo-hygiene.yml @@ -0,0 +1,62 @@ +name: Repo Hygiene + +on: + workflow_dispatch: + schedule: + - cron: "0 7 * * 1" + +permissions: + contents: write + +jobs: + sync-repo-state: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Install Python dependencies + run: pip install pyyaml + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + cache: "npm" + + - name: Install npm dependencies + run: npm ci + + - name: Run repo-state sync + run: npm run sync:repo-state + + - name: Commit and push if changed + run: | + set -euo pipefail + + managed_files=$(node tools/scripts/generated_files.js --shell --include-mixed) + + if git diff --quiet; then + echo "No repo-state drift detected." + exit 0 + fi + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add $managed_files || true + + if git diff --cached --quiet; then + echo "Repo hygiene produced unmanaged drift." + git status --short + exit 1 + fi + + git commit -m "chore: scheduled repo hygiene sync [ci skip]" + git pull origin main --rebase + git push origin HEAD diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eb3d062..ded68d91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Realigned README, package metadata, user docs, and GitHub About guidance to the current `1,304+` catalog state and `v8.4.0` release copy. - Automated metadata propagation for curated docs and package copy so `npm run chain` now keeps README, package description, and the main count-sensitive user/maintainer docs aligned when the skill catalog changes. - Added an explicit `sync:github-about` automation path so GitHub About description, homepage, and topics can be refreshed from the same metadata source instead of being updated manually. -- Added contributor sync plus repo-state audit automation: `sync:contributors`, `check:stale-claims`, `audit:consistency`, and `sync:repo-state` now cover contributor acknowledgements, stale count/version drift, and end-to-end maintainer sanity checks. +- Added contributor sync plus repo-state audit automation: `sync:contributors`, `sync:web-assets`, `check:stale-claims`, `audit:consistency`, `sync:release-state`, and `sync:repo-state` now cover contributor acknowledgements, tracked web artifacts, stale count/version drift, deterministic release-state verification, and end-to-end maintainer sanity checks. Main CI, the weekly `Repo Hygiene` workflow, and the npm publish workflow now reuse those paths instead of maintaining separate ad hoc sync steps. ## [8.4.0] - 2026-03-20 - "Discovery, Metadata, and Release Hardening" diff --git a/apps/web-app/public/sitemap.xml b/apps/web-app/public/sitemap.xml index dd058e43..c454ea53 100644 --- a/apps/web-app/public/sitemap.xml +++ b/apps/web-app/public/sitemap.xml @@ -1,248 +1,248 @@ - http://localhost/antigravity-awesome-skills/ - 2026-03-19 + http://localhost/ + 2026-03-21 daily 1.0 - http://localhost/antigravity-awesome-skills/skill/astro - 2026-03-19 + http://localhost/skill/ad-creative + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/hono - 2026-03-19 + http://localhost/skill/ai-seo + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/openclaw-github-repo-commander - 2026-03-19 + http://localhost/skill/churn-prevention + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/pydantic-ai - 2026-03-19 + http://localhost/skill/claude-api + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/sveltekit - 2026-03-19 + http://localhost/skill/cold-email + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/goldrush-api - 2026-03-19 + http://localhost/skill/content-strategy + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/progressive-web-app - 2026-03-19 + http://localhost/skill/defuddle + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/trpc-fullstack - 2026-03-19 + http://localhost/skill/internal-comms + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/vibers-code-review - 2026-03-19 + http://localhost/skill/json-canvas + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/ai-engineering-toolkit - 2026-03-19 + http://localhost/skill/lead-magnets + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/ai-native-cli - 2026-03-19 + http://localhost/skill/obsidian-bases + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/latex-paper-conversion - 2026-03-19 + http://localhost/skill/obsidian-cli + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/antigravity-skill-orchestrator - 2026-03-19 + http://localhost/skill/obsidian-markdown + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/k6-load-testing - 2026-03-19 + http://localhost/skill/product-marketing-context + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/recallmax - 2026-03-19 + http://localhost/skill/revops + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/tool-use-guardian - 2026-03-19 + http://localhost/skill/sales-enablement + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/acceptance-orchestrator - 2026-03-19 + http://localhost/skill/seo + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/closed-loop-delivery - 2026-03-19 + http://localhost/skill/seo-competitor-pages + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/create-issue-gate - 2026-03-19 + http://localhost/skill/seo-content + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/electron-development - 2026-03-19 + http://localhost/skill/seo-dataforseo + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/llm-structured-output - 2026-03-19 + http://localhost/skill/seo-geo + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/ai-md - 2026-03-19 + http://localhost/skill/seo-hreflang + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/explain-like-socrates - 2026-03-19 + http://localhost/skill/seo-image-gen + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/interview-coach - 2026-03-19 + http://localhost/skill/seo-images + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/keyword-extractor - 2026-03-19 + http://localhost/skill/seo-page + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/local-llm-expert - 2026-03-19 + http://localhost/skill/seo-plan + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/skill-check - 2026-03-19 + http://localhost/skill/seo-programmatic + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/yes-md - 2026-03-19 + http://localhost/skill/seo-schema + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/blueprint - 2026-03-19 + http://localhost/skill/seo-sitemap + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/lex - 2026-03-19 + http://localhost/skill/seo-technical + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/pipecat-friday-agent - 2026-03-19 + http://localhost/skill/site-architecture + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/progressive-estimation - 2026-03-19 + http://localhost/skill/advanced-evaluation + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/sankhya-dashboard-html-jsp-custom-best-pratices - 2026-03-19 + http://localhost/skill/agentic-actions-auditor + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/seek-and-analyze-video - 2026-03-19 + http://localhost/skill/astro + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/animejs-animation - 2026-03-19 + http://localhost/skill/hono + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/antigravity-design-expert - 2026-03-19 + http://localhost/skill/landing-page-generator + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/audit-skills - 2026-03-19 + http://localhost/skill/openclaw-github-repo-commander + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/daily - 2026-03-19 + http://localhost/skill/pydantic-ai + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/design-spells - 2026-03-19 + http://localhost/skill/sveltekit + 2026-03-21 weekly 0.7 - http://localhost/antigravity-awesome-skills/skill/frontend-slides - 2026-03-19 + http://localhost/skill/goldrush-api + 2026-03-21 weekly 0.7 diff --git a/apps/web-app/public/skills.json.backup b/apps/web-app/public/skills.json.backup index 28517f65..e182aacb 100644 --- a/apps/web-app/public/skills.json.backup +++ b/apps/web-app/public/skills.json.backup @@ -119,6 +119,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "ad-creative", + "path": "skills/ad-creative", + "category": "uncategorized", + "name": "ad-creative", + "description": "Create, iterate, and scale paid ad creative for Google Ads, Meta, LinkedIn, TikTok, and similar platforms. Use when generating headlines, descriptions, primary text, or large sets of ad variations for testing and performance optimization.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "address-github-comments", "path": "skills/address-github-comments", @@ -389,6 +399,16 @@ "source": "vibeship-spawner-skills (Apache 2.0)", "date_added": "2026-02-27" }, + { + "id": "ai-seo", + "path": "skills/ai-seo", + "category": "ai-ml", + "name": "ai-seo", + "description": "Optimize content for AI search and LLM citations across AI Overviews, ChatGPT, Perplexity, Claude, Gemini, and similar systems. Use when improving AI visibility, answer engine optimization, or citation readiness.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "ai-studio-image", "path": "skills/ai-studio-image", @@ -3089,6 +3109,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "churn-prevention", + "path": "skills/churn-prevention", + "category": "uncategorized", + "name": "churn-prevention", + "description": "Reduce voluntary and involuntary churn with cancel flows, save offers, dunning, win-back tactics, and retention strategy. Use when users are cancelling, failed payments are rising, or subscription retention needs improvement.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "cicd-automation-workflow-automate", "path": "skills/cicd-automation-workflow-automate", @@ -3159,6 +3189,16 @@ "source": "https://github.com/huifer/Claude-Ally-Health", "date_added": "2026-02-27" }, + { + "id": "claude-api", + "path": "skills/claude-api", + "category": "ai-ml", + "name": "claude-api", + "description": "Build apps with the Claude API or Anthropic SDK. TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`/`claude_agent_sdk`, or user asks to use Claude API, Anthropic SDKs, or Agent SDK. DO NOT TRIGGER when: code imports `openai`/other AI SDK, general programming, or ML/data-science tasks.", + "risk": "unknown", + "source": "https://github.com/anthropics/skills", + "date_added": "2026-03-21" + }, { "id": "claude-code-expert", "path": "skills/claude-code-expert", @@ -3509,6 +3549,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "cold-email", + "path": "skills/cold-email", + "category": "uncategorized", + "name": "cold-email", + "description": "Write B2B cold emails and follow-up sequences that earn replies. Use when creating outbound prospecting emails, SDR outreach, personalized opening lines, subject lines, CTAs, and multi-touch follow-up sequences.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "comfyui-gateway", "path": "skills/comfyui-gateway", @@ -3709,6 +3759,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "content-strategy", + "path": "skills/content-strategy", + "category": "uncategorized", + "name": "content-strategy", + "description": "Plan a content strategy, topic clusters, editorial roadmap, and content mix for traffic, authority, and lead generation. Use when deciding what to publish, what topics to prioritize, or how to structure a content program.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "context-agent", "path": "skills/context-agent", @@ -4339,6 +4399,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "defuddle", + "path": "skills/defuddle", + "category": "content", + "name": "defuddle", + "description": "Extract clean markdown content from web pages using Defuddle CLI, removing clutter and navigation to save tokens. Use instead of WebFetch when the user provides a URL to read or analyze, for online documentation, articles, blog posts, or any standard web page.", + "risk": "unknown", + "source": "https://github.com/kepano/obsidian-skills", + "date_added": "2026-03-21" + }, { "id": "dependency-management-deps-audit", "path": "skills/dependency-management-deps-audit", @@ -5865,9 +5935,9 @@ "category": "security", "name": "gha-security-review", "description": "Find exploitable vulnerabilities in GitHub Actions workflows. Every finding MUST include a concrete exploitation scenario \u2014 if you can't build the attack, don't report it.", - "risk": "unknown", + "risk": "safe", "source": "community", - "date_added": null + "date_added": "2026-03-16" }, { "id": "git-advanced-workflows", @@ -6749,6 +6819,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "internal-comms", + "path": "skills/internal-comms", + "category": "uncategorized", + "name": "internal-comms", + "description": "Write internal communications such as status reports, leadership updates, 3P updates, newsletters, FAQs, incident reports, and project updates using repeatable internal formats.", + "risk": "unknown", + "source": "https://github.com/anthropics/skills", + "date_added": "2026-03-21" + }, { "id": "internal-comms-anthropic", "path": "skills/internal-comms-anthropic", @@ -6889,6 +6969,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "json-canvas", + "path": "skills/json-canvas", + "category": "uncategorized", + "name": "json-canvas", + "description": "Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections. Use when working with .canvas files, creating visual canvases, mind maps, flowcharts, or when the user mentions Canvas files in Obsidian.", + "risk": "unknown", + "source": "https://github.com/kepano/obsidian-skills", + "date_added": "2026-03-21" + }, { "id": "julia-pro", "path": "skills/julia-pro", @@ -7099,6 +7189,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "lead-magnets", + "path": "skills/lead-magnets", + "category": "uncategorized", + "name": "lead-magnets", + "description": "Plan and optimize lead magnets for email capture and lead generation. Use when designing gated content, checklists, templates, downloadable resources, or other offers that convert visitors into subscribers.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "legacy-modernizer", "path": "skills/legacy-modernizer", @@ -8399,6 +8499,26 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "obsidian-bases", + "path": "skills/obsidian-bases", + "category": "uncategorized", + "name": "obsidian-bases", + "description": "Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.", + "risk": "unknown", + "source": "https://github.com/kepano/obsidian-skills", + "date_added": "2026-03-21" + }, + { + "id": "obsidian-cli", + "path": "skills/obsidian-cli", + "category": "uncategorized", + "name": "obsidian-cli", + "description": "Use the Obsidian CLI to read, create, search, and manage vault content, or to develop and debug Obsidian plugins and themes from the command line.", + "risk": "unknown", + "source": "https://github.com/kepano/obsidian-skills", + "date_added": "2026-03-21" + }, { "id": "obsidian-clipper-template-creator", "path": "skills/obsidian-clipper-template-creator", @@ -8409,6 +8529,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "obsidian-markdown", + "path": "skills/obsidian-markdown", + "category": "uncategorized", + "name": "obsidian-markdown", + "description": "Create and edit Obsidian Flavored Markdown with wikilinks, embeds, callouts, properties, and other Obsidian-specific syntax. Use when working with .md files in Obsidian, or when the user mentions wikilinks, callouts, frontmatter, tags, embeds, or Obsidian notes.", + "risk": "unknown", + "source": "https://github.com/kepano/obsidian-skills", + "date_added": "2026-03-21" + }, { "id": "occupational-health-analyzer", "path": "skills/occupational-health-analyzer", @@ -9259,6 +9389,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "product-marketing-context", + "path": "skills/product-marketing-context", + "category": "business", + "name": "product-marketing-context", + "description": "Create or update a reusable product marketing context document with positioning, audience, ICP, use cases, and messaging. Use at the start of a project to avoid repeating core marketing context across tasks.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "production-code-audit", "path": "skills/production-code-audit", @@ -9819,6 +9959,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "revops", + "path": "skills/revops", + "category": "business", + "name": "revops", + "description": "Design and improve revenue operations, lead lifecycle rules, scoring, routing, handoffs, and CRM process automation. Use when marketing, sales, and customer success workflows need clearer operational structure.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "risk-manager", "path": "skills/risk-manager", @@ -9949,6 +10099,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "sales-enablement", + "path": "skills/sales-enablement", + "category": "uncategorized", + "name": "sales-enablement", + "description": "Create sales collateral such as decks, one-pagers, objection docs, demo scripts, playbooks, and proposal templates. Use when a sales team needs assets that help reps move deals forward and close.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "salesforce-automation", "path": "skills/salesforce-automation", @@ -10299,6 +10459,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo", + "path": "skills/seo", + "category": "content", + "name": "seo", + "description": "Run a broad SEO audit across technical SEO, on-page SEO, schema, sitemaps, content quality, AI search readiness, and GEO. Use as the umbrella skill when the user asks for a full SEO analysis or strategy.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "seo-audit", "path": "skills/seo-audit", @@ -10329,6 +10499,26 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo-competitor-pages", + "path": "skills/seo-competitor-pages", + "category": "uncategorized", + "name": "seo-competitor-pages", + "description": "Generate SEO-optimized competitor comparison and alternatives pages. Covers \"X vs Y\" layouts, \"alternatives to X\" pages, feature matrices, schema markup, and conversion optimization. Use when user says \"comparison page\", \"vs page\", \"alternatives page\", \"competitor comparison\", or \"X vs Y\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-content", + "path": "skills/seo-content", + "category": "content", + "name": "seo-content", + "description": "Content quality and E-E-A-T analysis with AI citation readiness assessment. Use when user says \"content quality\", \"E-E-A-T\", \"content analysis\", \"readability check\", \"thin content\", or \"content audit\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "seo-content-auditor", "path": "skills/seo-content-auditor", @@ -10369,6 +10559,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo-dataforseo", + "path": "skills/seo-dataforseo", + "category": "uncategorized", + "name": "seo-dataforseo", + "description": "Use DataForSEO for live SERPs, keyword metrics, backlinks, competitor analysis, on-page checks, and AI visibility data. Trigger when the user needs real SEO data rather than static guidance.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "seo-forensic-incident-response", "path": "skills/seo-forensic-incident-response", @@ -10389,6 +10589,46 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo-geo", + "path": "skills/seo-geo", + "category": "uncategorized", + "name": "seo-geo", + "description": "Optimize content for AI Overviews, ChatGPT, Perplexity, and other AI search systems. Use when improving GEO, AI citations, llms.txt readiness, crawler accessibility, and passage-level citability.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-hreflang", + "path": "skills/seo-hreflang", + "category": "uncategorized", + "name": "seo-hreflang", + "description": "Hreflang and international SEO audit, validation, and generation. Detects common mistakes, validates language/region codes, and generates correct hreflang implementations. Use when user says \"hreflang\", \"i18n SEO\", \"international SEO\", \"multi-language\", \"multi-region\", or \"language tags\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-image-gen", + "path": "skills/seo-image-gen", + "category": "content", + "name": "seo-image-gen", + "description": "Generate SEO-focused images such as OG cards, hero images, schema assets, product visuals, and infographics. Use when image generation is part of an SEO workflow or content publishing task.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-images", + "path": "skills/seo-images", + "category": "uncategorized", + "name": "seo-images", + "description": "Image optimization analysis for SEO and performance. Checks alt text, file sizes, formats, responsive images, lazy loading, and CLS prevention. Use when user says \"image optimization\", \"alt text\", \"image SEO\", \"image size\", or \"image audit\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "seo-keyword-strategist", "path": "skills/seo-keyword-strategist", @@ -10409,6 +10649,56 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo-page", + "path": "skills/seo-page", + "category": "uncategorized", + "name": "seo-page", + "description": "Deep single-page SEO analysis covering on-page elements, content quality, technical meta tags, schema, images, and performance. Use when user says \"analyze this page\", \"check page SEO\", or provides a single URL for review.\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-plan", + "path": "skills/seo-plan", + "category": "content", + "name": "seo-plan", + "description": "Strategic SEO planning for new or existing websites. Industry-specific templates, competitive analysis, content strategy, and implementation roadmap. Use when user says \"SEO plan\", \"SEO strategy\", \"content strategy\", \"site architecture\", or \"SEO roadmap\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-programmatic", + "path": "skills/seo-programmatic", + "category": "uncategorized", + "name": "seo-programmatic", + "description": "Plan and audit programmatic SEO pages generated at scale from structured data. Use when designing templates, URL systems, internal linking, quality gates, and index-bloat safeguards for pages at scale.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-schema", + "path": "skills/seo-schema", + "category": "uncategorized", + "name": "seo-schema", + "description": "Detect, validate, and generate Schema.org structured data. JSON-LD format preferred. Use when user says \"schema\", \"structured data\", \"rich results\", \"JSON-LD\", or \"markup\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, + { + "id": "seo-sitemap", + "path": "skills/seo-sitemap", + "category": "uncategorized", + "name": "seo-sitemap", + "description": "Analyze existing XML sitemaps or generate new ones with industry templates. Validates format, URLs, and structure. Use when user says \"sitemap\", \"generate sitemap\", \"sitemap issues\", or \"XML sitemap\".\n", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "seo-snippet-hunter", "path": "skills/seo-snippet-hunter", @@ -10429,6 +10719,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "seo-technical", + "path": "skills/seo-technical", + "category": "web-development", + "name": "seo-technical", + "description": "Audit technical SEO across crawlability, indexability, security, URLs, mobile, Core Web Vitals, structured data, JavaScript rendering, and related platform signals like robots.txt and AI crawler access.", + "risk": "unknown", + "source": "https://github.com/AgriciDaniel/claude-seo", + "date_added": "2026-03-21" + }, { "id": "server-management", "path": "skills/server-management", @@ -10569,6 +10869,16 @@ "source": "community", "date_added": "2026-02-27" }, + { + "id": "site-architecture", + "path": "skills/site-architecture", + "category": "architecture", + "name": "site-architecture", + "description": "Plan or restructure website hierarchy, navigation, URL patterns, breadcrumbs, and internal linking. Use when mapping pages, sections, and site structure, but not for XML sitemap auditing or schema markup.", + "risk": "unknown", + "source": "https://github.com/coreyhaines31/marketingskills", + "date_added": "2026-03-21" + }, { "id": "skill-check", "path": "skills/skill-check", diff --git a/docs/maintainers/release-process.md b/docs/maintainers/release-process.md index e7c31dc8..e7ad9913 100644 --- a/docs/maintainers/release-process.md +++ b/docs/maintainers/release-process.md @@ -17,6 +17,8 @@ This is the maintainer playbook for cutting a repository release. Historical rel npm run release:preflight ``` +This preflight now runs the deterministic `sync:release-state` flow, refreshes the tracked web assets in `apps/web-app/public`, executes the local test suite, runs the web-app build, and performs `npm pack --dry-run --json` so release tags are validated against the same artifact path used later in CI. + 2. Mandatory documentation hardening (repo-wide SKILL.md security scan): ```bash @@ -71,6 +73,7 @@ npm publish ``` Normally this still happens via the existing GitHub release workflow after the GitHub release is published. +That workflow now reruns `sync:release-state`, refreshes tracked web assets, fails on canonical drift via `git diff --exit-code`, executes tests and docs security checks, builds the web app, and dry-runs the npm package before `npm publish`. ## Rollback Notes diff --git a/package.json b/package.json index 0559ec50..f48af0ff 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "sync:metadata": "node tools/scripts/run-python.js tools/scripts/sync_repo_metadata.py", "sync:github-about": "node tools/scripts/run-python.js tools/scripts/sync_repo_metadata.py --apply-github-about", "sync:contributors": "node tools/scripts/run-python.js tools/scripts/sync_contributors.py", + "sync:web-assets": "npm run app:setup && cd apps/web-app && npm run generate:sitemap", "chain": "npm run validate && npm run index && npm run sync:metadata", "sync:all": "npm run chain", - "sync:repo-state": "npm run chain && npm run catalog && npm run sync:contributors && npm run audit:consistency", + "sync:release-state": "npm run chain && npm run catalog && npm run sync:web-assets && npm run audit:consistency", + "sync:repo-state": "npm run chain && npm run catalog && npm run sync:web-assets && npm run sync:contributors && npm run audit:consistency", "sync:repo-state:full": "npm run sync:repo-state && npm run sync:github-about && npm run audit:consistency:github", "catalog": "node tools/scripts/build-catalog.js", "build": "npm run chain && npm run catalog", diff --git a/tools/config/generated-files.json b/tools/config/generated-files.json index 971c39ae..262adadc 100644 --- a/tools/config/generated-files.json +++ b/tools/config/generated-files.json @@ -5,10 +5,24 @@ "data/skills_index.json", "data/catalog.json", "data/bundles.json", - "data/aliases.json" + "data/aliases.json", + "apps/web-app/public/sitemap.xml", + "apps/web-app/public/skills.json.backup" ], "mixedFiles": [ - "README.md" + "README.md", + "package.json", + "docs/users/getting-started.md", + "docs/users/bundles.md", + "docs/users/claude-code-skills.md", + "docs/users/gemini-cli-skills.md", + "docs/users/usage.md", + "docs/users/visual-guide.md", + "docs/users/kiro-integration.md", + "docs/maintainers/repo-growth-seo.md", + "docs/maintainers/skills-update-guide.md", + "docs/integrations/jetski-cortex.md", + "docs/integrations/jetski-gemini-loader/README.md" ], "releaseManagedFiles": [ "CHANGELOG.md", diff --git a/tools/scripts/release_workflow.js b/tools/scripts/release_workflow.js index ba40b015..eb93b509 100644 --- a/tools/scripts/release_workflow.js +++ b/tools/scripts/release_workflow.js @@ -112,11 +112,11 @@ function writeReleaseNotes(projectRoot, version, sectionContent) { } function runReleaseSuite(projectRoot) { - runCommand("npm", ["run", "validate"], projectRoot); runCommand("npm", ["run", "validate:references"], projectRoot); - runCommand("npm", ["run", "sync:all"], projectRoot); + runCommand("npm", ["run", "sync:release-state"], projectRoot); runCommand("npm", ["run", "test"], projectRoot); runCommand("npm", ["run", "app:build"], projectRoot); + runCommand("npm", ["pack", "--dry-run", "--json"], projectRoot); } function runReleasePreflight(projectRoot) { diff --git a/tools/scripts/tests/automation_workflows.test.js b/tools/scripts/tests/automation_workflows.test.js new file mode 100644 index 00000000..ea5b2013 --- /dev/null +++ b/tools/scripts/tests/automation_workflows.test.js @@ -0,0 +1,130 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const repoRoot = path.resolve(__dirname, "..", "..", ".."); + +function readText(relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), "utf8"); +} + +const packageJson = JSON.parse(readText("package.json")); +const generatedFiles = JSON.parse(readText("tools/config/generated-files.json")); +const ciWorkflow = readText(".github/workflows/ci.yml"); +const publishWorkflow = readText(".github/workflows/publish-npm.yml"); +const hygieneWorkflowPath = path.join(repoRoot, ".github", "workflows", "repo-hygiene.yml"); + +assert.ok( + packageJson.scripts["sync:release-state"], + "package.json should expose a deterministic release-state sync command", +); +assert.ok( + packageJson.scripts["sync:web-assets"], + "package.json should expose a web-asset sync command for tracked web artifacts", +); +assert.match( + packageJson.scripts["sync:release-state"], + /sync:web-assets/, + "sync:release-state should refresh tracked web assets before auditing release drift", +); +assert.match( + packageJson.scripts["sync:repo-state"], + /sync:web-assets/, + "sync:repo-state should refresh tracked web assets before maintainer audits", +); + +for (const filePath of [ + "apps/web-app/public/sitemap.xml", + "apps/web-app/public/skills.json.backup", +]) { + assert.ok( + generatedFiles.derivedFiles.includes(filePath), + `generated-files derivedFiles should include ${filePath}`, + ); +} + +for (const filePath of [ + "README.md", + "package.json", + "docs/users/getting-started.md", + "docs/users/bundles.md", + "docs/users/claude-code-skills.md", + "docs/users/gemini-cli-skills.md", + "docs/users/usage.md", + "docs/users/visual-guide.md", + "docs/users/kiro-integration.md", + "docs/maintainers/repo-growth-seo.md", + "docs/maintainers/skills-update-guide.md", + "docs/integrations/jetski-cortex.md", + "docs/integrations/jetski-gemini-loader/README.md", +]) { + assert.ok( + generatedFiles.mixedFiles.includes(filePath), + `generated-files mixedFiles should include ${filePath}`, + ); +} + +assert.match( + ciWorkflow, + /- name: Run repo-state sync[\s\S]*?run: npm run sync:repo-state/, + "main CI should use the unified repo-state sync command", +); +assert.match( + ciWorkflow, + /GH_TOKEN: \$\{\{ github\.token \}\}/, + "main CI should provide GH_TOKEN for contributor synchronization", +); +assert.doesNotMatch( + ciWorkflow, + /^ - name: Generate index$/m, + "main CI should not keep the old standalone Generate index step", +); +assert.doesNotMatch( + ciWorkflow, + /^ - name: Update README$/m, + "main CI should not keep the old standalone Update README step", +); +assert.doesNotMatch( + ciWorkflow, + /^ - name: Build catalog$/m, + "main CI should not keep the old standalone Build catalog step", +); + +assert.ok(fs.existsSync(hygieneWorkflowPath), "repo hygiene workflow should exist"); + +const hygieneWorkflow = readText(".github/workflows/repo-hygiene.yml"); +assert.match(hygieneWorkflow, /^on:\n workflow_dispatch:\n schedule:/m, "repo hygiene workflow should support schedule and manual runs"); +assert.match( + hygieneWorkflow, + /GH_TOKEN: \$\{\{ github\.token \}\}/, + "repo hygiene workflow should provide GH_TOKEN for gh-based contributor sync", +); +assert.match( + hygieneWorkflow, + /run: npm run sync:repo-state/, + "repo hygiene workflow should run the unified repo-state sync command", +); +assert.match( + hygieneWorkflow, + /generated_files\.js --shell --include-mixed/, + "repo hygiene workflow should stage the mixed generated files contract", +); + +assert.match(publishWorkflow, /run: npm ci/, "npm publish workflow should install dependencies"); +assert.match( + publishWorkflow, + /run: npm run sync:release-state/, + "npm publish workflow should verify canonical release artifacts", +); +assert.match( + publishWorkflow, + /run: git diff --exit-code/, + "npm publish workflow should fail if canonical sync would leave release drift", +); +assert.match(publishWorkflow, /run: npm run test/, "npm publish workflow should run tests before publish"); +assert.match(publishWorkflow, /run: npm run app:build/, "npm publish workflow should build the app before publish"); +assert.match( + publishWorkflow, + /npm pack --dry-run --json/, + "npm publish workflow should dry-run package creation before publishing", +); diff --git a/tools/scripts/tests/run-test-suite.js b/tools/scripts/tests/run-test-suite.js index e3f86060..cff5e0e9 100644 --- a/tools/scripts/tests/run-test-suite.js +++ b/tools/scripts/tests/run-test-suite.js @@ -9,6 +9,7 @@ const TOOL_SCRIPTS = path.join("tools", "scripts"); const TOOL_TESTS = path.join(TOOL_SCRIPTS, "tests"); const LOCAL_TEST_COMMANDS = [ [path.join(TOOL_TESTS, "activate_skills_batch_security.test.js")], + [path.join(TOOL_TESTS, "automation_workflows.test.js")], [path.join(TOOL_TESTS, "build_catalog_bundles.test.js")], [path.join(TOOL_TESTS, "claude_plugin_marketplace.test.js")], [path.join(TOOL_TESTS, "jetski_gemini_loader.test.cjs")], diff --git a/walkthrough.md b/walkthrough.md index 0a18664b..289f6816 100644 --- a/walkthrough.md +++ b/walkthrough.md @@ -128,3 +128,4 @@ - Automated the recurring docs metadata maintenance by extending `tools/scripts/sync_repo_metadata.py`, wiring it into `npm run chain`, and adding a regression test so future skill-count/version updates propagate through the curated docs surface without manual patching. - Added a remote GitHub About sync path (`npm run sync:github-about`) backed by `gh repo edit` + `gh api .../topics` so the public repository metadata can be refreshed from the same source of truth on demand. - Added maintainer automation for repo-state hygiene: `sync:contributors` updates the README contributor list from GitHub contributors, `check:stale-claims`/`audit:consistency` catch drift in count-sensitive docs, and `sync:repo-state` now chains the local maintainer sweep into a single command. +- Hardened automation surfaces beyond the local CLI: `main` CI now runs the unified repo-state sync, tracked web artifacts are refreshed through `sync:web-assets`, release verification now uses a deterministic `sync:release-state` path plus `npm pack --dry-run`, the npm publish workflow reruns those checks before publishing, and a weekly `Repo Hygiene` GitHub Actions workflow now sweeps slow drift on `main`.