diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index b2f45c8..a4c9d56 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "marketing-skills", "description": "Marketing skills for AI agents — conversion optimization, copywriting, SEO, paid ads, ad creative, and growth", - "version": "1.9.0", + "version": "2.1.0", "author": { "name": "Corey Haines" }, diff --git a/.github/scripts/sync-skills.js b/.github/scripts/sync-skills.js index f56ffe4..0dc90a1 100644 --- a/.github/scripts/sync-skills.js +++ b/.github/scripts/sync-skills.js @@ -11,6 +11,7 @@ const path = require("path"); const SKILLS_DIR = "skills"; const MARKETPLACE_FILE = ".claude-plugin/marketplace.json"; +const PLUGIN_FILE = ".claude-plugin/plugin.json"; const README_FILE = "README.md"; /** @@ -157,13 +158,36 @@ function updateMarketplace(skills) { return { updated: true, removedSkillsArray: hadStaleSkillsArray }; } +/** + * Update plugin.json's `version` field to match marketplace.json's + * `metadata.version`. Claude Code uses plugin.json's version for the update + * check (`claude plugin update`); if it drifts from marketplace.json the + * update path silently breaks. + */ +function updatePluginVersion() { + if (!fs.existsSync(PLUGIN_FILE)) return { updated: false }; + + const marketplace = JSON.parse(fs.readFileSync(MARKETPLACE_FILE, "utf8")); + const plugin = JSON.parse(fs.readFileSync(PLUGIN_FILE, "utf8")); + const marketplaceVersion = marketplace.metadata && marketplace.metadata.version; + + if (!marketplaceVersion) return { updated: false }; + if (plugin.version === marketplaceVersion) return { updated: false }; + + const oldVersion = plugin.version; + plugin.version = marketplaceVersion; + fs.writeFileSync(PLUGIN_FILE, JSON.stringify(plugin, null, 2) + "\n"); + return { updated: true, oldVersion, newVersion: marketplaceVersion }; +} + function main() { const skills = getSkillsWithMetadata(); const marketplaceResult = updateMarketplace(skills); const readmeUpdated = updateReadme(skills); + const pluginResult = updatePluginVersion(); - if (!marketplaceResult.updated && !readmeUpdated) { + if (!marketplaceResult.updated && !readmeUpdated && !pluginResult.updated) { console.log("Everything is already in sync"); return; } @@ -175,6 +199,10 @@ function main() { console.log(`Updated marketplace.json (${skills.length} skills)`); } + if (pluginResult.updated) { + console.log(`Bumped plugin.json version: ${pluginResult.oldVersion} → ${pluginResult.newVersion}`); + } + if (readmeUpdated) { console.log("Updated README.md skills table"); } diff --git a/.github/workflows/sync-skills.yml b/.github/workflows/sync-skills.yml index 4e9d5b9..bcbb97a 100644 --- a/.github/workflows/sync-skills.yml +++ b/.github/workflows/sync-skills.yml @@ -5,6 +5,7 @@ on: branches: [main] paths: - 'skills/**' + - '.claude-plugin/marketplace.json' jobs: sync: @@ -26,5 +27,5 @@ jobs: with: commit_user_name: Coreybot commit_user_email: coreybot+github-actions[bot]@users.noreply.github.com - commit_message: "chore: sync skills with marketplace.json and README" - file_pattern: ".claude-plugin/marketplace.json README.md" + commit_message: "chore: sync skills with marketplace.json, plugin.json, and README" + file_pattern: ".claude-plugin/marketplace.json .claude-plugin/plugin.json README.md"