@npeercy/skills 0.1.6 → 0.1.7

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
@@ -9,7 +9,7 @@ import {
9
9
  cmdEdit, cmdValidate, cmdPublish, cmdImport, cmdDoctor,
10
10
  cmdShare, cmdUnshare, cmdVisibility,
11
11
  } from '../lib/skills.js';
12
- import { loadConfig, saveConfig } from '../lib/config.js';
12
+ import { runStartupChecks } from '../lib/startup.js';
13
13
 
14
14
  const USAGE = `skill-sharer — CLI skill manager for coding agents
15
15
 
@@ -51,49 +51,8 @@ const PKG = JSON.parse(
51
51
  readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8')
52
52
  );
53
53
 
54
- function cmpSemver(a, b) {
55
- const pa = String(a || '').split('.').map(n => parseInt(n, 10) || 0);
56
- const pb = String(b || '').split('.').map(n => parseInt(n, 10) || 0);
57
- const len = Math.max(pa.length, pb.length);
58
- for (let i = 0; i < len; i++) {
59
- const da = pa[i] || 0;
60
- const db = pb[i] || 0;
61
- if (da > db) return 1;
62
- if (da < db) return -1;
63
- }
64
- return 0;
65
- }
66
-
67
- async function maybeWarnOutdated() {
68
- if (process.env.SKILLS_NO_UPDATE_CHECK === '1') return;
69
-
70
- const cfg = loadConfig();
71
- const now = Date.now();
72
- const oneDayMs = 24 * 60 * 60 * 1000;
73
- const lastChecked = cfg.updateCheck?.lastChecked ? Date.parse(cfg.updateCheck.lastChecked) : 0;
74
- let latest = cfg.updateCheck?.latestVersion || '';
75
-
76
- if (!lastChecked || now - lastChecked > oneDayMs || !latest) {
77
- try {
78
- const res = await fetch('https://registry.npmjs.org/@npeercy%2fskills/latest');
79
- if (res.ok) {
80
- const data = await res.json();
81
- latest = data.version || latest;
82
- cfg.updateCheck = {
83
- lastChecked: new Date(now).toISOString(),
84
- latestVersion: latest,
85
- };
86
- saveConfig(cfg);
87
- }
88
- } catch {
89
- // Silent fail; command should continue even offline.
90
- }
91
- }
92
-
93
- if (latest && cmpSemver(latest, PKG.version) > 0) {
94
- console.log(`⚠ Update available: @npeercy/skills ${PKG.version} → ${latest}`);
95
- console.log(' Run: npm install -g @npeercy/skills\n');
96
- }
54
+ function hasJsonFlag(args) {
55
+ return args.includes('--json');
97
56
  }
98
57
 
99
58
  async function main() {
@@ -101,20 +60,24 @@ async function main() {
101
60
 
102
61
  // `skills` by itself -> list all local skills (managed + unmanaged + bundled)
103
62
  if (args.length === 0) {
104
- await maybeWarnOutdated();
63
+ await runStartupChecks({ currentVersion: PKG.version, command: 'list', jsonMode: false });
105
64
  await cmdList({ verify: false, outdated: false, json: false });
106
65
  return;
107
66
  }
108
67
 
109
68
  if (args[0] === '--help' || args[0] === '-h') {
69
+ await runStartupChecks({ currentVersion: PKG.version, command: 'help', jsonMode: false });
110
70
  console.log(USAGE);
111
71
  return;
112
72
  }
113
73
 
114
74
  const cmd = args[0];
115
75
  const rest = args.slice(1);
116
-
117
- await maybeWarnOutdated();
76
+ await runStartupChecks({
77
+ currentVersion: PKG.version,
78
+ command: cmd,
79
+ jsonMode: cmd === 'list' && hasJsonFlag(rest),
80
+ });
118
81
 
119
82
  try {
120
83
  switch (cmd) {
package/lib/skills.js CHANGED
@@ -255,6 +255,26 @@ function bundledBuiltins() {
255
255
  return out;
256
256
  }
257
257
 
258
+ export function getLocalDiagnostics() {
259
+ const st = loadState();
260
+ const agents = detectAgents();
261
+ const bundled = bundledBuiltins();
262
+ const unmanaged = discoverUnmanaged(agents, st);
263
+ const conflicts = discoverAgentNameConflicts(agents);
264
+
265
+ return {
266
+ state: st,
267
+ agents,
268
+ managedCount: Object.keys(st.installed).length,
269
+ bundledBuiltinsCount: bundled.length,
270
+ hasBuiltinsInstalled: Object.keys(st.installed).some(id => id.startsWith('__builtin__/local/')),
271
+ unmanagedCount: unmanaged.size,
272
+ conflictCount: conflicts.length,
273
+ unmanaged,
274
+ conflicts,
275
+ };
276
+ }
277
+
258
278
  async function installBuiltins(agents) {
259
279
  const st = loadState();
260
280
 
package/lib/startup.js ADDED
@@ -0,0 +1,86 @@
1
+ import { loadConfig, saveConfig } from './config.js';
2
+ import { getLocalDiagnostics } from './skills.js';
3
+
4
+ function cmpSemver(a, b) {
5
+ const pa = String(a || '').split('.').map(n => parseInt(n, 10) || 0);
6
+ const pb = String(b || '').split('.').map(n => parseInt(n, 10) || 0);
7
+ const len = Math.max(pa.length, pb.length);
8
+ for (let i = 0; i < len; i++) {
9
+ const da = pa[i] || 0;
10
+ const db = pb[i] || 0;
11
+ if (da > db) return 1;
12
+ if (da < db) return -1;
13
+ }
14
+ return 0;
15
+ }
16
+
17
+ async function latestPublishedVersion() {
18
+ const controller = new AbortController();
19
+ const timeout = setTimeout(() => controller.abort(), 2500);
20
+ try {
21
+ const res = await fetch('https://registry.npmjs.org/@npeercy%2fskills/latest', {
22
+ signal: controller.signal,
23
+ });
24
+ if (!res.ok) return '';
25
+ const data = await res.json();
26
+ return data.version || '';
27
+ } catch {
28
+ return '';
29
+ } finally {
30
+ clearTimeout(timeout);
31
+ }
32
+ }
33
+
34
+ async function runUpdateCheck(currentVersion, { silent = false } = {}) {
35
+ if (process.env.SKILLS_NO_UPDATE_CHECK === '1') return;
36
+
37
+ const cfg = loadConfig();
38
+ const latestLive = await latestPublishedVersion();
39
+ const latest = latestLive || cfg.updateCheck?.latestVersion || '';
40
+
41
+ if (latestLive) {
42
+ cfg.updateCheck = {
43
+ lastChecked: new Date().toISOString(),
44
+ latestVersion: latestLive,
45
+ };
46
+ saveConfig(cfg);
47
+ }
48
+
49
+ if (!silent && latest && cmpSemver(latest, currentVersion) > 0) {
50
+ console.log(`⚠ Update available: @npeercy/skills ${currentVersion} → ${latest}`);
51
+ console.log(' Run: npm install -g @npeercy/skills\n');
52
+ }
53
+ }
54
+
55
+ function printSetupWarnings(command, startupInfo, { jsonMode = false } = {}) {
56
+ if (jsonMode) return;
57
+
58
+ // Avoid noisy preflight banner for direct setup/auth commands.
59
+ if (['init', 'login'].includes(command)) return;
60
+
61
+ const warnings = [];
62
+ if (!startupInfo.hasBuiltinsInstalled && startupInfo.bundledBuiltinsCount > 0) {
63
+ warnings.push('Built-in skills are not installed. Run: skills init --no-import');
64
+ }
65
+ if (startupInfo.unmanagedCount > 0) {
66
+ warnings.push(`Found ${startupInfo.unmanagedCount} unmanaged local skill(s). Run: skills import`);
67
+ }
68
+ if (startupInfo.conflictCount > 0) {
69
+ warnings.push(`Found ${startupInfo.conflictCount} duplicate skill-name conflict(s). Run: skills doctor`);
70
+ }
71
+
72
+ if (warnings.length > 0) {
73
+ console.log('⚠ Startup checks:');
74
+ for (const w of warnings) {
75
+ console.log(` - ${w}`);
76
+ }
77
+ console.log('');
78
+ }
79
+ }
80
+
81
+ export async function runStartupChecks({ currentVersion, command, jsonMode = false }) {
82
+ await runUpdateCheck(currentVersion, { silent: jsonMode });
83
+ const startupInfo = getLocalDiagnostics();
84
+ printSetupWarnings(command, startupInfo, { jsonMode });
85
+ return startupInfo;
86
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npeercy/skills",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "CLI-first skill marketplace for coding agents",
5
5
  "type": "module",
6
6
  "bin": {