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.
Files changed (2) hide show
  1. package/bin/install.js +31 -4
  2. 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) => !isOurs(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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luckiest-co",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
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"