luckiest-co 1.0.8 → 1.0.9
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 +31 -4
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -75,6 +75,8 @@ if (hasHelp) {
|
|
|
75
75
|
${cyan}-l, --local${reset} Install locally (to ./.claude in current directory)
|
|
76
76
|
${cyan}-c, --config-dir <path>${reset} Specify custom Claude config directory
|
|
77
77
|
${cyan}--sync-only${reset} Skip install, only sync owned skills from luckiest.co
|
|
78
|
+
${cyan}--hook${reset} Enable skill usage tracking without prompting
|
|
79
|
+
${cyan}--no-hook${reset} Skip it (and remove it if a past install added it)
|
|
78
80
|
${cyan}-h, --help${reset} Show this help message
|
|
79
81
|
|
|
80
82
|
${yellow}Examples:${reset}
|
|
@@ -210,6 +212,8 @@ async function syncSkills() {
|
|
|
210
212
|
console.log(` ${green}✓${reset} Removed duplicate commands/luckiest (plugin marketplace already provides them)`);
|
|
211
213
|
}
|
|
212
214
|
|
|
215
|
+
nudgeUsageHook(globalDir);
|
|
216
|
+
|
|
213
217
|
const key = readSavedKey();
|
|
214
218
|
if (!key) {
|
|
215
219
|
console.log(` ${dim}No luckiest.co connection key saved yet. Run ${cyan}npx luckiest-co${dim} and paste one to sync your owned skills.${reset}`);
|
|
@@ -448,6 +452,32 @@ async function shouldRegisterHook() {
|
|
|
448
452
|
});
|
|
449
453
|
}
|
|
450
454
|
|
|
455
|
+
// Identifies our hook entry across installs even when the absolute path changed.
|
|
456
|
+
const isOurHookEntry = (entry) =>
|
|
457
|
+
(entry?.hooks || []).some((h) => String(h?.command || '').includes('report-skill-usage.mjs'));
|
|
458
|
+
|
|
459
|
+
function usageHookRegistered(claudeDir) {
|
|
460
|
+
try {
|
|
461
|
+
const settings = JSON.parse(fs.readFileSync(path.join(claudeDir, 'settings.json'), 'utf8'));
|
|
462
|
+
return (settings.hooks?.PostToolUse || []).some(isOurHookEntry);
|
|
463
|
+
} catch {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Tell, don't act. --sync-only runs unattended at session start, so there's no
|
|
470
|
+
* terminal to ask at and registering there would mean silently editing
|
|
471
|
+
* settings.json on a call the user never typed. Instead, say the tracking is off
|
|
472
|
+
* once and let them opt in deliberately. Silent when it's already handled, so
|
|
473
|
+
* this adds nothing to the common session-start path.
|
|
474
|
+
*/
|
|
475
|
+
function nudgeUsageHook(globalClaudeDir) {
|
|
476
|
+
if (hasMarketplacePlugin(globalClaudeDir)) return; // plugin registers its own
|
|
477
|
+
if (usageHookRegistered(globalClaudeDir)) return;
|
|
478
|
+
console.log(` ${dim}Skill usage tracking is off. Run ${cyan}npx luckiest-co@latest --hook${dim} to turn it on.${reset}`);
|
|
479
|
+
}
|
|
480
|
+
|
|
451
481
|
/**
|
|
452
482
|
* Register the PostToolUse(Skill) telemetry hook in the user's settings.json.
|
|
453
483
|
*
|
|
@@ -464,9 +494,6 @@ async function shouldRegisterHook() {
|
|
|
464
494
|
function registerUsageHook(claudeDir, globalClaudeDir, consented) {
|
|
465
495
|
const hookPath = path.join(claudeDir, 'hooks', 'report-skill-usage.mjs');
|
|
466
496
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
467
|
-
// Identifies our entry across installs even when the absolute path changed.
|
|
468
|
-
const isOurs = (entry) =>
|
|
469
|
-
(entry?.hooks || []).some((h) => String(h?.command || '').includes('report-skill-usage.mjs'));
|
|
470
497
|
|
|
471
498
|
let settings = {};
|
|
472
499
|
if (fs.existsSync(settingsPath)) {
|
|
@@ -481,7 +508,7 @@ function registerUsageHook(claudeDir, globalClaudeDir, consented) {
|
|
|
481
508
|
|
|
482
509
|
settings.hooks = settings.hooks || {};
|
|
483
510
|
const existing = Array.isArray(settings.hooks.PostToolUse) ? settings.hooks.PostToolUse : [];
|
|
484
|
-
const others = existing.filter((e) => !
|
|
511
|
+
const others = existing.filter((e) => !isOurHookEntry(e));
|
|
485
512
|
const hadOurs = others.length !== existing.length;
|
|
486
513
|
|
|
487
514
|
// Declining is also an instruction to remove a hook a past install added.
|