@npeercy/skills 0.1.7 → 0.1.8

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/skills.js CHANGED
@@ -16,7 +16,7 @@ const USAGE = `skill-sharer — CLI skill manager for coding agents
16
16
  Usage: skills <command> [options]
17
17
 
18
18
  Setup:
19
- init [--server <url>] [--token <token>] [--no-import] Setup skill-sharer
19
+ init [--server <url>] [--token <token>] Setup skill-sharer (local-only; never publishes)
20
20
  login [--server <url>] [--token <token>] Set/refresh token (prompts if missing)
21
21
  logout Remove stored token
22
22
 
@@ -85,9 +85,9 @@ async function main() {
85
85
  const { values } = parseArgs({ args: rest, options: {
86
86
  server: { type: 'string' },
87
87
  token: { type: 'string' },
88
- 'no-import': { type: 'boolean', default: false },
88
+ 'no-import': { type: 'boolean', default: false }, // deprecated compatibility; init never imports
89
89
  }, allowPositionals: false });
90
- await cmdInit({ server: values.server, token: values.token, noImport: values['no-import'] });
90
+ await cmdInit({ server: values.server, token: values.token });
91
91
  break;
92
92
  }
93
93
  case 'login': {
package/lib/skills.js CHANGED
@@ -262,12 +262,20 @@ export function getLocalDiagnostics() {
262
262
  const unmanaged = discoverUnmanaged(agents, st);
263
263
  const conflicts = discoverAgentNameConflicts(agents);
264
264
 
265
+ const installedBuiltinIds = new Set(
266
+ Object.keys(st.installed).filter(id => id.startsWith('__builtin__/local/')),
267
+ );
268
+ const missingBuiltins = bundled.filter(b => !installedBuiltinIds.has(b.id));
269
+
265
270
  return {
266
271
  state: st,
267
272
  agents,
268
273
  managedCount: Object.keys(st.installed).length,
269
274
  bundledBuiltinsCount: bundled.length,
270
- hasBuiltinsInstalled: Object.keys(st.installed).some(id => id.startsWith('__builtin__/local/')),
275
+ installedBuiltinsCount: installedBuiltinIds.size,
276
+ missingBuiltinsCount: missingBuiltins.length,
277
+ hasBuiltinsInstalled: missingBuiltins.length === 0,
278
+ missingBuiltins,
271
279
  unmanagedCount: unmanaged.size,
272
280
  conflictCount: conflicts.length,
273
281
  unmanaged,
@@ -275,7 +283,7 @@ export function getLocalDiagnostics() {
275
283
  };
276
284
  }
277
285
 
278
- async function installBuiltins(agents) {
286
+ async function installBuiltins(agents, { quiet = false } = {}) {
279
287
  const st = loadState();
280
288
 
281
289
  const installed = [];
@@ -344,14 +352,14 @@ async function installBuiltins(agents) {
344
352
 
345
353
  saveState(st);
346
354
 
347
- if (installed.length > 0) {
355
+ if (!quiet && installed.length > 0) {
348
356
  console.log('\nInstalled built-in skills:');
349
357
  for (const name of installed) {
350
358
  console.log(` ✓ ${name} → ${Object.keys(agents).join(', ') || '(no agents detected)'}`);
351
359
  }
352
360
  }
353
361
 
354
- if (skipped.length > 0) {
362
+ if (!quiet && skipped.length > 0) {
355
363
  console.log('\nSkipped built-ins to avoid skill-name conflicts in agents:');
356
364
  for (const s of skipped) {
357
365
  const where = s.conflicts.map(c => `${c.agent}/${c.entryName}`).join(', ');
@@ -359,6 +367,22 @@ async function installBuiltins(agents) {
359
367
  }
360
368
  console.log(' Tip: remove/rename duplicates if you want bundled docs linked automatically.');
361
369
  }
370
+
371
+ return { installed, skipped };
372
+ }
373
+
374
+ export async function ensureBuiltinsInstalled({ quiet = true } = {}) {
375
+ const d = getLocalDiagnostics();
376
+ if (d.missingBuiltinsCount === 0) {
377
+ return { changed: false, installed: [], skipped: [] };
378
+ }
379
+
380
+ const result = await installBuiltins(d.agents, { quiet });
381
+ return {
382
+ changed: result.installed.length > 0,
383
+ installed: result.installed,
384
+ skipped: result.skipped,
385
+ };
362
386
  }
363
387
 
364
388
  // --- Commands ---
@@ -405,14 +429,17 @@ export async function cmdInit(args) {
405
429
  throw new Error(`Token invalid: ${e.message}`);
406
430
  }
407
431
 
408
- // Import existing skills
409
- if (!args.noImport) {
410
- await cmdImport({ all: true, quiet: false });
411
- }
412
-
413
- // Install built-ins
432
+ // Install built-ins (safe local setup)
414
433
  await installBuiltins(agents);
415
434
 
435
+ const unmanaged = discoverUnmanaged(agents, loadState());
436
+
437
+ console.log('\nSetup complete.');
438
+ console.log('Next command: skills');
439
+ if (unmanaged.size > 0) {
440
+ console.log(`Optional publish step: skills import (found ${unmanaged.size} unmanaged local skill(s))`);
441
+ }
442
+
416
443
  console.log('\nReady! Ask your agent to "install a skill" or "create a new skill".');
417
444
  }
418
445
 
@@ -437,10 +464,9 @@ export async function cmdLogin(args) {
437
464
  console.log(` Your publish namespace is: ${me.org}/${me.user}/<skillname>`);
438
465
 
439
466
  // First-time setup guidance
440
- const st = loadState();
441
- const agents = detectAgents();
442
- const unmanaged = discoverUnmanaged(agents, st);
443
- const hasBuiltins = Object.keys(st.installed).some(id => id.startsWith('__builtin__/local/'));
467
+ const diag = getLocalDiagnostics();
468
+ const unmanaged = diag.unmanaged;
469
+ const hasBuiltins = diag.hasBuiltinsInstalled;
444
470
 
445
471
  if (!hasBuiltins || unmanaged.size > 0) {
446
472
  console.log('\nSetup not complete yet.');
@@ -449,12 +475,18 @@ export async function cmdLogin(args) {
449
475
 
450
476
  const doSetup = await promptYesNo('Run guided setup now? (recommended)', true);
451
477
  if (doSetup) {
452
- await cmdInit({ server: cfg.server, token: cfg.token, noImport: false });
478
+ await cmdInit({ server: cfg.server, token: cfg.token });
479
+ if (unmanaged.size > 0) {
480
+ const doImport = await promptYesNo('Import unmanaged local skills to registry now?', false);
481
+ if (doImport) {
482
+ await cmdImport({ all: true, quiet: false });
483
+ }
484
+ }
453
485
  return;
454
486
  }
455
487
 
456
488
  console.log('\nNext steps:');
457
- if (!hasBuiltins) console.log(' skills init --no-import');
489
+ if (!hasBuiltins) console.log(' skills init');
458
490
  if (unmanaged.size > 0) console.log(' skills import');
459
491
  }
460
492
  }
package/lib/startup.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { loadConfig, saveConfig } from './config.js';
2
- import { getLocalDiagnostics } from './skills.js';
2
+ import { ensureBuiltinsInstalled, getLocalDiagnostics } from './skills.js';
3
3
 
4
4
  function cmpSemver(a, b) {
5
5
  const pa = String(a || '').split('.').map(n => parseInt(n, 10) || 0);
@@ -52,6 +52,16 @@ async function runUpdateCheck(currentVersion, { silent = false } = {}) {
52
52
  }
53
53
  }
54
54
 
55
+ async function runAutoHeal(command, { jsonMode = false } = {}) {
56
+ if (process.env.SKILLS_NO_STARTUP_HEAL === '1') return;
57
+ if (['init'].includes(command)) return;
58
+
59
+ const result = await ensureBuiltinsInstalled({ quiet: true });
60
+ if (!jsonMode && result.changed) {
61
+ console.log(`✓ Startup heal: installed ${result.installed.length} missing built-in skill(s).`);
62
+ }
63
+ }
64
+
55
65
  function printSetupWarnings(command, startupInfo, { jsonMode = false } = {}) {
56
66
  if (jsonMode) return;
57
67
 
@@ -60,7 +70,7 @@ function printSetupWarnings(command, startupInfo, { jsonMode = false } = {}) {
60
70
 
61
71
  const warnings = [];
62
72
  if (!startupInfo.hasBuiltinsInstalled && startupInfo.bundledBuiltinsCount > 0) {
63
- warnings.push('Built-in skills are not installed. Run: skills init --no-import');
73
+ warnings.push('Built-in skills are not installed. Run: skills init');
64
74
  }
65
75
  if (startupInfo.unmanagedCount > 0) {
66
76
  warnings.push(`Found ${startupInfo.unmanagedCount} unmanaged local skill(s). Run: skills import`);
@@ -80,6 +90,7 @@ function printSetupWarnings(command, startupInfo, { jsonMode = false } = {}) {
80
90
 
81
91
  export async function runStartupChecks({ currentVersion, command, jsonMode = false }) {
82
92
  await runUpdateCheck(currentVersion, { silent: jsonMode });
93
+ await runAutoHeal(command, { jsonMode });
83
94
  const startupInfo = getLocalDiagnostics();
84
95
  printSetupWarnings(command, startupInfo, { jsonMode });
85
96
  return startupInfo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npeercy/skills",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "CLI-first skill marketplace for coding agents",
5
5
  "type": "module",
6
6
  "bin": {