luckiest-co 1.0.34 → 1.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/install.js
CHANGED
|
@@ -224,6 +224,58 @@ function placeSkills(extractDir, skillsRoot, fallbackName) {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
async function syncSkills() {
|
|
227
|
+
try {
|
|
228
|
+
await syncOwnedSkills();
|
|
229
|
+
} finally {
|
|
230
|
+
// Self-heal the luckiest-x + luckiest:luckiest-x duplicate: the marketplace
|
|
231
|
+
// plugin already registers its skills, so a copy in ~/.claude/skills (from
|
|
232
|
+
// older installers or from this sync) lists every one of them twice.
|
|
233
|
+
const globalDir = expandTilde(explicitConfigDir) || expandTilde(process.env.CLAUDE_CONFIG_DIR) || path.join(os.homedir(), '.claude');
|
|
234
|
+
const removed = dropPluginDuplicates(path.join(globalDir, 'skills'), pluginSkillNames(globalDir));
|
|
235
|
+
if (removed.length) {
|
|
236
|
+
console.log(` ${green}✓${reset} Removed ${removed.length} duplicate skill(s) from skills/ (plugin marketplace already provides them)`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Skill folder names shipped by the enabled marketplace plugin, read from its
|
|
243
|
+
* installPath. Empty when the plugin is absent or disabled.
|
|
244
|
+
*/
|
|
245
|
+
function pluginSkillNames(globalClaudeDir) {
|
|
246
|
+
const names = new Set();
|
|
247
|
+
if (!hasMarketplacePlugin(globalClaudeDir)) return names;
|
|
248
|
+
try {
|
|
249
|
+
const manifest = JSON.parse(
|
|
250
|
+
fs.readFileSync(path.join(globalClaudeDir, 'plugins', 'installed_plugins.json'), 'utf8')
|
|
251
|
+
);
|
|
252
|
+
for (const [key, value] of Object.entries(manifest.plugins || {})) {
|
|
253
|
+
if (!key.startsWith('luckiest@')) continue;
|
|
254
|
+
for (const item of Array.isArray(value) ? value : [value]) {
|
|
255
|
+
const dir = item && item.installPath && path.join(item.installPath, 'skills');
|
|
256
|
+
if (dir && fs.existsSync(dir)) fs.readdirSync(dir).forEach((n) => names.add(n));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
// Unreadable manifest: remove nothing.
|
|
261
|
+
}
|
|
262
|
+
return names;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Remove skills/<name> for every name the plugin ships. Returns removed names. */
|
|
266
|
+
function dropPluginDuplicates(skillsRoot, names) {
|
|
267
|
+
const removed = [];
|
|
268
|
+
for (const name of names) {
|
|
269
|
+
const dest = path.join(skillsRoot, name);
|
|
270
|
+
if (fs.existsSync(path.join(dest, 'SKILL.md'))) {
|
|
271
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
272
|
+
removed.push(name);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return removed;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function syncOwnedSkills() {
|
|
227
279
|
// Self-heal the /luckiest:luckiest:* duplicate: older installers copied
|
|
228
280
|
// commands into ~/.claude/commands/luckiest even when the marketplace
|
|
229
281
|
// plugin already registers them. Sync runs every session, so clean it here.
|
|
@@ -428,8 +480,12 @@ function install(isGlobal) {
|
|
|
428
480
|
}
|
|
429
481
|
|
|
430
482
|
// Copy references/, templates/, .claude-plugin/ into the target root
|
|
483
|
+
// skills/ is skipped when the marketplace plugin ships them, for the same
|
|
484
|
+
// reason as commands/ above (luckiest-x and luckiest:luckiest-x).
|
|
485
|
+
const pluginPresent = hasMarketplacePlugin(defaultGlobalDir);
|
|
431
486
|
const topLevelDirs = ['references', 'templates', 'skills', '.claude-plugin', 'hooks'];
|
|
432
487
|
for (const dir of topLevelDirs) {
|
|
488
|
+
if (dir === 'skills' && pluginPresent) continue;
|
|
433
489
|
const dirSrc = path.join(src, dir);
|
|
434
490
|
const dirDest = path.join(claudeDir, dir);
|
|
435
491
|
if (fs.existsSync(dirSrc)) {
|
|
@@ -718,4 +774,4 @@ if (require.main === module) {
|
|
|
718
774
|
});
|
|
719
775
|
}
|
|
720
776
|
|
|
721
|
-
module.exports = { placeSkills };
|
|
777
|
+
module.exports = { placeSkills, dropPluginDuplicates };
|