diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1a9330eb..32f8ccec 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,14 +6,14 @@ }, "metadata": { "description": "Syncable CLI skills for AI coding agents — project analysis, security, vulnerabilities, dependencies, IaC validation, and cloud deployment.", - "version": "0.1.8" + "version": "0.1.0" }, "plugins": [ { "name": "syncable-cli-skills", "source": "./installer/plugins/syncable-cli-skills", "description": "Syncable CLI skills for project analysis, security scanning, vulnerability detection, dependency auditing, IaC validation, Kubernetes optimization, and cloud deployment.", - "version": "0.1.8", + "version": "0.1.0", "author": { "name": "Syncable", "email": "support@syncable.dev" diff --git a/installer/package.json b/installer/package.json index fb46d292..d684e844 100644 --- a/installer/package.json +++ b/installer/package.json @@ -1,6 +1,6 @@ { "name": "syncable-cli-skills", - "version": "0.1.8", + "version": "0.1.9", "type": "module", "description": "Install Syncable CLI skills for AI coding agents (Claude Code, Cursor, Windsurf, Codex, Gemini CLI)", "license": "GPL-3.0", diff --git a/installer/plugins/syncable-cli-skills/.claude-plugin/plugin.json b/installer/plugins/syncable-cli-skills/.claude-plugin/plugin.json index fd74b057..4e3d689f 100644 --- a/installer/plugins/syncable-cli-skills/.claude-plugin/plugin.json +++ b/installer/plugins/syncable-cli-skills/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "syncable-cli-skills", "description": "Syncable CLI skills for project analysis, security scanning, vulnerability detection, dependency auditing, IaC validation, Kubernetes optimization, and cloud deployment.", - "version": "0.1.8", + "version": "0.1.0", "author": { "name": "Syncable", "email": "support@syncable.dev" diff --git a/installer/src/transformers/claude.ts b/installer/src/transformers/claude.ts index 2593a17f..1b77cbbd 100644 --- a/installer/src/transformers/claude.ts +++ b/installer/src/transformers/claude.ts @@ -6,7 +6,7 @@ import { TransformResult } from './types.js'; import { execCommand, commandExists } from '../utils.js'; const PLUGIN_NAME = 'syncable-cli-skills'; -const PLUGIN_VERSION = '0.1.8'; +const PLUGIN_VERSION = '0.1.0'; const MARKETPLACE_NAME = 'syncable'; const MARKETPLACE_REPO = 'syncable-dev/syncable-cli'; @@ -173,32 +173,23 @@ function enablePluginInSettings(): void { * 2. Fall back to manual: write cache files + update settings.json */ export async function installClaudePlugin(skills: Skill[]): Promise<{ cacheDir: string; skillCount: number }> { - // Try the official CLI first — this handles enabledPlugins registration. - // We don't return early on success because the CLI may have cached an old - // version of the plugin that is missing the skills directory (e.g. from a - // previous install before skills were added, or from a stale npx cache). - // We always write skills directly to the cache so they're guaranteed to exist. + // Try the official CLI first — this registers the marketplace and plugin + // in Claude Code's settings. We still do a manual write afterwards because + // the CLI-cached version may be stale or missing skills. await tryClaudeCliInstall(); const cacheDir = getClaudePluginCacheDir(); + const pluginRootDir = path.dirname(cacheDir); // .../syncable-cli-skills/ - // Remove stale older-version cache entries so Claude Code doesn't load an - // empty/outdated version instead of the current one. - const pluginRootDir = path.dirname(cacheDir); + // Nuke the ENTIRE plugin cache (all versions) and recreate fresh. + // This prevents version mismatches, stale caches, and — critically — + // removes any .orphaned_at marker that Claude Code writes when a cached + // version doesn't match the marketplace catalog. if (fs.existsSync(pluginRootDir)) { - for (const entry of fs.readdirSync(pluginRootDir)) { - if (entry !== PLUGIN_VERSION) { - fs.rmSync(path.join(pluginRootDir, entry), { recursive: true, force: true }); - } - } - } - - // Clear old skills and rewrite them so the cache is always up to date. - const skillsDir = path.join(cacheDir, 'skills'); - if (fs.existsSync(skillsDir)) { - fs.rmSync(skillsDir, { recursive: true }); + fs.rmSync(pluginRootDir, { recursive: true, force: true }); } + // Write every skill into a clean cache directory. for (const skill of skills) { const results = transformForClaude(skill); for (const { relativePath, content } of results) {