@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 +10 -47
- package/lib/skills.js +20 -0
- package/lib/startup.js +86 -0
- package/package.json +1 -1
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 {
|
|
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
|
|
55
|
-
|
|
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
|
|
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
|
-
|
|
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
|
+
}
|