@skillkit/core 1.7.6 → 1.7.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/dist/index.d.ts +97 -8
- package/dist/index.js +1038 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17,7 +17,22 @@ var AgentType = z.enum([
|
|
|
17
17
|
"roo",
|
|
18
18
|
"trae",
|
|
19
19
|
"windsurf",
|
|
20
|
-
"universal"
|
|
20
|
+
"universal",
|
|
21
|
+
"cline",
|
|
22
|
+
"codebuddy",
|
|
23
|
+
"commandcode",
|
|
24
|
+
"continue",
|
|
25
|
+
"crush",
|
|
26
|
+
"factory",
|
|
27
|
+
"mcpjam",
|
|
28
|
+
"mux",
|
|
29
|
+
"neovate",
|
|
30
|
+
"openhands",
|
|
31
|
+
"pi",
|
|
32
|
+
"qoder",
|
|
33
|
+
"qwen",
|
|
34
|
+
"vercel",
|
|
35
|
+
"zencoder"
|
|
21
36
|
]);
|
|
22
37
|
var GitProvider = z.enum(["github", "gitlab", "bitbucket", "local"]);
|
|
23
38
|
var SkillFrontmatter = z.object({
|
|
@@ -233,6 +248,127 @@ var AGENT_CONFIG = {
|
|
|
233
248
|
configFormat: "xml",
|
|
234
249
|
usesFrontmatter: true,
|
|
235
250
|
supportsAutoDiscovery: true
|
|
251
|
+
},
|
|
252
|
+
// Cline
|
|
253
|
+
cline: {
|
|
254
|
+
skillsDir: ".cline/skills",
|
|
255
|
+
configFile: "AGENTS.md",
|
|
256
|
+
configFormat: "xml",
|
|
257
|
+
usesFrontmatter: true,
|
|
258
|
+
supportsAutoDiscovery: true
|
|
259
|
+
},
|
|
260
|
+
// Codebuddy
|
|
261
|
+
codebuddy: {
|
|
262
|
+
skillsDir: ".codebuddy/skills",
|
|
263
|
+
configFile: "AGENTS.md",
|
|
264
|
+
configFormat: "xml",
|
|
265
|
+
usesFrontmatter: true,
|
|
266
|
+
supportsAutoDiscovery: true
|
|
267
|
+
},
|
|
268
|
+
// Commandcode
|
|
269
|
+
commandcode: {
|
|
270
|
+
skillsDir: ".commandcode/skills",
|
|
271
|
+
configFile: "AGENTS.md",
|
|
272
|
+
configFormat: "xml",
|
|
273
|
+
usesFrontmatter: true,
|
|
274
|
+
supportsAutoDiscovery: true
|
|
275
|
+
},
|
|
276
|
+
// Continue
|
|
277
|
+
continue: {
|
|
278
|
+
skillsDir: ".continue/skills",
|
|
279
|
+
configFile: "AGENTS.md",
|
|
280
|
+
globalSkillsDir: "~/.continue/skills",
|
|
281
|
+
configFormat: "xml",
|
|
282
|
+
usesFrontmatter: true,
|
|
283
|
+
supportsAutoDiscovery: true
|
|
284
|
+
},
|
|
285
|
+
// Crush
|
|
286
|
+
crush: {
|
|
287
|
+
skillsDir: ".crush/skills",
|
|
288
|
+
configFile: "AGENTS.md",
|
|
289
|
+
configFormat: "xml",
|
|
290
|
+
usesFrontmatter: true,
|
|
291
|
+
supportsAutoDiscovery: true
|
|
292
|
+
},
|
|
293
|
+
// Factory
|
|
294
|
+
factory: {
|
|
295
|
+
skillsDir: ".factory/skills",
|
|
296
|
+
configFile: "AGENTS.md",
|
|
297
|
+
configFormat: "xml",
|
|
298
|
+
usesFrontmatter: true,
|
|
299
|
+
supportsAutoDiscovery: true
|
|
300
|
+
},
|
|
301
|
+
// MCPJam
|
|
302
|
+
mcpjam: {
|
|
303
|
+
skillsDir: ".mcpjam/skills",
|
|
304
|
+
configFile: "AGENTS.md",
|
|
305
|
+
configFormat: "xml",
|
|
306
|
+
usesFrontmatter: true,
|
|
307
|
+
supportsAutoDiscovery: true
|
|
308
|
+
},
|
|
309
|
+
// Mux
|
|
310
|
+
mux: {
|
|
311
|
+
skillsDir: ".mux/skills",
|
|
312
|
+
configFile: "AGENTS.md",
|
|
313
|
+
configFormat: "xml",
|
|
314
|
+
usesFrontmatter: true,
|
|
315
|
+
supportsAutoDiscovery: true
|
|
316
|
+
},
|
|
317
|
+
// Neovate
|
|
318
|
+
neovate: {
|
|
319
|
+
skillsDir: ".neovate/skills",
|
|
320
|
+
configFile: "AGENTS.md",
|
|
321
|
+
configFormat: "xml",
|
|
322
|
+
usesFrontmatter: true,
|
|
323
|
+
supportsAutoDiscovery: true
|
|
324
|
+
},
|
|
325
|
+
// OpenHands
|
|
326
|
+
openhands: {
|
|
327
|
+
skillsDir: ".openhands/skills",
|
|
328
|
+
configFile: "AGENTS.md",
|
|
329
|
+
configFormat: "xml",
|
|
330
|
+
usesFrontmatter: true,
|
|
331
|
+
supportsAutoDiscovery: true
|
|
332
|
+
},
|
|
333
|
+
// Pi
|
|
334
|
+
pi: {
|
|
335
|
+
skillsDir: ".pi/skills",
|
|
336
|
+
configFile: "AGENTS.md",
|
|
337
|
+
configFormat: "xml",
|
|
338
|
+
usesFrontmatter: true,
|
|
339
|
+
supportsAutoDiscovery: true
|
|
340
|
+
},
|
|
341
|
+
// Qoder
|
|
342
|
+
qoder: {
|
|
343
|
+
skillsDir: ".qoder/skills",
|
|
344
|
+
configFile: "AGENTS.md",
|
|
345
|
+
configFormat: "xml",
|
|
346
|
+
usesFrontmatter: true,
|
|
347
|
+
supportsAutoDiscovery: true
|
|
348
|
+
},
|
|
349
|
+
// Qwen
|
|
350
|
+
qwen: {
|
|
351
|
+
skillsDir: ".qwen/skills",
|
|
352
|
+
configFile: "AGENTS.md",
|
|
353
|
+
configFormat: "xml",
|
|
354
|
+
usesFrontmatter: true,
|
|
355
|
+
supportsAutoDiscovery: true
|
|
356
|
+
},
|
|
357
|
+
// Vercel
|
|
358
|
+
vercel: {
|
|
359
|
+
skillsDir: ".vercel/skills",
|
|
360
|
+
configFile: "AGENTS.md",
|
|
361
|
+
configFormat: "xml",
|
|
362
|
+
usesFrontmatter: true,
|
|
363
|
+
supportsAutoDiscovery: true
|
|
364
|
+
},
|
|
365
|
+
// Zencoder
|
|
366
|
+
zencoder: {
|
|
367
|
+
skillsDir: ".zencoder/skills",
|
|
368
|
+
configFile: "AGENTS.md",
|
|
369
|
+
configFormat: "xml",
|
|
370
|
+
usesFrontmatter: true,
|
|
371
|
+
supportsAutoDiscovery: true
|
|
236
372
|
}
|
|
237
373
|
};
|
|
238
374
|
function getAgentDirectoryConfig(agent) {
|
|
@@ -271,10 +407,20 @@ var SKILL_DISCOVERY_PATHS = [
|
|
|
271
407
|
"skills/.curated",
|
|
272
408
|
"skills/.experimental",
|
|
273
409
|
"skills/.system",
|
|
410
|
+
"agents",
|
|
274
411
|
".agents/skills",
|
|
275
412
|
".agent/skills",
|
|
413
|
+
".amp/skills",
|
|
414
|
+
".antigravity/skills",
|
|
276
415
|
".claude/skills",
|
|
416
|
+
".cline/skills",
|
|
417
|
+
".clawdbot/skills",
|
|
418
|
+
".codebuddy/skills",
|
|
277
419
|
".codex/skills",
|
|
420
|
+
".commandcode/skills",
|
|
421
|
+
".continue/skills",
|
|
422
|
+
".copilot/skills",
|
|
423
|
+
".crush/skills",
|
|
278
424
|
".cursor/skills",
|
|
279
425
|
".factory/skills",
|
|
280
426
|
".gemini/skills",
|
|
@@ -282,13 +428,19 @@ var SKILL_DISCOVERY_PATHS = [
|
|
|
282
428
|
".goose/skills",
|
|
283
429
|
".kilocode/skills",
|
|
284
430
|
".kiro/skills",
|
|
431
|
+
".mcpjam/skills",
|
|
432
|
+
".mux/skills",
|
|
433
|
+
".neovate/skills",
|
|
285
434
|
".opencode/skills",
|
|
435
|
+
".openhands/skills",
|
|
436
|
+
".pi/skills",
|
|
437
|
+
".qoder/skills",
|
|
438
|
+
".qwen/skills",
|
|
286
439
|
".roo/skills",
|
|
287
440
|
".trae/skills",
|
|
441
|
+
".vercel/skills",
|
|
288
442
|
".windsurf/skills",
|
|
289
|
-
".
|
|
290
|
-
".antigravity/skills",
|
|
291
|
-
".copilot/skills"
|
|
443
|
+
".zencoder/skills"
|
|
292
444
|
];
|
|
293
445
|
function discoverSkillsInDir(dir) {
|
|
294
446
|
const skills = [];
|
|
@@ -297,11 +449,17 @@ function discoverSkillsInDir(dir) {
|
|
|
297
449
|
}
|
|
298
450
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
299
451
|
for (const entry of entries) {
|
|
300
|
-
if (
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
452
|
+
if (entry.isDirectory()) {
|
|
453
|
+
const skillPath = join(dir, entry.name);
|
|
454
|
+
const skillMdPath = join(skillPath, "SKILL.md");
|
|
455
|
+
if (existsSync(skillMdPath)) {
|
|
456
|
+
const skill = parseSkill(skillPath);
|
|
457
|
+
if (skill) {
|
|
458
|
+
skills.push(skill);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
} else if (entry.isFile() && entry.name.endsWith(".md") && entry.name !== "README.md") {
|
|
462
|
+
const skill = parseStandaloneSkill(join(dir, entry.name));
|
|
305
463
|
if (skill) {
|
|
306
464
|
skills.push(skill);
|
|
307
465
|
}
|
|
@@ -309,6 +467,32 @@ function discoverSkillsInDir(dir) {
|
|
|
309
467
|
}
|
|
310
468
|
return skills;
|
|
311
469
|
}
|
|
470
|
+
function parseStandaloneSkill(filePath, location = "project") {
|
|
471
|
+
if (!existsSync(filePath)) {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
const content = readFileSync(filePath, "utf-8");
|
|
476
|
+
const frontmatter = extractFrontmatter(content);
|
|
477
|
+
if (!frontmatter) {
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
const name = frontmatter.name || basename(filePath, ".md");
|
|
481
|
+
const description = frontmatter.description || "No description available";
|
|
482
|
+
if (!name || name.length === 0) {
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
return {
|
|
486
|
+
name,
|
|
487
|
+
description,
|
|
488
|
+
path: filePath,
|
|
489
|
+
location,
|
|
490
|
+
enabled: true
|
|
491
|
+
};
|
|
492
|
+
} catch {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
312
496
|
function discoverSkillsRecursive(dir, seen, maxDepth = 5, currentDepth = 0) {
|
|
313
497
|
const skills = [];
|
|
314
498
|
if (currentDepth >= maxDepth || !existsSync(dir)) {
|
|
@@ -320,18 +504,25 @@ function discoverSkillsRecursive(dir, seen, maxDepth = 5, currentDepth = 0) {
|
|
|
320
504
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
321
505
|
continue;
|
|
322
506
|
}
|
|
323
|
-
if (!entry.isDirectory()) continue;
|
|
324
507
|
const entryPath = join(dir, entry.name);
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
508
|
+
if (entry.isDirectory()) {
|
|
509
|
+
const skillMdPath = join(entryPath, "SKILL.md");
|
|
510
|
+
if (existsSync(skillMdPath)) {
|
|
511
|
+
const skill = parseSkill(entryPath);
|
|
512
|
+
if (skill && !seen.has(skill.name)) {
|
|
513
|
+
seen.add(skill.name);
|
|
514
|
+
skills.push(skill);
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
const subSkills = discoverSkillsRecursive(entryPath, seen, maxDepth, currentDepth + 1);
|
|
518
|
+
skills.push(...subSkills);
|
|
519
|
+
}
|
|
520
|
+
} else if (entry.isFile() && entry.name.endsWith(".md") && entry.name !== "README.md") {
|
|
521
|
+
const skill = parseStandaloneSkill(entryPath);
|
|
328
522
|
if (skill && !seen.has(skill.name)) {
|
|
329
523
|
seen.add(skill.name);
|
|
330
524
|
skills.push(skill);
|
|
331
525
|
}
|
|
332
|
-
} else {
|
|
333
|
-
const subSkills = discoverSkillsRecursive(entryPath, seen, maxDepth, currentDepth + 1);
|
|
334
|
-
skills.push(...subSkills);
|
|
335
526
|
}
|
|
336
527
|
}
|
|
337
528
|
} catch {
|
|
@@ -446,7 +637,7 @@ function loadMetadata(skillPath) {
|
|
|
446
637
|
}
|
|
447
638
|
}
|
|
448
639
|
function readSkillContent(skillPath) {
|
|
449
|
-
const skillMdPath = join(skillPath, "SKILL.md");
|
|
640
|
+
const skillMdPath = skillPath.endsWith(".md") ? skillPath : join(skillPath, "SKILL.md");
|
|
450
641
|
if (!existsSync(skillMdPath)) {
|
|
451
642
|
return null;
|
|
452
643
|
}
|
|
@@ -486,8 +677,9 @@ function findAllSkills(searchDirs) {
|
|
|
486
677
|
function validateSkill(skillPath) {
|
|
487
678
|
const errors = [];
|
|
488
679
|
const warnings = [];
|
|
489
|
-
const
|
|
490
|
-
const
|
|
680
|
+
const isStandalone = skillPath.endsWith(".md");
|
|
681
|
+
const dirName = isStandalone ? basename(skillPath, ".md") : basename(skillPath);
|
|
682
|
+
const skillMdPath = isStandalone ? skillPath : join(skillPath, "SKILL.md");
|
|
491
683
|
if (!existsSync(skillMdPath)) {
|
|
492
684
|
errors.push("Missing SKILL.md file");
|
|
493
685
|
return { valid: false, errors };
|
|
@@ -1033,7 +1225,22 @@ var AGENT_FORMAT_MAP = {
|
|
|
1033
1225
|
"universal": "skill-md",
|
|
1034
1226
|
"cursor": "cursor-mdc",
|
|
1035
1227
|
"windsurf": "markdown-rules",
|
|
1036
|
-
"github-copilot": "markdown-rules"
|
|
1228
|
+
"github-copilot": "markdown-rules",
|
|
1229
|
+
"cline": "skill-md",
|
|
1230
|
+
"codebuddy": "skill-md",
|
|
1231
|
+
"commandcode": "skill-md",
|
|
1232
|
+
"continue": "skill-md",
|
|
1233
|
+
"crush": "skill-md",
|
|
1234
|
+
"factory": "skill-md",
|
|
1235
|
+
"mcpjam": "skill-md",
|
|
1236
|
+
"mux": "skill-md",
|
|
1237
|
+
"neovate": "skill-md",
|
|
1238
|
+
"openhands": "skill-md",
|
|
1239
|
+
"pi": "skill-md",
|
|
1240
|
+
"qoder": "skill-md",
|
|
1241
|
+
"qwen": "skill-md",
|
|
1242
|
+
"vercel": "skill-md",
|
|
1243
|
+
"zencoder": "skill-md"
|
|
1037
1244
|
};
|
|
1038
1245
|
var TranslatableSkillFrontmatter = z2.object({
|
|
1039
1246
|
name: z2.string(),
|
|
@@ -15094,6 +15301,111 @@ var AGENT_FORMATS = {
|
|
|
15094
15301
|
directory: "commands",
|
|
15095
15302
|
supportsSlashCommands: true,
|
|
15096
15303
|
supportsCommandFiles: true
|
|
15304
|
+
},
|
|
15305
|
+
cline: {
|
|
15306
|
+
agent: "cline",
|
|
15307
|
+
extension: ".md",
|
|
15308
|
+
directory: ".cline/commands",
|
|
15309
|
+
supportsSlashCommands: true,
|
|
15310
|
+
supportsCommandFiles: true
|
|
15311
|
+
},
|
|
15312
|
+
codebuddy: {
|
|
15313
|
+
agent: "codebuddy",
|
|
15314
|
+
extension: ".md",
|
|
15315
|
+
directory: ".codebuddy/commands",
|
|
15316
|
+
supportsSlashCommands: true,
|
|
15317
|
+
supportsCommandFiles: true
|
|
15318
|
+
},
|
|
15319
|
+
commandcode: {
|
|
15320
|
+
agent: "commandcode",
|
|
15321
|
+
extension: ".md",
|
|
15322
|
+
directory: ".commandcode/commands",
|
|
15323
|
+
supportsSlashCommands: true,
|
|
15324
|
+
supportsCommandFiles: true
|
|
15325
|
+
},
|
|
15326
|
+
continue: {
|
|
15327
|
+
agent: "continue",
|
|
15328
|
+
extension: ".md",
|
|
15329
|
+
directory: ".continue/commands",
|
|
15330
|
+
supportsSlashCommands: true,
|
|
15331
|
+
supportsCommandFiles: true
|
|
15332
|
+
},
|
|
15333
|
+
crush: {
|
|
15334
|
+
agent: "crush",
|
|
15335
|
+
extension: ".md",
|
|
15336
|
+
directory: ".crush/commands",
|
|
15337
|
+
supportsSlashCommands: true,
|
|
15338
|
+
supportsCommandFiles: true
|
|
15339
|
+
},
|
|
15340
|
+
factory: {
|
|
15341
|
+
agent: "factory",
|
|
15342
|
+
extension: ".md",
|
|
15343
|
+
directory: ".factory/commands",
|
|
15344
|
+
supportsSlashCommands: true,
|
|
15345
|
+
supportsCommandFiles: true
|
|
15346
|
+
},
|
|
15347
|
+
mcpjam: {
|
|
15348
|
+
agent: "mcpjam",
|
|
15349
|
+
extension: ".md",
|
|
15350
|
+
directory: ".mcpjam/commands",
|
|
15351
|
+
supportsSlashCommands: true,
|
|
15352
|
+
supportsCommandFiles: true
|
|
15353
|
+
},
|
|
15354
|
+
mux: {
|
|
15355
|
+
agent: "mux",
|
|
15356
|
+
extension: ".md",
|
|
15357
|
+
directory: ".mux/commands",
|
|
15358
|
+
supportsSlashCommands: true,
|
|
15359
|
+
supportsCommandFiles: true
|
|
15360
|
+
},
|
|
15361
|
+
neovate: {
|
|
15362
|
+
agent: "neovate",
|
|
15363
|
+
extension: ".md",
|
|
15364
|
+
directory: ".neovate/commands",
|
|
15365
|
+
supportsSlashCommands: true,
|
|
15366
|
+
supportsCommandFiles: true
|
|
15367
|
+
},
|
|
15368
|
+
openhands: {
|
|
15369
|
+
agent: "openhands",
|
|
15370
|
+
extension: ".md",
|
|
15371
|
+
directory: ".openhands/commands",
|
|
15372
|
+
supportsSlashCommands: true,
|
|
15373
|
+
supportsCommandFiles: true
|
|
15374
|
+
},
|
|
15375
|
+
pi: {
|
|
15376
|
+
agent: "pi",
|
|
15377
|
+
extension: ".md",
|
|
15378
|
+
directory: ".pi/commands",
|
|
15379
|
+
supportsSlashCommands: true,
|
|
15380
|
+
supportsCommandFiles: true
|
|
15381
|
+
},
|
|
15382
|
+
qoder: {
|
|
15383
|
+
agent: "qoder",
|
|
15384
|
+
extension: ".md",
|
|
15385
|
+
directory: ".qoder/commands",
|
|
15386
|
+
supportsSlashCommands: true,
|
|
15387
|
+
supportsCommandFiles: true
|
|
15388
|
+
},
|
|
15389
|
+
qwen: {
|
|
15390
|
+
agent: "qwen",
|
|
15391
|
+
extension: ".md",
|
|
15392
|
+
directory: ".qwen/commands",
|
|
15393
|
+
supportsSlashCommands: true,
|
|
15394
|
+
supportsCommandFiles: true
|
|
15395
|
+
},
|
|
15396
|
+
vercel: {
|
|
15397
|
+
agent: "vercel",
|
|
15398
|
+
extension: ".md",
|
|
15399
|
+
directory: ".vercel/commands",
|
|
15400
|
+
supportsSlashCommands: true,
|
|
15401
|
+
supportsCommandFiles: true
|
|
15402
|
+
},
|
|
15403
|
+
zencoder: {
|
|
15404
|
+
agent: "zencoder",
|
|
15405
|
+
extension: ".md",
|
|
15406
|
+
directory: ".zencoder/commands",
|
|
15407
|
+
supportsSlashCommands: true,
|
|
15408
|
+
supportsCommandFiles: true
|
|
15097
15409
|
}
|
|
15098
15410
|
};
|
|
15099
15411
|
var CommandGenerator = class {
|
|
@@ -16086,7 +16398,7 @@ var AGENT_DISCOVERY_PATHS = {
|
|
|
16086
16398
|
"antigravity": [".antigravity/agents"],
|
|
16087
16399
|
"amp": [".amp/agents"],
|
|
16088
16400
|
"clawdbot": [".clawdbot/agents", "agents"],
|
|
16089
|
-
"droid": [".
|
|
16401
|
+
"droid": [".droid/agents"],
|
|
16090
16402
|
"github-copilot": [".github/agents", ".github/instructions", ".github/custom-agents"],
|
|
16091
16403
|
"goose": [".goose/agents"],
|
|
16092
16404
|
"kilo": [".kilocode/agents", ".kilocode/modes"],
|
|
@@ -16094,22 +16406,41 @@ var AGENT_DISCOVERY_PATHS = {
|
|
|
16094
16406
|
"roo": [".roo/agents", ".roo/modes"],
|
|
16095
16407
|
"trae": [".trae/agents", ".trae/agent"],
|
|
16096
16408
|
"windsurf": [".windsurf/agents", ".windsurf/workflows"],
|
|
16097
|
-
"universal": ["agents", ".agents"]
|
|
16409
|
+
"universal": ["agents", ".agents"],
|
|
16410
|
+
"cline": [".cline/agents"],
|
|
16411
|
+
"codebuddy": [".codebuddy/agents"],
|
|
16412
|
+
"commandcode": [".commandcode/agents"],
|
|
16413
|
+
"continue": [".continue/agents"],
|
|
16414
|
+
"crush": [".crush/agents"],
|
|
16415
|
+
"factory": [".factory/agents"],
|
|
16416
|
+
"mcpjam": [".mcpjam/agents"],
|
|
16417
|
+
"mux": [".mux/agents"],
|
|
16418
|
+
"neovate": [".neovate/agents"],
|
|
16419
|
+
"openhands": [".openhands/agents"],
|
|
16420
|
+
"pi": [".pi/agents"],
|
|
16421
|
+
"qoder": [".qoder/agents"],
|
|
16422
|
+
"qwen": [".qwen/agents"],
|
|
16423
|
+
"vercel": [".vercel/agents"],
|
|
16424
|
+
"zencoder": [".zencoder/agents"]
|
|
16098
16425
|
};
|
|
16099
16426
|
var ALL_AGENT_DISCOVERY_PATHS = [
|
|
16100
16427
|
"agents",
|
|
16101
16428
|
".agents",
|
|
16429
|
+
".amp/agents",
|
|
16430
|
+
".antigravity/agents",
|
|
16102
16431
|
".claude/agents",
|
|
16432
|
+
".cline/agents",
|
|
16433
|
+
".clawdbot/agents",
|
|
16434
|
+
".codebuddy/agents",
|
|
16435
|
+
".codex/agents",
|
|
16436
|
+
".commandcode/agents",
|
|
16437
|
+
".continue/agents",
|
|
16438
|
+
".crush/agents",
|
|
16103
16439
|
".cursor/agents",
|
|
16104
16440
|
".cursor/commands",
|
|
16105
|
-
".
|
|
16106
|
-
".gemini/agents",
|
|
16107
|
-
".opencode/agents",
|
|
16108
|
-
".opencode/agent",
|
|
16109
|
-
".antigravity/agents",
|
|
16110
|
-
".amp/agents",
|
|
16111
|
-
".clawdbot/agents",
|
|
16441
|
+
".droid/agents",
|
|
16112
16442
|
".factory/agents",
|
|
16443
|
+
".gemini/agents",
|
|
16113
16444
|
".github/agents",
|
|
16114
16445
|
".github/instructions",
|
|
16115
16446
|
".github/custom-agents",
|
|
@@ -16117,12 +16448,23 @@ var ALL_AGENT_DISCOVERY_PATHS = [
|
|
|
16117
16448
|
".kilocode/agents",
|
|
16118
16449
|
".kilocode/modes",
|
|
16119
16450
|
".kiro/agents",
|
|
16451
|
+
".mcpjam/agents",
|
|
16452
|
+
".mux/agents",
|
|
16453
|
+
".neovate/agents",
|
|
16454
|
+
".opencode/agents",
|
|
16455
|
+
".opencode/agent",
|
|
16456
|
+
".openhands/agents",
|
|
16457
|
+
".pi/agents",
|
|
16458
|
+
".qoder/agents",
|
|
16459
|
+
".qwen/agents",
|
|
16120
16460
|
".roo/agents",
|
|
16121
16461
|
".roo/modes",
|
|
16122
16462
|
".trae/agents",
|
|
16123
16463
|
".trae/agent",
|
|
16464
|
+
".vercel/agents",
|
|
16124
16465
|
".windsurf/agents",
|
|
16125
|
-
".windsurf/workflows"
|
|
16466
|
+
".windsurf/workflows",
|
|
16467
|
+
".zencoder/agents"
|
|
16126
16468
|
];
|
|
16127
16469
|
var CUSTOM_AGENT_FORMAT_MAP = {
|
|
16128
16470
|
"claude-code": "claude-agent",
|
|
@@ -16141,7 +16483,22 @@ var CUSTOM_AGENT_FORMAT_MAP = {
|
|
|
16141
16483
|
"roo": "claude-agent",
|
|
16142
16484
|
"trae": "claude-agent",
|
|
16143
16485
|
"windsurf": "universal",
|
|
16144
|
-
"universal": "universal"
|
|
16486
|
+
"universal": "universal",
|
|
16487
|
+
"cline": "claude-agent",
|
|
16488
|
+
"codebuddy": "claude-agent",
|
|
16489
|
+
"commandcode": "claude-agent",
|
|
16490
|
+
"continue": "claude-agent",
|
|
16491
|
+
"crush": "claude-agent",
|
|
16492
|
+
"factory": "claude-agent",
|
|
16493
|
+
"mcpjam": "claude-agent",
|
|
16494
|
+
"mux": "claude-agent",
|
|
16495
|
+
"neovate": "claude-agent",
|
|
16496
|
+
"openhands": "claude-agent",
|
|
16497
|
+
"pi": "claude-agent",
|
|
16498
|
+
"qoder": "claude-agent",
|
|
16499
|
+
"qwen": "claude-agent",
|
|
16500
|
+
"vercel": "claude-agent",
|
|
16501
|
+
"zencoder": "claude-agent"
|
|
16145
16502
|
};
|
|
16146
16503
|
|
|
16147
16504
|
// src/agents/parser.ts
|
|
@@ -17522,6 +17879,643 @@ function generateManifestFromInstalled(installedSkills) {
|
|
|
17522
17879
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17523
17880
|
};
|
|
17524
17881
|
}
|
|
17882
|
+
|
|
17883
|
+
// src/quality/index.ts
|
|
17884
|
+
import { readFileSync as readFileSync26, existsSync as existsSync34 } from "fs";
|
|
17885
|
+
import { join as join35, basename as basename12 } from "path";
|
|
17886
|
+
|
|
17887
|
+
// src/quality/benchmark.ts
|
|
17888
|
+
var CATEGORY_BENCHMARKS = {
|
|
17889
|
+
react: {
|
|
17890
|
+
category: "react",
|
|
17891
|
+
avgScore: 78,
|
|
17892
|
+
topScore: 95,
|
|
17893
|
+
topSkills: ["react-patterns", "react-hooks-best-practices"],
|
|
17894
|
+
count: 150,
|
|
17895
|
+
distribution: { A: 15, B: 35, C: 30, D: 15, F: 5 }
|
|
17896
|
+
},
|
|
17897
|
+
typescript: {
|
|
17898
|
+
category: "typescript",
|
|
17899
|
+
avgScore: 75,
|
|
17900
|
+
topScore: 92,
|
|
17901
|
+
topSkills: ["typescript-strict", "type-safety-patterns"],
|
|
17902
|
+
count: 120,
|
|
17903
|
+
distribution: { A: 12, B: 30, C: 35, D: 18, F: 5 }
|
|
17904
|
+
},
|
|
17905
|
+
testing: {
|
|
17906
|
+
category: "testing",
|
|
17907
|
+
avgScore: 72,
|
|
17908
|
+
topScore: 90,
|
|
17909
|
+
topSkills: ["tdd-workflow", "testing-best-practices"],
|
|
17910
|
+
count: 80,
|
|
17911
|
+
distribution: { A: 10, B: 28, C: 38, D: 19, F: 5 }
|
|
17912
|
+
},
|
|
17913
|
+
git: {
|
|
17914
|
+
category: "git",
|
|
17915
|
+
avgScore: 80,
|
|
17916
|
+
topScore: 94,
|
|
17917
|
+
topSkills: ["git-workflow", "conventional-commits"],
|
|
17918
|
+
count: 60,
|
|
17919
|
+
distribution: { A: 18, B: 40, C: 28, D: 12, F: 2 }
|
|
17920
|
+
},
|
|
17921
|
+
security: {
|
|
17922
|
+
category: "security",
|
|
17923
|
+
avgScore: 76,
|
|
17924
|
+
topScore: 93,
|
|
17925
|
+
topSkills: ["security-review", "owasp-patterns"],
|
|
17926
|
+
count: 45,
|
|
17927
|
+
distribution: { A: 14, B: 32, C: 34, D: 16, F: 4 }
|
|
17928
|
+
},
|
|
17929
|
+
api: {
|
|
17930
|
+
category: "api",
|
|
17931
|
+
avgScore: 74,
|
|
17932
|
+
topScore: 91,
|
|
17933
|
+
topSkills: ["api-design", "rest-best-practices"],
|
|
17934
|
+
count: 55,
|
|
17935
|
+
distribution: { A: 11, B: 30, C: 36, D: 18, F: 5 }
|
|
17936
|
+
},
|
|
17937
|
+
general: {
|
|
17938
|
+
category: "general",
|
|
17939
|
+
avgScore: 70,
|
|
17940
|
+
topScore: 88,
|
|
17941
|
+
topSkills: ["code-review", "best-practices"],
|
|
17942
|
+
count: 200,
|
|
17943
|
+
distribution: { A: 8, B: 25, C: 40, D: 22, F: 5 }
|
|
17944
|
+
}
|
|
17945
|
+
};
|
|
17946
|
+
function getGrade(score) {
|
|
17947
|
+
if (score >= 90) return "A";
|
|
17948
|
+
if (score >= 80) return "B";
|
|
17949
|
+
if (score >= 70) return "C";
|
|
17950
|
+
if (score >= 60) return "D";
|
|
17951
|
+
return "F";
|
|
17952
|
+
}
|
|
17953
|
+
function detectCategory(skillName, tags = []) {
|
|
17954
|
+
const lowerName = skillName.toLowerCase();
|
|
17955
|
+
const lowerTags = tags.map((t) => t.toLowerCase());
|
|
17956
|
+
const searchTerms = [lowerName, ...lowerTags];
|
|
17957
|
+
const categoryKeywords = {
|
|
17958
|
+
react: ["react", "hooks", "jsx", "tsx", "component", "nextjs", "remix"],
|
|
17959
|
+
typescript: ["typescript", "type", "types", "ts", "strict"],
|
|
17960
|
+
testing: ["test", "testing", "tdd", "jest", "vitest", "playwright", "e2e"],
|
|
17961
|
+
git: ["git", "commit", "branch", "merge", "workflow", "conventional"],
|
|
17962
|
+
security: ["security", "auth", "owasp", "vulnerability", "safe"],
|
|
17963
|
+
api: ["api", "rest", "graphql", "endpoint", "http"]
|
|
17964
|
+
};
|
|
17965
|
+
for (const [category, keywords] of Object.entries(categoryKeywords)) {
|
|
17966
|
+
for (const term of searchTerms) {
|
|
17967
|
+
if (keywords.some((kw) => term.includes(kw))) {
|
|
17968
|
+
return category;
|
|
17969
|
+
}
|
|
17970
|
+
}
|
|
17971
|
+
}
|
|
17972
|
+
return "general";
|
|
17973
|
+
}
|
|
17974
|
+
function calculatePercentile(score, categoryStats) {
|
|
17975
|
+
const { distribution } = categoryStats;
|
|
17976
|
+
const totalSkills = distribution.A + distribution.B + distribution.C + distribution.D + distribution.F;
|
|
17977
|
+
let percentBelow = 0;
|
|
17978
|
+
if (score < 60) {
|
|
17979
|
+
percentBelow = score / 60 * (distribution.F / totalSkills) * 100;
|
|
17980
|
+
} else if (score < 70) {
|
|
17981
|
+
percentBelow = distribution.F / totalSkills * 100;
|
|
17982
|
+
percentBelow += (score - 60) / 10 * (distribution.D / totalSkills) * 100;
|
|
17983
|
+
} else if (score < 80) {
|
|
17984
|
+
percentBelow = (distribution.F + distribution.D) / totalSkills * 100;
|
|
17985
|
+
percentBelow += (score - 70) / 10 * (distribution.C / totalSkills) * 100;
|
|
17986
|
+
} else if (score < 90) {
|
|
17987
|
+
percentBelow = (distribution.F + distribution.D + distribution.C) / totalSkills * 100;
|
|
17988
|
+
percentBelow += (score - 80) / 10 * (distribution.B / totalSkills) * 100;
|
|
17989
|
+
} else {
|
|
17990
|
+
percentBelow = (distribution.F + distribution.D + distribution.C + distribution.B) / totalSkills * 100;
|
|
17991
|
+
percentBelow += (score - 90) / 10 * (distribution.A / totalSkills) * 100;
|
|
17992
|
+
}
|
|
17993
|
+
return Math.round(Math.min(99, Math.max(1, percentBelow)));
|
|
17994
|
+
}
|
|
17995
|
+
function generateComparisonNotes(quality, categoryStats) {
|
|
17996
|
+
const notes = [];
|
|
17997
|
+
const topScore = categoryStats.topScore;
|
|
17998
|
+
const avgScore = categoryStats.avgScore;
|
|
17999
|
+
if (quality.overall >= topScore) {
|
|
18000
|
+
notes.push("Your skill is among the top performers in this category");
|
|
18001
|
+
} else if (quality.overall >= avgScore) {
|
|
18002
|
+
notes.push(`Your skill is above the category average (${avgScore})`);
|
|
18003
|
+
} else {
|
|
18004
|
+
notes.push(`Your skill is ${avgScore - quality.overall} points below the category average`);
|
|
18005
|
+
}
|
|
18006
|
+
if (!quality.structure.hasExamples) {
|
|
18007
|
+
notes.push("Missing code examples (present in 95% of top skills)");
|
|
18008
|
+
}
|
|
18009
|
+
if (!quality.structure.hasTriggers) {
|
|
18010
|
+
notes.push("Missing trigger conditions (present in 80% of top skills)");
|
|
18011
|
+
}
|
|
18012
|
+
if (!quality.structure.hasBoundaries) {
|
|
18013
|
+
notes.push('Missing "When Not to Use" section (present in 80% of top skills)');
|
|
18014
|
+
}
|
|
18015
|
+
if (quality.specificity.vagueTermCount > 3) {
|
|
18016
|
+
notes.push("Trigger conditions are less specific than category average");
|
|
18017
|
+
}
|
|
18018
|
+
if (quality.clarity.lineCount > 300) {
|
|
18019
|
+
notes.push("Skill is longer than recommended (top skills average 150-250 lines)");
|
|
18020
|
+
}
|
|
18021
|
+
if (quality.advanced.deprecatedPatterns.length > 0) {
|
|
18022
|
+
notes.push("Contains deprecated patterns not found in top skills");
|
|
18023
|
+
}
|
|
18024
|
+
return notes;
|
|
18025
|
+
}
|
|
18026
|
+
function generateRecommendations(quality, categoryStats) {
|
|
18027
|
+
const recommendations = [];
|
|
18028
|
+
const gap = categoryStats.topScore - quality.overall;
|
|
18029
|
+
if (gap > 20) {
|
|
18030
|
+
recommendations.push("Consider studying top skills in this category for patterns");
|
|
18031
|
+
}
|
|
18032
|
+
if (!quality.structure.hasExamples) {
|
|
18033
|
+
recommendations.push(`Add ${quality.specificity.hasCodeExamples ? "more" : ""} code examples showing input/output`);
|
|
18034
|
+
}
|
|
18035
|
+
if (!quality.structure.hasTriggers) {
|
|
18036
|
+
recommendations.push('Add explicit trigger conditions with patterns like "Triggers when:"');
|
|
18037
|
+
}
|
|
18038
|
+
if (!quality.structure.hasBoundaries) {
|
|
18039
|
+
recommendations.push('Add a "Boundaries" or "Limitations" section');
|
|
18040
|
+
}
|
|
18041
|
+
if (quality.clarity.lineCount > 400) {
|
|
18042
|
+
recommendations.push("Split into multiple focused skills (top skills are 150-250 lines)");
|
|
18043
|
+
}
|
|
18044
|
+
if (quality.specificity.vagueTermCount > 0) {
|
|
18045
|
+
recommendations.push(`Replace ${quality.specificity.vagueTermCount} vague term(s) with specific instructions`);
|
|
18046
|
+
}
|
|
18047
|
+
if (quality.advanced.completeness.hasTodos) {
|
|
18048
|
+
recommendations.push("Complete TODO items before publishing");
|
|
18049
|
+
}
|
|
18050
|
+
return recommendations;
|
|
18051
|
+
}
|
|
18052
|
+
function benchmarkSkill(skillName, quality, tags = [], customCategoryStats) {
|
|
18053
|
+
const category = detectCategory(skillName, tags);
|
|
18054
|
+
const categoryStats = customCategoryStats || CATEGORY_BENCHMARKS[category] || CATEGORY_BENCHMARKS.general;
|
|
18055
|
+
const percentile = calculatePercentile(quality.overall, categoryStats);
|
|
18056
|
+
const comparisonNotes = generateComparisonNotes(quality, categoryStats);
|
|
18057
|
+
const recommendations = generateRecommendations(quality, categoryStats);
|
|
18058
|
+
return {
|
|
18059
|
+
skill: skillName,
|
|
18060
|
+
score: quality.overall,
|
|
18061
|
+
grade: getGrade(quality.overall),
|
|
18062
|
+
categoryAvg: categoryStats.avgScore,
|
|
18063
|
+
topSkillScore: categoryStats.topScore,
|
|
18064
|
+
percentile,
|
|
18065
|
+
comparisonNotes,
|
|
18066
|
+
recommendations
|
|
18067
|
+
};
|
|
18068
|
+
}
|
|
18069
|
+
function getCategoryStats(category) {
|
|
18070
|
+
return CATEGORY_BENCHMARKS[category] || null;
|
|
18071
|
+
}
|
|
18072
|
+
function getAllCategories() {
|
|
18073
|
+
return Object.keys(CATEGORY_BENCHMARKS);
|
|
18074
|
+
}
|
|
18075
|
+
|
|
18076
|
+
// src/quality/index.ts
|
|
18077
|
+
var VAGUE_TERMS = [
|
|
18078
|
+
"be helpful",
|
|
18079
|
+
"assist the user",
|
|
18080
|
+
"help with",
|
|
18081
|
+
"try to",
|
|
18082
|
+
"attempt to",
|
|
18083
|
+
"do your best",
|
|
18084
|
+
"as needed",
|
|
18085
|
+
"when appropriate",
|
|
18086
|
+
"if necessary",
|
|
18087
|
+
"general purpose",
|
|
18088
|
+
"various tasks",
|
|
18089
|
+
"many things",
|
|
18090
|
+
"etc.",
|
|
18091
|
+
"and so on",
|
|
18092
|
+
"stuff like that"
|
|
18093
|
+
];
|
|
18094
|
+
var BOUNDARY_PATTERNS = [
|
|
18095
|
+
/never\s+(?:do|use|commit|push|delete|remove)/i,
|
|
18096
|
+
/always\s+(?:do|use|check|verify|ensure)/i,
|
|
18097
|
+
/don'?t\s+(?:do|use|commit|push|delete)/i,
|
|
18098
|
+
/avoid\s+(?:using|doing|committing)/i,
|
|
18099
|
+
/must\s+(?:not|always|never)/i,
|
|
18100
|
+
/forbidden/i,
|
|
18101
|
+
/prohibited/i,
|
|
18102
|
+
/required/i
|
|
18103
|
+
];
|
|
18104
|
+
var TRIGGER_PATTERNS = [
|
|
18105
|
+
/when\s+to\s+use/i,
|
|
18106
|
+
/use\s+this\s+(?:skill|when)/i,
|
|
18107
|
+
/triggers?\s*(?:when|:)/i,
|
|
18108
|
+
/activated?\s+(?:when|by)/i,
|
|
18109
|
+
/applies?\s+(?:when|to)/i,
|
|
18110
|
+
/invoke\s+(?:when|this)/i
|
|
18111
|
+
];
|
|
18112
|
+
var COMMAND_PATTERNS = [
|
|
18113
|
+
/```(?:bash|sh|shell|zsh)[\s\S]*?```/g,
|
|
18114
|
+
/`(?:npm|pnpm|yarn|bun|npx|git|docker|kubectl)\s+[^`]+`/g,
|
|
18115
|
+
/\$\s*\w+/g
|
|
18116
|
+
];
|
|
18117
|
+
var CODE_EXAMPLE_PATTERNS = [
|
|
18118
|
+
/```(?:typescript|javascript|tsx|jsx|python|go|rust|java)[\s\S]*?```/g,
|
|
18119
|
+
/```[\s\S]{50,}?```/g
|
|
18120
|
+
];
|
|
18121
|
+
var FILE_PATTERN_PATTERNS = [
|
|
18122
|
+
/\*\*\/\*\.\w+/,
|
|
18123
|
+
/\.\w+$/m,
|
|
18124
|
+
/glob[s]?\s*[:=]/i,
|
|
18125
|
+
/include[s]?\s*[:=]/i,
|
|
18126
|
+
/pattern[s]?\s*[:=]/i
|
|
18127
|
+
];
|
|
18128
|
+
var DEPRECATED_PATTERNS = [
|
|
18129
|
+
{ pattern: /require\s*\(['"][^'"]+['"]\)/g, message: "Uses CommonJS require() instead of ES modules" },
|
|
18130
|
+
{ pattern: /React\.Component/g, message: "Uses class components instead of functional" },
|
|
18131
|
+
{ pattern: /componentDidMount|componentWillUnmount|componentDidUpdate/g, message: "Uses lifecycle methods instead of hooks" },
|
|
18132
|
+
{ pattern: /\bvar\s+\w+\s*=/g, message: "Uses var instead of const/let" },
|
|
18133
|
+
{ pattern: /\.then\s*\([^)]*\)\.catch/g, message: "Uses .then().catch() instead of async/await" },
|
|
18134
|
+
{ pattern: /new\s+Promise\s*\(/g, message: "Consider using async/await instead of new Promise()" }
|
|
18135
|
+
];
|
|
18136
|
+
var SECURITY_PATTERNS = [
|
|
18137
|
+
{ pattern: /password\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded password" },
|
|
18138
|
+
{ pattern: /api[_-]?key\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded API key" },
|
|
18139
|
+
{ pattern: /secret\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded secret" },
|
|
18140
|
+
{ pattern: /token\s*[:=]\s*['"][A-Za-z0-9_-]{20,}['"]/gi, message: "Potential hardcoded token" },
|
|
18141
|
+
{ pattern: /\$\{[^}]*\}/g, message: "Template literal - ensure proper sanitization in shell commands" },
|
|
18142
|
+
{ pattern: /eval\s*\(/g, message: "Uses eval() - potential code injection risk" },
|
|
18143
|
+
{ pattern: /innerHTML\s*=/g, message: "Uses innerHTML - potential XSS risk" },
|
|
18144
|
+
{ pattern: /dangerouslySetInnerHTML/g, message: "Uses dangerouslySetInnerHTML - potential XSS risk" }
|
|
18145
|
+
];
|
|
18146
|
+
function extractFrontmatter4(content) {
|
|
18147
|
+
const normalizedContent = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
18148
|
+
const match = normalizedContent.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
18149
|
+
if (!match) return null;
|
|
18150
|
+
const frontmatter = {};
|
|
18151
|
+
const lines = match[1].split("\n");
|
|
18152
|
+
for (const line of lines) {
|
|
18153
|
+
const colonIndex = line.indexOf(":");
|
|
18154
|
+
if (colonIndex > 0) {
|
|
18155
|
+
const key = line.slice(0, colonIndex).trim();
|
|
18156
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
18157
|
+
frontmatter[key] = value;
|
|
18158
|
+
}
|
|
18159
|
+
}
|
|
18160
|
+
return Object.keys(frontmatter).length > 0 ? frontmatter : null;
|
|
18161
|
+
}
|
|
18162
|
+
function countTokens(text) {
|
|
18163
|
+
return Math.ceil(text.length / 4);
|
|
18164
|
+
}
|
|
18165
|
+
function countVagueTerms(content) {
|
|
18166
|
+
const lowerContent = content.toLowerCase();
|
|
18167
|
+
let count = 0;
|
|
18168
|
+
for (const term of VAGUE_TERMS) {
|
|
18169
|
+
const regex = new RegExp(term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
18170
|
+
const matches = lowerContent.match(regex);
|
|
18171
|
+
if (matches) count += matches.length;
|
|
18172
|
+
}
|
|
18173
|
+
return count;
|
|
18174
|
+
}
|
|
18175
|
+
function hasPattern(content, patterns) {
|
|
18176
|
+
return patterns.some((p) => p.test(content));
|
|
18177
|
+
}
|
|
18178
|
+
function countMatches(content, patterns) {
|
|
18179
|
+
let count = 0;
|
|
18180
|
+
for (const pattern of patterns) {
|
|
18181
|
+
const matches = content.match(pattern);
|
|
18182
|
+
if (matches) count += matches.length;
|
|
18183
|
+
}
|
|
18184
|
+
return count;
|
|
18185
|
+
}
|
|
18186
|
+
function calculateAvgSentenceLength(content) {
|
|
18187
|
+
const contentWithoutCode = content.replace(/```[\s\S]*?```/g, "");
|
|
18188
|
+
const sentences = contentWithoutCode.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
18189
|
+
if (sentences.length === 0) return 0;
|
|
18190
|
+
const totalWords = sentences.reduce((sum, s) => sum + s.trim().split(/\s+/).length, 0);
|
|
18191
|
+
return Math.round(totalWords / sentences.length);
|
|
18192
|
+
}
|
|
18193
|
+
function evaluateStructure(content) {
|
|
18194
|
+
const frontmatter = extractFrontmatter4(content);
|
|
18195
|
+
const hasMetadata = frontmatter !== null && Object.keys(frontmatter).length > 0;
|
|
18196
|
+
const hasDescription = !!frontmatter?.description || /^#+\s*description/im.test(content);
|
|
18197
|
+
const hasTriggers = hasPattern(content, TRIGGER_PATTERNS);
|
|
18198
|
+
const hasExamples = countMatches(content, CODE_EXAMPLE_PATTERNS) > 0;
|
|
18199
|
+
const hasBoundaries = hasPattern(content, BOUNDARY_PATTERNS);
|
|
18200
|
+
const hasWhenToUse = /when\s+to\s+use|use\s+case|scenario/i.test(content);
|
|
18201
|
+
let score = 0;
|
|
18202
|
+
if (hasMetadata) score += 15;
|
|
18203
|
+
if (hasDescription) score += 10;
|
|
18204
|
+
if (hasTriggers) score += 20;
|
|
18205
|
+
if (hasExamples) score += 20;
|
|
18206
|
+
if (hasBoundaries) score += 20;
|
|
18207
|
+
if (hasWhenToUse) score += 15;
|
|
18208
|
+
return {
|
|
18209
|
+
score: Math.min(100, score),
|
|
18210
|
+
hasMetadata,
|
|
18211
|
+
hasDescription,
|
|
18212
|
+
hasTriggers,
|
|
18213
|
+
hasExamples,
|
|
18214
|
+
hasBoundaries,
|
|
18215
|
+
hasWhenToUse
|
|
18216
|
+
};
|
|
18217
|
+
}
|
|
18218
|
+
function evaluateClarity(content) {
|
|
18219
|
+
const lines = content.split("\n");
|
|
18220
|
+
const lineCount = lines.length;
|
|
18221
|
+
const tokenCount = countTokens(content);
|
|
18222
|
+
const avgSentenceLength = calculateAvgSentenceLength(content);
|
|
18223
|
+
const hasHeaders = /^#+\s+/m.test(content);
|
|
18224
|
+
let score = 100;
|
|
18225
|
+
if (lineCount > 500) score -= 30;
|
|
18226
|
+
else if (lineCount > 300) score -= 15;
|
|
18227
|
+
else if (lineCount > 150) score -= 5;
|
|
18228
|
+
if (tokenCount > 4e3) score -= 30;
|
|
18229
|
+
else if (tokenCount > 2e3) score -= 15;
|
|
18230
|
+
else if (tokenCount > 1e3) score -= 5;
|
|
18231
|
+
if (avgSentenceLength > 30) score -= 20;
|
|
18232
|
+
else if (avgSentenceLength > 20) score -= 10;
|
|
18233
|
+
if (!hasHeaders) score -= 15;
|
|
18234
|
+
return {
|
|
18235
|
+
score: Math.max(0, score),
|
|
18236
|
+
lineCount,
|
|
18237
|
+
tokenCount,
|
|
18238
|
+
avgSentenceLength,
|
|
18239
|
+
hasHeaders
|
|
18240
|
+
};
|
|
18241
|
+
}
|
|
18242
|
+
function countCodeBlocks(content) {
|
|
18243
|
+
const fencedBlocks = content.match(/```[\s\S]*?```/g) || [];
|
|
18244
|
+
return fencedBlocks.length;
|
|
18245
|
+
}
|
|
18246
|
+
function detectDeprecatedPatterns(content) {
|
|
18247
|
+
const codeBlocks = content.match(/```[\s\S]*?```/g) || [];
|
|
18248
|
+
const codeContent = codeBlocks.join("\n");
|
|
18249
|
+
const issues = [];
|
|
18250
|
+
for (const { pattern, message } of DEPRECATED_PATTERNS) {
|
|
18251
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
18252
|
+
if (regex.test(codeContent)) {
|
|
18253
|
+
issues.push(message);
|
|
18254
|
+
}
|
|
18255
|
+
}
|
|
18256
|
+
return [...new Set(issues)];
|
|
18257
|
+
}
|
|
18258
|
+
function detectSecurityPatterns(content) {
|
|
18259
|
+
const issues = [];
|
|
18260
|
+
for (const { pattern, message } of SECURITY_PATTERNS) {
|
|
18261
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
18262
|
+
if (regex.test(content)) {
|
|
18263
|
+
if (!message.includes("Template literal") || content.includes("bash") || content.includes("shell")) {
|
|
18264
|
+
issues.push(message);
|
|
18265
|
+
}
|
|
18266
|
+
}
|
|
18267
|
+
}
|
|
18268
|
+
return [...new Set(issues)];
|
|
18269
|
+
}
|
|
18270
|
+
function detectConflictingInstructions(content) {
|
|
18271
|
+
const issues = [];
|
|
18272
|
+
const lowerContent = content.toLowerCase();
|
|
18273
|
+
const alwaysMatches = lowerContent.match(/always\s+(?:use|do|include|add)\s+(\w+)/gi) || [];
|
|
18274
|
+
const neverMatches = lowerContent.match(/never\s+(?:use|do|include|add)\s+(\w+)/gi) || [];
|
|
18275
|
+
for (const always of alwaysMatches) {
|
|
18276
|
+
const term = always.replace(/always\s+(?:use|do|include|add)\s+/i, "").toLowerCase();
|
|
18277
|
+
for (const never of neverMatches) {
|
|
18278
|
+
const neverTerm = never.replace(/never\s+(?:use|do|include|add)\s+/i, "").toLowerCase();
|
|
18279
|
+
if (term === neverTerm) {
|
|
18280
|
+
issues.push(`Conflicting instructions: "always" and "never" used with "${term}"`);
|
|
18281
|
+
}
|
|
18282
|
+
}
|
|
18283
|
+
}
|
|
18284
|
+
const mustMatches = lowerContent.match(/must\s+(\w+)/gi) || [];
|
|
18285
|
+
const mustNotMatches = lowerContent.match(/must\s+not\s+(\w+)/gi) || [];
|
|
18286
|
+
for (const must of mustMatches) {
|
|
18287
|
+
const term = must.replace(/must\s+/i, "").toLowerCase();
|
|
18288
|
+
for (const mustNot of mustNotMatches) {
|
|
18289
|
+
const notTerm = mustNot.replace(/must\s+not\s+/i, "").toLowerCase();
|
|
18290
|
+
if (term === notTerm) {
|
|
18291
|
+
issues.push(`Conflicting instructions: "must" and "must not" used with "${term}"`);
|
|
18292
|
+
}
|
|
18293
|
+
}
|
|
18294
|
+
}
|
|
18295
|
+
return [...new Set(issues)];
|
|
18296
|
+
}
|
|
18297
|
+
function assessCompleteness(content) {
|
|
18298
|
+
const todoMatches = content.match(/TODO|FIXME|XXX|HACK/gi) || [];
|
|
18299
|
+
const todoCount = todoMatches.length;
|
|
18300
|
+
const headerPositions = [];
|
|
18301
|
+
const lines = content.split("\n");
|
|
18302
|
+
let inFence = false;
|
|
18303
|
+
let offset = 0;
|
|
18304
|
+
for (const line of lines) {
|
|
18305
|
+
if (/^```|^~~~/.test(line)) {
|
|
18306
|
+
inFence = !inFence;
|
|
18307
|
+
} else if (!inFence && /^#+\s+.+$/.test(line)) {
|
|
18308
|
+
headerPositions.push({ header: line, index: offset });
|
|
18309
|
+
}
|
|
18310
|
+
offset += line.length + 1;
|
|
18311
|
+
}
|
|
18312
|
+
const emptySections = [];
|
|
18313
|
+
for (let i = 0; i < headerPositions.length - 1; i++) {
|
|
18314
|
+
const current = headerPositions[i];
|
|
18315
|
+
const next = headerPositions[i + 1];
|
|
18316
|
+
const sectionContent = content.slice(current.index + current.header.length, next.index).trim();
|
|
18317
|
+
if (sectionContent.length < 20) {
|
|
18318
|
+
const sectionName = current.header.replace(/^#+\s+/, "");
|
|
18319
|
+
emptySections.push(sectionName);
|
|
18320
|
+
}
|
|
18321
|
+
}
|
|
18322
|
+
if (headerPositions.length > 0) {
|
|
18323
|
+
const last = headerPositions[headerPositions.length - 1];
|
|
18324
|
+
const tailContent = content.slice(last.index + last.header.length).trim();
|
|
18325
|
+
if (tailContent.length < 20) {
|
|
18326
|
+
const sectionName = last.header.replace(/^#+\s+/, "");
|
|
18327
|
+
emptySections.push(sectionName);
|
|
18328
|
+
}
|
|
18329
|
+
}
|
|
18330
|
+
const codeBlocks = countCodeBlocks(content);
|
|
18331
|
+
const exampleCoverage = Math.min(100, codeBlocks * 25);
|
|
18332
|
+
let score = 100;
|
|
18333
|
+
if (todoCount > 0) score -= Math.min(30, todoCount * 10);
|
|
18334
|
+
if (emptySections.length > 0) score -= Math.min(30, emptySections.length * 10);
|
|
18335
|
+
if (codeBlocks < 2) score -= 20;
|
|
18336
|
+
else if (codeBlocks < 4) score -= 10;
|
|
18337
|
+
return {
|
|
18338
|
+
score: Math.max(0, score),
|
|
18339
|
+
hasTodos: todoCount > 0,
|
|
18340
|
+
todoCount,
|
|
18341
|
+
emptySections,
|
|
18342
|
+
exampleCoverage
|
|
18343
|
+
};
|
|
18344
|
+
}
|
|
18345
|
+
function evaluateAdvanced(content) {
|
|
18346
|
+
const deprecatedPatterns = detectDeprecatedPatterns(content);
|
|
18347
|
+
const conflictingInstructions = detectConflictingInstructions(content);
|
|
18348
|
+
const securityIssues = detectSecurityPatterns(content);
|
|
18349
|
+
const completeness = assessCompleteness(content);
|
|
18350
|
+
let score = 100;
|
|
18351
|
+
score -= Math.min(30, deprecatedPatterns.length * 10);
|
|
18352
|
+
score -= Math.min(30, conflictingInstructions.length * 15);
|
|
18353
|
+
score -= Math.min(25, securityIssues.length * 10);
|
|
18354
|
+
score -= Math.round((100 - completeness.score) * 0.15);
|
|
18355
|
+
return {
|
|
18356
|
+
score: Math.max(0, score),
|
|
18357
|
+
deprecatedPatterns,
|
|
18358
|
+
conflictingInstructions,
|
|
18359
|
+
securityIssues,
|
|
18360
|
+
completeness
|
|
18361
|
+
};
|
|
18362
|
+
}
|
|
18363
|
+
function evaluateSpecificity(content) {
|
|
18364
|
+
const hasConcreteCommands = countMatches(content, COMMAND_PATTERNS) > 0;
|
|
18365
|
+
const hasFilePatterns = hasPattern(content, FILE_PATTERN_PATTERNS);
|
|
18366
|
+
const codeBlockCount = countCodeBlocks(content);
|
|
18367
|
+
const hasCodeExamples = codeBlockCount >= 2;
|
|
18368
|
+
const vagueTermCount = countVagueTerms(content);
|
|
18369
|
+
let score = 0;
|
|
18370
|
+
if (hasConcreteCommands) score += 30;
|
|
18371
|
+
if (hasFilePatterns) score += 25;
|
|
18372
|
+
if (hasCodeExamples) score += 30;
|
|
18373
|
+
if (vagueTermCount === 0) score += 15;
|
|
18374
|
+
else if (vagueTermCount <= 2) score += 10;
|
|
18375
|
+
else if (vagueTermCount <= 5) score += 5;
|
|
18376
|
+
return {
|
|
18377
|
+
score: Math.min(100, score),
|
|
18378
|
+
hasConcreteCommands,
|
|
18379
|
+
hasFilePatterns,
|
|
18380
|
+
hasCodeExamples,
|
|
18381
|
+
vagueTermCount
|
|
18382
|
+
};
|
|
18383
|
+
}
|
|
18384
|
+
function generateWarnings(structure, clarity, specificity, advanced) {
|
|
18385
|
+
const warnings = [];
|
|
18386
|
+
if (!structure.hasMetadata) {
|
|
18387
|
+
warnings.push("Missing frontmatter metadata");
|
|
18388
|
+
}
|
|
18389
|
+
if (!structure.hasTriggers) {
|
|
18390
|
+
warnings.push("No trigger conditions defined");
|
|
18391
|
+
}
|
|
18392
|
+
if (!structure.hasBoundaries) {
|
|
18393
|
+
warnings.push("No boundaries or constraints specified");
|
|
18394
|
+
}
|
|
18395
|
+
if (clarity.lineCount > 500) {
|
|
18396
|
+
warnings.push(`Skill is too long (${clarity.lineCount} lines)`);
|
|
18397
|
+
}
|
|
18398
|
+
if (clarity.tokenCount > 4e3) {
|
|
18399
|
+
warnings.push(`High token usage (${clarity.tokenCount} tokens)`);
|
|
18400
|
+
}
|
|
18401
|
+
if (specificity.vagueTermCount > 5) {
|
|
18402
|
+
warnings.push(`Contains ${specificity.vagueTermCount} vague terms`);
|
|
18403
|
+
}
|
|
18404
|
+
if (!structure.hasExamples) {
|
|
18405
|
+
warnings.push("No code examples provided");
|
|
18406
|
+
} else if (!specificity.hasCodeExamples) {
|
|
18407
|
+
warnings.push("Only one code example provided");
|
|
18408
|
+
}
|
|
18409
|
+
for (const issue of advanced.securityIssues) {
|
|
18410
|
+
warnings.push(`Security: ${issue}`);
|
|
18411
|
+
}
|
|
18412
|
+
for (const conflict of advanced.conflictingInstructions) {
|
|
18413
|
+
warnings.push(conflict);
|
|
18414
|
+
}
|
|
18415
|
+
if (advanced.completeness.hasTodos) {
|
|
18416
|
+
warnings.push(`Contains ${advanced.completeness.todoCount} TODO/FIXME comment(s)`);
|
|
18417
|
+
}
|
|
18418
|
+
if (advanced.completeness.emptySections.length > 0) {
|
|
18419
|
+
warnings.push(`Empty sections: ${advanced.completeness.emptySections.join(", ")}`);
|
|
18420
|
+
}
|
|
18421
|
+
return warnings;
|
|
18422
|
+
}
|
|
18423
|
+
function generateSuggestions(structure, clarity, specificity, advanced) {
|
|
18424
|
+
const suggestions = [];
|
|
18425
|
+
if (!structure.hasMetadata) {
|
|
18426
|
+
suggestions.push("Add YAML frontmatter with name, description, and globs");
|
|
18427
|
+
}
|
|
18428
|
+
if (!structure.hasTriggers) {
|
|
18429
|
+
suggestions.push('Add a "When to Use" section with specific trigger conditions');
|
|
18430
|
+
}
|
|
18431
|
+
if (!structure.hasExamples) {
|
|
18432
|
+
suggestions.push("Include code examples showing expected output");
|
|
18433
|
+
}
|
|
18434
|
+
if (!structure.hasBoundaries) {
|
|
18435
|
+
suggestions.push("Define boundaries: what the agent should never do");
|
|
18436
|
+
}
|
|
18437
|
+
if (clarity.lineCount > 300) {
|
|
18438
|
+
suggestions.push("Consider splitting into multiple focused skills");
|
|
18439
|
+
}
|
|
18440
|
+
if (!clarity.hasHeaders) {
|
|
18441
|
+
suggestions.push("Use markdown headers to organize content");
|
|
18442
|
+
}
|
|
18443
|
+
if (specificity.vagueTermCount > 0) {
|
|
18444
|
+
suggestions.push("Replace vague terms with specific instructions");
|
|
18445
|
+
}
|
|
18446
|
+
if (!specificity.hasConcreteCommands) {
|
|
18447
|
+
suggestions.push("Add concrete executable commands with flags");
|
|
18448
|
+
}
|
|
18449
|
+
if (advanced.deprecatedPatterns.length > 0) {
|
|
18450
|
+
suggestions.push("Update code examples to use modern patterns (ES modules, hooks, async/await)");
|
|
18451
|
+
}
|
|
18452
|
+
if (advanced.securityIssues.length > 0) {
|
|
18453
|
+
suggestions.push("Review and remove potential security risks from examples");
|
|
18454
|
+
}
|
|
18455
|
+
if (advanced.completeness.hasTodos) {
|
|
18456
|
+
suggestions.push("Complete or remove TODO/FIXME comments");
|
|
18457
|
+
}
|
|
18458
|
+
if (advanced.completeness.emptySections.length > 0) {
|
|
18459
|
+
suggestions.push("Add content to empty sections or remove them");
|
|
18460
|
+
}
|
|
18461
|
+
if (advanced.completeness.exampleCoverage < 50) {
|
|
18462
|
+
suggestions.push("Add more code examples to improve coverage");
|
|
18463
|
+
}
|
|
18464
|
+
return suggestions;
|
|
18465
|
+
}
|
|
18466
|
+
function evaluateSkillContent(content) {
|
|
18467
|
+
const structure = evaluateStructure(content);
|
|
18468
|
+
const clarity = evaluateClarity(content);
|
|
18469
|
+
const specificity = evaluateSpecificity(content);
|
|
18470
|
+
const advanced = evaluateAdvanced(content);
|
|
18471
|
+
const overall = Math.round(
|
|
18472
|
+
structure.score * 0.35 + clarity.score * 0.25 + specificity.score * 0.25 + advanced.score * 0.15
|
|
18473
|
+
);
|
|
18474
|
+
const warnings = generateWarnings(structure, clarity, specificity, advanced);
|
|
18475
|
+
const suggestions = generateSuggestions(structure, clarity, specificity, advanced);
|
|
18476
|
+
return {
|
|
18477
|
+
overall,
|
|
18478
|
+
structure,
|
|
18479
|
+
clarity,
|
|
18480
|
+
specificity,
|
|
18481
|
+
advanced,
|
|
18482
|
+
warnings,
|
|
18483
|
+
suggestions
|
|
18484
|
+
};
|
|
18485
|
+
}
|
|
18486
|
+
function evaluateSkillFile(filePath) {
|
|
18487
|
+
if (!existsSync34(filePath)) return null;
|
|
18488
|
+
try {
|
|
18489
|
+
const content = readFileSync26(filePath, "utf-8");
|
|
18490
|
+
return evaluateSkillContent(content);
|
|
18491
|
+
} catch {
|
|
18492
|
+
return null;
|
|
18493
|
+
}
|
|
18494
|
+
}
|
|
18495
|
+
function evaluateSkillDirectory(dirPath) {
|
|
18496
|
+
const skillMdPath = join35(dirPath, "SKILL.md");
|
|
18497
|
+
if (existsSync34(skillMdPath)) {
|
|
18498
|
+
return evaluateSkillFile(skillMdPath);
|
|
18499
|
+
}
|
|
18500
|
+
const mdcFiles = ["index.mdc", `${basename12(dirPath)}.mdc`];
|
|
18501
|
+
for (const file of mdcFiles) {
|
|
18502
|
+
const mdcPath = join35(dirPath, file);
|
|
18503
|
+
if (existsSync34(mdcPath)) {
|
|
18504
|
+
return evaluateSkillFile(mdcPath);
|
|
18505
|
+
}
|
|
18506
|
+
}
|
|
18507
|
+
return null;
|
|
18508
|
+
}
|
|
18509
|
+
function getQualityGrade(score) {
|
|
18510
|
+
if (score >= 90) return "A";
|
|
18511
|
+
if (score >= 80) return "B";
|
|
18512
|
+
if (score >= 70) return "C";
|
|
18513
|
+
if (score >= 60) return "D";
|
|
18514
|
+
return "F";
|
|
18515
|
+
}
|
|
18516
|
+
function isHighQuality(score) {
|
|
18517
|
+
return score.overall >= 80 && score.warnings.length <= 2;
|
|
18518
|
+
}
|
|
17525
18519
|
export {
|
|
17526
18520
|
AGENT_CLI_CONFIGS,
|
|
17527
18521
|
AGENT_CONFIG,
|
|
@@ -17620,7 +18614,9 @@ export {
|
|
|
17620
18614
|
addToManifest,
|
|
17621
18615
|
agentExists,
|
|
17622
18616
|
analyzeProject,
|
|
18617
|
+
benchmarkSkill,
|
|
17623
18618
|
buildSkillIndex,
|
|
18619
|
+
calculatePercentile,
|
|
17624
18620
|
canTranslate,
|
|
17625
18621
|
copilotTranslator,
|
|
17626
18622
|
createAPIBasedCompressor,
|
|
@@ -17658,6 +18654,7 @@ export {
|
|
|
17658
18654
|
createWorkflowOrchestrator,
|
|
17659
18655
|
createWorkflowTemplate,
|
|
17660
18656
|
cursorTranslator,
|
|
18657
|
+
detectCategory,
|
|
17661
18658
|
detectProvider,
|
|
17662
18659
|
detectSkillFormat,
|
|
17663
18660
|
discoverAgents,
|
|
@@ -17668,6 +18665,9 @@ export {
|
|
|
17668
18665
|
discoverSkills,
|
|
17669
18666
|
dryRunExecutor,
|
|
17670
18667
|
estimateTokens,
|
|
18668
|
+
evaluateSkillContent,
|
|
18669
|
+
evaluateSkillDirectory,
|
|
18670
|
+
evaluateSkillFile,
|
|
17671
18671
|
executeWithAgent,
|
|
17672
18672
|
exportBundle,
|
|
17673
18673
|
extractAgentContent,
|
|
@@ -17683,7 +18683,9 @@ export {
|
|
|
17683
18683
|
findSkill,
|
|
17684
18684
|
formatSkillAsPrompt,
|
|
17685
18685
|
fromCanonicalAgent,
|
|
18686
|
+
generateComparisonNotes,
|
|
17686
18687
|
generateManifestFromInstalled,
|
|
18688
|
+
generateRecommendations,
|
|
17687
18689
|
generateSkillsConfig,
|
|
17688
18690
|
getAgentCLIConfig,
|
|
17689
18691
|
getAgentConfigFile,
|
|
@@ -17695,16 +18697,19 @@ export {
|
|
|
17695
18697
|
getAgentStats,
|
|
17696
18698
|
getAgentTargetDirectory,
|
|
17697
18699
|
getAgentsDirectory,
|
|
18700
|
+
getAllCategories,
|
|
17698
18701
|
getAllProviders,
|
|
17699
18702
|
getAllSkillsDirs,
|
|
17700
18703
|
getAvailableCLIAgents,
|
|
17701
18704
|
getBuiltinPacksDir,
|
|
17702
18705
|
getCICDTemplate,
|
|
18706
|
+
getCategoryStats,
|
|
17703
18707
|
getConfigFile,
|
|
17704
18708
|
getConfigFormat,
|
|
17705
18709
|
getExecutionStrategy,
|
|
17706
18710
|
getGlobalConfigPath,
|
|
17707
18711
|
getGlobalSkillsDir,
|
|
18712
|
+
getGrade,
|
|
17708
18713
|
getIndexStatus,
|
|
17709
18714
|
getInstallDir,
|
|
17710
18715
|
getManualExecutionInstructions,
|
|
@@ -17712,6 +18717,7 @@ export {
|
|
|
17712
18717
|
getMemoryStatus,
|
|
17713
18718
|
getProjectConfigPath,
|
|
17714
18719
|
getProvider,
|
|
18720
|
+
getQualityGrade,
|
|
17715
18721
|
getSearchDirs,
|
|
17716
18722
|
getSkillsDir,
|
|
17717
18723
|
getStackTags,
|
|
@@ -17726,6 +18732,7 @@ export {
|
|
|
17726
18732
|
isAgentCLIAvailable,
|
|
17727
18733
|
isAgentCompatible,
|
|
17728
18734
|
isGitUrl,
|
|
18735
|
+
isHighQuality,
|
|
17729
18736
|
isIndexStale,
|
|
17730
18737
|
isLocalPath,
|
|
17731
18738
|
isPathInside,
|