luckiest-co 1.0.23 → 1.0.24
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/bin/install.js +46 -12
- package/package.json +3 -2
package/bin/install.js
CHANGED
|
@@ -64,7 +64,7 @@ function parseConfigDirArg() {
|
|
|
64
64
|
const explicitConfigDir = parseConfigDirArg();
|
|
65
65
|
const hasHelp = args.includes('--help') || args.includes('-h');
|
|
66
66
|
|
|
67
|
-
console.log(banner);
|
|
67
|
+
if (require.main === module) console.log(banner);
|
|
68
68
|
|
|
69
69
|
// Show help if requested
|
|
70
70
|
if (hasHelp) {
|
|
@@ -201,6 +201,28 @@ function hasUnzip() {
|
|
|
201
201
|
* Sync owned skills from luckiest.co into ~/.claude/skills/<name>/.
|
|
202
202
|
* Never logs the key or the Authorization header.
|
|
203
203
|
*/
|
|
204
|
+
/**
|
|
205
|
+
* Move extracted skill folders into skillsRoot, replacing older copies.
|
|
206
|
+
* Published zips hold one top-level <skill>/ folder per skill (a bundle holds
|
|
207
|
+
* several). Older zips put SKILL.md at the root; those install as fallbackName.
|
|
208
|
+
* Returns the names placed. Entries without a SKILL.md or with an unsafe name
|
|
209
|
+
* are skipped.
|
|
210
|
+
*/
|
|
211
|
+
function placeSkills(extractDir, skillsRoot, fallbackName) {
|
|
212
|
+
const moves = fs.existsSync(path.join(extractDir, 'SKILL.md'))
|
|
213
|
+
? [[extractDir, fallbackName]]
|
|
214
|
+
: fs.readdirSync(extractDir, { withFileTypes: true })
|
|
215
|
+
.filter((e) => e.isDirectory() && !e.name.startsWith('.'))
|
|
216
|
+
.filter((e) => fs.existsSync(path.join(extractDir, e.name, 'SKILL.md')))
|
|
217
|
+
.map((e) => [path.join(extractDir, e.name), e.name]);
|
|
218
|
+
for (const [src, name] of moves) {
|
|
219
|
+
const dest = path.join(skillsRoot, name);
|
|
220
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
221
|
+
fs.renameSync(src, dest);
|
|
222
|
+
}
|
|
223
|
+
return moves.map(([, name]) => name);
|
|
224
|
+
}
|
|
225
|
+
|
|
204
226
|
async function syncSkills() {
|
|
205
227
|
// Self-heal the /luckiest:luckiest:* duplicate: older installers copied
|
|
206
228
|
// commands into ~/.claude/commands/luckiest even when the marketplace
|
|
@@ -273,15 +295,23 @@ async function syncSkills() {
|
|
|
273
295
|
const buf = Buffer.from(await zipRes.arrayBuffer());
|
|
274
296
|
|
|
275
297
|
if (unzipAvailable) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
fs.writeFileSync(tmpZip, buf);
|
|
298
|
+
// Extract into a private temp dir under skillsRoot (same disk, so the
|
|
299
|
+
// final move is a rename), then place each skill folder at the top level.
|
|
300
|
+
const tmpDir = fs.mkdtempSync(path.join(skillsRoot, '.luckiest-sync-'));
|
|
280
301
|
try {
|
|
281
|
-
|
|
282
|
-
|
|
302
|
+
const tmpZip = path.join(tmpDir, 'skill.zip');
|
|
303
|
+
fs.writeFileSync(tmpZip, buf);
|
|
304
|
+
const extractDir = path.join(tmpDir, 'x');
|
|
305
|
+
execFileSync('unzip', ['-q', tmpZip, '-d', extractDir]);
|
|
306
|
+
for (const placed of placeSkills(extractDir, skillsRoot, safeName)) {
|
|
307
|
+
results.push({
|
|
308
|
+
name: placed,
|
|
309
|
+
version: placed === safeName ? (version || 'unknown') : `bundled with ${safeName}`,
|
|
310
|
+
path: path.join(skillsRoot, placed),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
283
313
|
} finally {
|
|
284
|
-
fs.
|
|
314
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
285
315
|
}
|
|
286
316
|
} else {
|
|
287
317
|
const zipPath = path.join(skillsRoot, `${safeName}.zip`);
|
|
@@ -681,7 +711,11 @@ async function main() {
|
|
|
681
711
|
await syncSkills();
|
|
682
712
|
}
|
|
683
713
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
714
|
+
if (require.main === module) {
|
|
715
|
+
main().catch((err) => {
|
|
716
|
+
console.error(` ${red}Install failed: ${err.message}${reset}`);
|
|
717
|
+
process.exit(1);
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
module.exports = { placeSkills };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luckiest-co",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"description": "Luckiest for Claude Code: plan, go, finish. Your luckiest.co skills and tribe, inside Claude.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"luckiest-co": "./bin/install.js"
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"hooks",
|
|
15
15
|
".claude-plugin",
|
|
16
16
|
"!**/__pycache__",
|
|
17
|
-
"!**/*.pyc"
|
|
17
|
+
"!**/*.pyc",
|
|
18
|
+
"!bin/*.test.js"
|
|
18
19
|
],
|
|
19
20
|
"license": "SEE LICENSE IN LICENSE",
|
|
20
21
|
"engines": {
|