@skillkit/core 1.7.5 → 1.7.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/dist/index.d.ts +128 -8
- package/dist/index.js +1194 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
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 {
|
|
@@ -1033,7 +1224,22 @@ var AGENT_FORMAT_MAP = {
|
|
|
1033
1224
|
"universal": "skill-md",
|
|
1034
1225
|
"cursor": "cursor-mdc",
|
|
1035
1226
|
"windsurf": "markdown-rules",
|
|
1036
|
-
"github-copilot": "markdown-rules"
|
|
1227
|
+
"github-copilot": "markdown-rules",
|
|
1228
|
+
"cline": "skill-md",
|
|
1229
|
+
"codebuddy": "skill-md",
|
|
1230
|
+
"commandcode": "skill-md",
|
|
1231
|
+
"continue": "skill-md",
|
|
1232
|
+
"crush": "skill-md",
|
|
1233
|
+
"factory": "skill-md",
|
|
1234
|
+
"mcpjam": "skill-md",
|
|
1235
|
+
"mux": "skill-md",
|
|
1236
|
+
"neovate": "skill-md",
|
|
1237
|
+
"openhands": "skill-md",
|
|
1238
|
+
"pi": "skill-md",
|
|
1239
|
+
"qoder": "skill-md",
|
|
1240
|
+
"qwen": "skill-md",
|
|
1241
|
+
"vercel": "skill-md",
|
|
1242
|
+
"zencoder": "skill-md"
|
|
1037
1243
|
};
|
|
1038
1244
|
var TranslatableSkillFrontmatter = z2.object({
|
|
1039
1245
|
name: z2.string(),
|
|
@@ -15094,6 +15300,111 @@ var AGENT_FORMATS = {
|
|
|
15094
15300
|
directory: "commands",
|
|
15095
15301
|
supportsSlashCommands: true,
|
|
15096
15302
|
supportsCommandFiles: true
|
|
15303
|
+
},
|
|
15304
|
+
cline: {
|
|
15305
|
+
agent: "cline",
|
|
15306
|
+
extension: ".md",
|
|
15307
|
+
directory: ".cline/commands",
|
|
15308
|
+
supportsSlashCommands: true,
|
|
15309
|
+
supportsCommandFiles: true
|
|
15310
|
+
},
|
|
15311
|
+
codebuddy: {
|
|
15312
|
+
agent: "codebuddy",
|
|
15313
|
+
extension: ".md",
|
|
15314
|
+
directory: ".codebuddy/commands",
|
|
15315
|
+
supportsSlashCommands: true,
|
|
15316
|
+
supportsCommandFiles: true
|
|
15317
|
+
},
|
|
15318
|
+
commandcode: {
|
|
15319
|
+
agent: "commandcode",
|
|
15320
|
+
extension: ".md",
|
|
15321
|
+
directory: ".commandcode/commands",
|
|
15322
|
+
supportsSlashCommands: true,
|
|
15323
|
+
supportsCommandFiles: true
|
|
15324
|
+
},
|
|
15325
|
+
continue: {
|
|
15326
|
+
agent: "continue",
|
|
15327
|
+
extension: ".md",
|
|
15328
|
+
directory: ".continue/commands",
|
|
15329
|
+
supportsSlashCommands: true,
|
|
15330
|
+
supportsCommandFiles: true
|
|
15331
|
+
},
|
|
15332
|
+
crush: {
|
|
15333
|
+
agent: "crush",
|
|
15334
|
+
extension: ".md",
|
|
15335
|
+
directory: ".crush/commands",
|
|
15336
|
+
supportsSlashCommands: true,
|
|
15337
|
+
supportsCommandFiles: true
|
|
15338
|
+
},
|
|
15339
|
+
factory: {
|
|
15340
|
+
agent: "factory",
|
|
15341
|
+
extension: ".md",
|
|
15342
|
+
directory: ".factory/commands",
|
|
15343
|
+
supportsSlashCommands: true,
|
|
15344
|
+
supportsCommandFiles: true
|
|
15345
|
+
},
|
|
15346
|
+
mcpjam: {
|
|
15347
|
+
agent: "mcpjam",
|
|
15348
|
+
extension: ".md",
|
|
15349
|
+
directory: ".mcpjam/commands",
|
|
15350
|
+
supportsSlashCommands: true,
|
|
15351
|
+
supportsCommandFiles: true
|
|
15352
|
+
},
|
|
15353
|
+
mux: {
|
|
15354
|
+
agent: "mux",
|
|
15355
|
+
extension: ".md",
|
|
15356
|
+
directory: ".mux/commands",
|
|
15357
|
+
supportsSlashCommands: true,
|
|
15358
|
+
supportsCommandFiles: true
|
|
15359
|
+
},
|
|
15360
|
+
neovate: {
|
|
15361
|
+
agent: "neovate",
|
|
15362
|
+
extension: ".md",
|
|
15363
|
+
directory: ".neovate/commands",
|
|
15364
|
+
supportsSlashCommands: true,
|
|
15365
|
+
supportsCommandFiles: true
|
|
15366
|
+
},
|
|
15367
|
+
openhands: {
|
|
15368
|
+
agent: "openhands",
|
|
15369
|
+
extension: ".md",
|
|
15370
|
+
directory: ".openhands/commands",
|
|
15371
|
+
supportsSlashCommands: true,
|
|
15372
|
+
supportsCommandFiles: true
|
|
15373
|
+
},
|
|
15374
|
+
pi: {
|
|
15375
|
+
agent: "pi",
|
|
15376
|
+
extension: ".md",
|
|
15377
|
+
directory: ".pi/commands",
|
|
15378
|
+
supportsSlashCommands: true,
|
|
15379
|
+
supportsCommandFiles: true
|
|
15380
|
+
},
|
|
15381
|
+
qoder: {
|
|
15382
|
+
agent: "qoder",
|
|
15383
|
+
extension: ".md",
|
|
15384
|
+
directory: ".qoder/commands",
|
|
15385
|
+
supportsSlashCommands: true,
|
|
15386
|
+
supportsCommandFiles: true
|
|
15387
|
+
},
|
|
15388
|
+
qwen: {
|
|
15389
|
+
agent: "qwen",
|
|
15390
|
+
extension: ".md",
|
|
15391
|
+
directory: ".qwen/commands",
|
|
15392
|
+
supportsSlashCommands: true,
|
|
15393
|
+
supportsCommandFiles: true
|
|
15394
|
+
},
|
|
15395
|
+
vercel: {
|
|
15396
|
+
agent: "vercel",
|
|
15397
|
+
extension: ".md",
|
|
15398
|
+
directory: ".vercel/commands",
|
|
15399
|
+
supportsSlashCommands: true,
|
|
15400
|
+
supportsCommandFiles: true
|
|
15401
|
+
},
|
|
15402
|
+
zencoder: {
|
|
15403
|
+
agent: "zencoder",
|
|
15404
|
+
extension: ".md",
|
|
15405
|
+
directory: ".zencoder/commands",
|
|
15406
|
+
supportsSlashCommands: true,
|
|
15407
|
+
supportsCommandFiles: true
|
|
15097
15408
|
}
|
|
15098
15409
|
};
|
|
15099
15410
|
var CommandGenerator = class {
|
|
@@ -16094,22 +16405,40 @@ var AGENT_DISCOVERY_PATHS = {
|
|
|
16094
16405
|
"roo": [".roo/agents", ".roo/modes"],
|
|
16095
16406
|
"trae": [".trae/agents", ".trae/agent"],
|
|
16096
16407
|
"windsurf": [".windsurf/agents", ".windsurf/workflows"],
|
|
16097
|
-
"universal": ["agents", ".agents"]
|
|
16408
|
+
"universal": ["agents", ".agents"],
|
|
16409
|
+
"cline": [".cline/agents"],
|
|
16410
|
+
"codebuddy": [".codebuddy/agents"],
|
|
16411
|
+
"commandcode": [".commandcode/agents"],
|
|
16412
|
+
"continue": [".continue/agents"],
|
|
16413
|
+
"crush": [".crush/agents"],
|
|
16414
|
+
"factory": [".factory/agents"],
|
|
16415
|
+
"mcpjam": [".mcpjam/agents"],
|
|
16416
|
+
"mux": [".mux/agents"],
|
|
16417
|
+
"neovate": [".neovate/agents"],
|
|
16418
|
+
"openhands": [".openhands/agents"],
|
|
16419
|
+
"pi": [".pi/agents"],
|
|
16420
|
+
"qoder": [".qoder/agents"],
|
|
16421
|
+
"qwen": [".qwen/agents"],
|
|
16422
|
+
"vercel": [".vercel/agents"],
|
|
16423
|
+
"zencoder": [".zencoder/agents"]
|
|
16098
16424
|
};
|
|
16099
16425
|
var ALL_AGENT_DISCOVERY_PATHS = [
|
|
16100
16426
|
"agents",
|
|
16101
16427
|
".agents",
|
|
16428
|
+
".amp/agents",
|
|
16429
|
+
".antigravity/agents",
|
|
16102
16430
|
".claude/agents",
|
|
16431
|
+
".cline/agents",
|
|
16432
|
+
".clawdbot/agents",
|
|
16433
|
+
".codebuddy/agents",
|
|
16434
|
+
".codex/agents",
|
|
16435
|
+
".commandcode/agents",
|
|
16436
|
+
".continue/agents",
|
|
16437
|
+
".crush/agents",
|
|
16103
16438
|
".cursor/agents",
|
|
16104
16439
|
".cursor/commands",
|
|
16105
|
-
".codex/agents",
|
|
16106
|
-
".gemini/agents",
|
|
16107
|
-
".opencode/agents",
|
|
16108
|
-
".opencode/agent",
|
|
16109
|
-
".antigravity/agents",
|
|
16110
|
-
".amp/agents",
|
|
16111
|
-
".clawdbot/agents",
|
|
16112
16440
|
".factory/agents",
|
|
16441
|
+
".gemini/agents",
|
|
16113
16442
|
".github/agents",
|
|
16114
16443
|
".github/instructions",
|
|
16115
16444
|
".github/custom-agents",
|
|
@@ -16117,12 +16446,23 @@ var ALL_AGENT_DISCOVERY_PATHS = [
|
|
|
16117
16446
|
".kilocode/agents",
|
|
16118
16447
|
".kilocode/modes",
|
|
16119
16448
|
".kiro/agents",
|
|
16449
|
+
".mcpjam/agents",
|
|
16450
|
+
".mux/agents",
|
|
16451
|
+
".neovate/agents",
|
|
16452
|
+
".opencode/agents",
|
|
16453
|
+
".opencode/agent",
|
|
16454
|
+
".openhands/agents",
|
|
16455
|
+
".pi/agents",
|
|
16456
|
+
".qoder/agents",
|
|
16457
|
+
".qwen/agents",
|
|
16120
16458
|
".roo/agents",
|
|
16121
16459
|
".roo/modes",
|
|
16122
16460
|
".trae/agents",
|
|
16123
16461
|
".trae/agent",
|
|
16462
|
+
".vercel/agents",
|
|
16124
16463
|
".windsurf/agents",
|
|
16125
|
-
".windsurf/workflows"
|
|
16464
|
+
".windsurf/workflows",
|
|
16465
|
+
".zencoder/agents"
|
|
16126
16466
|
];
|
|
16127
16467
|
var CUSTOM_AGENT_FORMAT_MAP = {
|
|
16128
16468
|
"claude-code": "claude-agent",
|
|
@@ -16141,7 +16481,22 @@ var CUSTOM_AGENT_FORMAT_MAP = {
|
|
|
16141
16481
|
"roo": "claude-agent",
|
|
16142
16482
|
"trae": "claude-agent",
|
|
16143
16483
|
"windsurf": "universal",
|
|
16144
|
-
"universal": "universal"
|
|
16484
|
+
"universal": "universal",
|
|
16485
|
+
"cline": "claude-agent",
|
|
16486
|
+
"codebuddy": "claude-agent",
|
|
16487
|
+
"commandcode": "claude-agent",
|
|
16488
|
+
"continue": "claude-agent",
|
|
16489
|
+
"crush": "claude-agent",
|
|
16490
|
+
"factory": "claude-agent",
|
|
16491
|
+
"mcpjam": "claude-agent",
|
|
16492
|
+
"mux": "claude-agent",
|
|
16493
|
+
"neovate": "claude-agent",
|
|
16494
|
+
"openhands": "claude-agent",
|
|
16495
|
+
"pi": "claude-agent",
|
|
16496
|
+
"qoder": "claude-agent",
|
|
16497
|
+
"qwen": "claude-agent",
|
|
16498
|
+
"vercel": "claude-agent",
|
|
16499
|
+
"zencoder": "claude-agent"
|
|
16145
16500
|
};
|
|
16146
16501
|
|
|
16147
16502
|
// src/agents/parser.ts
|
|
@@ -17367,6 +17722,798 @@ function escapeXml(text) {
|
|
|
17367
17722
|
}
|
|
17368
17723
|
var getAgentSkillsDir = getSkillsDir;
|
|
17369
17724
|
var getAgentConfigFile = getConfigFile;
|
|
17725
|
+
|
|
17726
|
+
// src/manifest/index.ts
|
|
17727
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync18, existsSync as existsSync33 } from "fs";
|
|
17728
|
+
import { join as join34, dirname as dirname12 } from "path";
|
|
17729
|
+
import { parse as parseYaml12, stringify as stringifyYaml9 } from "yaml";
|
|
17730
|
+
var MANIFEST_FILENAMES = [".skills", ".skills.yaml", ".skills.yml", "skills.yaml"];
|
|
17731
|
+
function findManifestPath(startDir = process.cwd()) {
|
|
17732
|
+
let dir = startDir;
|
|
17733
|
+
while (dir !== dirname12(dir)) {
|
|
17734
|
+
for (const filename of MANIFEST_FILENAMES) {
|
|
17735
|
+
const manifestPath = join34(dir, filename);
|
|
17736
|
+
if (existsSync33(manifestPath)) {
|
|
17737
|
+
return manifestPath;
|
|
17738
|
+
}
|
|
17739
|
+
}
|
|
17740
|
+
dir = dirname12(dir);
|
|
17741
|
+
}
|
|
17742
|
+
return null;
|
|
17743
|
+
}
|
|
17744
|
+
function loadManifest(manifestPath) {
|
|
17745
|
+
const path2 = manifestPath || findManifestPath();
|
|
17746
|
+
if (!path2 || !existsSync33(path2)) {
|
|
17747
|
+
return null;
|
|
17748
|
+
}
|
|
17749
|
+
try {
|
|
17750
|
+
const content = readFileSync25(path2, "utf-8");
|
|
17751
|
+
const parsed = parseYaml12(content);
|
|
17752
|
+
if (!parsed || typeof parsed !== "object") {
|
|
17753
|
+
return null;
|
|
17754
|
+
}
|
|
17755
|
+
return {
|
|
17756
|
+
version: parsed.version || 1,
|
|
17757
|
+
skills: normalizeSkills(parsed.skills || []),
|
|
17758
|
+
agents: parsed.agents,
|
|
17759
|
+
installMethod: parsed.installMethod,
|
|
17760
|
+
updatedAt: parsed.updatedAt
|
|
17761
|
+
};
|
|
17762
|
+
} catch {
|
|
17763
|
+
return null;
|
|
17764
|
+
}
|
|
17765
|
+
}
|
|
17766
|
+
function normalizeSkills(skills) {
|
|
17767
|
+
return skills.map((skill) => {
|
|
17768
|
+
if (typeof skill === "string") {
|
|
17769
|
+
const parts = skill.split("/");
|
|
17770
|
+
if (parts.length >= 3) {
|
|
17771
|
+
return {
|
|
17772
|
+
source: `${parts[0]}/${parts[1]}`,
|
|
17773
|
+
skills: [parts.slice(2).join("/")],
|
|
17774
|
+
enabled: true
|
|
17775
|
+
};
|
|
17776
|
+
}
|
|
17777
|
+
return { source: skill, enabled: true };
|
|
17778
|
+
}
|
|
17779
|
+
if (typeof skill === "object" && skill !== null) {
|
|
17780
|
+
const entry = skill;
|
|
17781
|
+
return {
|
|
17782
|
+
source: String(entry.source || ""),
|
|
17783
|
+
skills: entry.skills,
|
|
17784
|
+
agents: entry.agents,
|
|
17785
|
+
enabled: entry.enabled !== false
|
|
17786
|
+
};
|
|
17787
|
+
}
|
|
17788
|
+
return { source: "", enabled: false };
|
|
17789
|
+
}).filter((s) => s.source);
|
|
17790
|
+
}
|
|
17791
|
+
function saveManifest(manifest, manifestPath) {
|
|
17792
|
+
const path2 = manifestPath || join34(process.cwd(), ".skills");
|
|
17793
|
+
const content = stringifyYaml9({
|
|
17794
|
+
version: manifest.version || 1,
|
|
17795
|
+
skills: manifest.skills.map((s) => {
|
|
17796
|
+
if (!s.skills && !s.agents && s.enabled !== false) {
|
|
17797
|
+
return s.source;
|
|
17798
|
+
}
|
|
17799
|
+
return s;
|
|
17800
|
+
}),
|
|
17801
|
+
...manifest.agents && { agents: manifest.agents },
|
|
17802
|
+
...manifest.installMethod && { installMethod: manifest.installMethod },
|
|
17803
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17804
|
+
});
|
|
17805
|
+
writeFileSync18(path2, content, "utf-8");
|
|
17806
|
+
}
|
|
17807
|
+
function addToManifest(source, options, manifestPath) {
|
|
17808
|
+
const existing = loadManifest(manifestPath) || {
|
|
17809
|
+
version: 1,
|
|
17810
|
+
skills: []
|
|
17811
|
+
};
|
|
17812
|
+
const existingIndex = existing.skills.findIndex((s) => s.source === source);
|
|
17813
|
+
if (existingIndex >= 0) {
|
|
17814
|
+
existing.skills[existingIndex] = {
|
|
17815
|
+
...existing.skills[existingIndex],
|
|
17816
|
+
...options,
|
|
17817
|
+
enabled: true
|
|
17818
|
+
};
|
|
17819
|
+
} else {
|
|
17820
|
+
existing.skills.push({
|
|
17821
|
+
source,
|
|
17822
|
+
...options,
|
|
17823
|
+
enabled: true
|
|
17824
|
+
});
|
|
17825
|
+
}
|
|
17826
|
+
saveManifest(existing, manifestPath);
|
|
17827
|
+
return existing;
|
|
17828
|
+
}
|
|
17829
|
+
function removeFromManifest(source, manifestPath) {
|
|
17830
|
+
const existing = loadManifest(manifestPath);
|
|
17831
|
+
if (!existing) {
|
|
17832
|
+
return null;
|
|
17833
|
+
}
|
|
17834
|
+
existing.skills = existing.skills.filter((s) => s.source !== source);
|
|
17835
|
+
saveManifest(existing, manifestPath);
|
|
17836
|
+
return existing;
|
|
17837
|
+
}
|
|
17838
|
+
function initManifest(options, manifestPath) {
|
|
17839
|
+
const manifest = {
|
|
17840
|
+
version: 1,
|
|
17841
|
+
skills: [],
|
|
17842
|
+
...options,
|
|
17843
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17844
|
+
};
|
|
17845
|
+
saveManifest(manifest, manifestPath);
|
|
17846
|
+
return manifest;
|
|
17847
|
+
}
|
|
17848
|
+
function generateManifestFromInstalled(installedSkills) {
|
|
17849
|
+
const skillsBySource = /* @__PURE__ */ new Map();
|
|
17850
|
+
for (const skill of installedSkills) {
|
|
17851
|
+
if (!skill.source) continue;
|
|
17852
|
+
const existing = skillsBySource.get(skill.source);
|
|
17853
|
+
if (existing) {
|
|
17854
|
+
existing.skills.push(skill.name);
|
|
17855
|
+
if (skill.agents) {
|
|
17856
|
+
skill.agents.forEach((a) => existing.agents.add(a));
|
|
17857
|
+
}
|
|
17858
|
+
} else {
|
|
17859
|
+
skillsBySource.set(skill.source, {
|
|
17860
|
+
skills: [skill.name],
|
|
17861
|
+
agents: new Set(skill.agents || [])
|
|
17862
|
+
});
|
|
17863
|
+
}
|
|
17864
|
+
}
|
|
17865
|
+
const skills = [];
|
|
17866
|
+
for (const [source, data] of skillsBySource) {
|
|
17867
|
+
skills.push({
|
|
17868
|
+
source,
|
|
17869
|
+
skills: data.skills.length > 0 ? data.skills : void 0,
|
|
17870
|
+
agents: data.agents.size > 0 ? Array.from(data.agents) : void 0,
|
|
17871
|
+
enabled: true
|
|
17872
|
+
});
|
|
17873
|
+
}
|
|
17874
|
+
return {
|
|
17875
|
+
version: 1,
|
|
17876
|
+
skills,
|
|
17877
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17878
|
+
};
|
|
17879
|
+
}
|
|
17880
|
+
|
|
17881
|
+
// src/quality/index.ts
|
|
17882
|
+
import { readFileSync as readFileSync26, existsSync as existsSync34 } from "fs";
|
|
17883
|
+
import { join as join35, basename as basename12 } from "path";
|
|
17884
|
+
|
|
17885
|
+
// src/quality/benchmark.ts
|
|
17886
|
+
var CATEGORY_BENCHMARKS = {
|
|
17887
|
+
react: {
|
|
17888
|
+
category: "react",
|
|
17889
|
+
avgScore: 78,
|
|
17890
|
+
topScore: 95,
|
|
17891
|
+
topSkills: ["react-patterns", "react-hooks-best-practices"],
|
|
17892
|
+
count: 150,
|
|
17893
|
+
distribution: { A: 15, B: 35, C: 30, D: 15, F: 5 }
|
|
17894
|
+
},
|
|
17895
|
+
typescript: {
|
|
17896
|
+
category: "typescript",
|
|
17897
|
+
avgScore: 75,
|
|
17898
|
+
topScore: 92,
|
|
17899
|
+
topSkills: ["typescript-strict", "type-safety-patterns"],
|
|
17900
|
+
count: 120,
|
|
17901
|
+
distribution: { A: 12, B: 30, C: 35, D: 18, F: 5 }
|
|
17902
|
+
},
|
|
17903
|
+
testing: {
|
|
17904
|
+
category: "testing",
|
|
17905
|
+
avgScore: 72,
|
|
17906
|
+
topScore: 90,
|
|
17907
|
+
topSkills: ["tdd-workflow", "testing-best-practices"],
|
|
17908
|
+
count: 80,
|
|
17909
|
+
distribution: { A: 10, B: 28, C: 38, D: 19, F: 5 }
|
|
17910
|
+
},
|
|
17911
|
+
git: {
|
|
17912
|
+
category: "git",
|
|
17913
|
+
avgScore: 80,
|
|
17914
|
+
topScore: 94,
|
|
17915
|
+
topSkills: ["git-workflow", "conventional-commits"],
|
|
17916
|
+
count: 60,
|
|
17917
|
+
distribution: { A: 18, B: 40, C: 28, D: 12, F: 2 }
|
|
17918
|
+
},
|
|
17919
|
+
security: {
|
|
17920
|
+
category: "security",
|
|
17921
|
+
avgScore: 76,
|
|
17922
|
+
topScore: 93,
|
|
17923
|
+
topSkills: ["security-review", "owasp-patterns"],
|
|
17924
|
+
count: 45,
|
|
17925
|
+
distribution: { A: 14, B: 32, C: 34, D: 16, F: 4 }
|
|
17926
|
+
},
|
|
17927
|
+
api: {
|
|
17928
|
+
category: "api",
|
|
17929
|
+
avgScore: 74,
|
|
17930
|
+
topScore: 91,
|
|
17931
|
+
topSkills: ["api-design", "rest-best-practices"],
|
|
17932
|
+
count: 55,
|
|
17933
|
+
distribution: { A: 11, B: 30, C: 36, D: 18, F: 5 }
|
|
17934
|
+
},
|
|
17935
|
+
general: {
|
|
17936
|
+
category: "general",
|
|
17937
|
+
avgScore: 70,
|
|
17938
|
+
topScore: 88,
|
|
17939
|
+
topSkills: ["code-review", "best-practices"],
|
|
17940
|
+
count: 200,
|
|
17941
|
+
distribution: { A: 8, B: 25, C: 40, D: 22, F: 5 }
|
|
17942
|
+
}
|
|
17943
|
+
};
|
|
17944
|
+
function getGrade(score) {
|
|
17945
|
+
if (score >= 90) return "A";
|
|
17946
|
+
if (score >= 80) return "B";
|
|
17947
|
+
if (score >= 70) return "C";
|
|
17948
|
+
if (score >= 60) return "D";
|
|
17949
|
+
return "F";
|
|
17950
|
+
}
|
|
17951
|
+
function detectCategory(skillName, tags = []) {
|
|
17952
|
+
const lowerName = skillName.toLowerCase();
|
|
17953
|
+
const lowerTags = tags.map((t) => t.toLowerCase());
|
|
17954
|
+
const searchTerms = [lowerName, ...lowerTags];
|
|
17955
|
+
const categoryKeywords = {
|
|
17956
|
+
react: ["react", "hooks", "jsx", "tsx", "component", "nextjs", "remix"],
|
|
17957
|
+
typescript: ["typescript", "type", "types", "ts", "strict"],
|
|
17958
|
+
testing: ["test", "testing", "tdd", "jest", "vitest", "playwright", "e2e"],
|
|
17959
|
+
git: ["git", "commit", "branch", "merge", "workflow", "conventional"],
|
|
17960
|
+
security: ["security", "auth", "owasp", "vulnerability", "safe"],
|
|
17961
|
+
api: ["api", "rest", "graphql", "endpoint", "http"]
|
|
17962
|
+
};
|
|
17963
|
+
for (const [category, keywords] of Object.entries(categoryKeywords)) {
|
|
17964
|
+
for (const term of searchTerms) {
|
|
17965
|
+
if (keywords.some((kw) => term.includes(kw))) {
|
|
17966
|
+
return category;
|
|
17967
|
+
}
|
|
17968
|
+
}
|
|
17969
|
+
}
|
|
17970
|
+
return "general";
|
|
17971
|
+
}
|
|
17972
|
+
function calculatePercentile(score, categoryStats) {
|
|
17973
|
+
const { distribution } = categoryStats;
|
|
17974
|
+
const totalSkills = distribution.A + distribution.B + distribution.C + distribution.D + distribution.F;
|
|
17975
|
+
let percentBelow = 0;
|
|
17976
|
+
if (score < 60) {
|
|
17977
|
+
percentBelow = score / 60 * (distribution.F / totalSkills) * 100;
|
|
17978
|
+
} else if (score < 70) {
|
|
17979
|
+
percentBelow = distribution.F / totalSkills * 100;
|
|
17980
|
+
percentBelow += (score - 60) / 10 * (distribution.D / totalSkills) * 100;
|
|
17981
|
+
} else if (score < 80) {
|
|
17982
|
+
percentBelow = (distribution.F + distribution.D) / totalSkills * 100;
|
|
17983
|
+
percentBelow += (score - 70) / 10 * (distribution.C / totalSkills) * 100;
|
|
17984
|
+
} else if (score < 90) {
|
|
17985
|
+
percentBelow = (distribution.F + distribution.D + distribution.C) / totalSkills * 100;
|
|
17986
|
+
percentBelow += (score - 80) / 10 * (distribution.B / totalSkills) * 100;
|
|
17987
|
+
} else {
|
|
17988
|
+
percentBelow = (distribution.F + distribution.D + distribution.C + distribution.B) / totalSkills * 100;
|
|
17989
|
+
percentBelow += (score - 90) / 10 * (distribution.A / totalSkills) * 100;
|
|
17990
|
+
}
|
|
17991
|
+
return Math.round(Math.min(99, Math.max(1, percentBelow)));
|
|
17992
|
+
}
|
|
17993
|
+
function generateComparisonNotes(quality, categoryStats) {
|
|
17994
|
+
const notes = [];
|
|
17995
|
+
const topScore = categoryStats.topScore;
|
|
17996
|
+
const avgScore = categoryStats.avgScore;
|
|
17997
|
+
if (quality.overall >= topScore) {
|
|
17998
|
+
notes.push("Your skill is among the top performers in this category");
|
|
17999
|
+
} else if (quality.overall >= avgScore) {
|
|
18000
|
+
notes.push(`Your skill is above the category average (${avgScore})`);
|
|
18001
|
+
} else {
|
|
18002
|
+
notes.push(`Your skill is ${avgScore - quality.overall} points below the category average`);
|
|
18003
|
+
}
|
|
18004
|
+
if (!quality.structure.hasExamples) {
|
|
18005
|
+
notes.push("Missing code examples (present in 95% of top skills)");
|
|
18006
|
+
}
|
|
18007
|
+
if (!quality.structure.hasTriggers) {
|
|
18008
|
+
notes.push("Missing trigger conditions (present in 80% of top skills)");
|
|
18009
|
+
}
|
|
18010
|
+
if (!quality.structure.hasBoundaries) {
|
|
18011
|
+
notes.push('Missing "When Not to Use" section (present in 80% of top skills)');
|
|
18012
|
+
}
|
|
18013
|
+
if (quality.specificity.vagueTermCount > 3) {
|
|
18014
|
+
notes.push("Trigger conditions are less specific than category average");
|
|
18015
|
+
}
|
|
18016
|
+
if (quality.clarity.lineCount > 300) {
|
|
18017
|
+
notes.push("Skill is longer than recommended (top skills average 150-250 lines)");
|
|
18018
|
+
}
|
|
18019
|
+
if (quality.advanced.deprecatedPatterns.length > 0) {
|
|
18020
|
+
notes.push("Contains deprecated patterns not found in top skills");
|
|
18021
|
+
}
|
|
18022
|
+
return notes;
|
|
18023
|
+
}
|
|
18024
|
+
function generateRecommendations(quality, categoryStats) {
|
|
18025
|
+
const recommendations = [];
|
|
18026
|
+
const gap = categoryStats.topScore - quality.overall;
|
|
18027
|
+
if (gap > 20) {
|
|
18028
|
+
recommendations.push("Consider studying top skills in this category for patterns");
|
|
18029
|
+
}
|
|
18030
|
+
if (!quality.structure.hasExamples) {
|
|
18031
|
+
recommendations.push(`Add ${quality.specificity.hasCodeExamples ? "more" : ""} code examples showing input/output`);
|
|
18032
|
+
}
|
|
18033
|
+
if (!quality.structure.hasTriggers) {
|
|
18034
|
+
recommendations.push('Add explicit trigger conditions with patterns like "Triggers when:"');
|
|
18035
|
+
}
|
|
18036
|
+
if (!quality.structure.hasBoundaries) {
|
|
18037
|
+
recommendations.push('Add a "Boundaries" or "Limitations" section');
|
|
18038
|
+
}
|
|
18039
|
+
if (quality.clarity.lineCount > 400) {
|
|
18040
|
+
recommendations.push("Split into multiple focused skills (top skills are 150-250 lines)");
|
|
18041
|
+
}
|
|
18042
|
+
if (quality.specificity.vagueTermCount > 0) {
|
|
18043
|
+
recommendations.push(`Replace ${quality.specificity.vagueTermCount} vague term(s) with specific instructions`);
|
|
18044
|
+
}
|
|
18045
|
+
if (quality.advanced.completeness.hasTodos) {
|
|
18046
|
+
recommendations.push("Complete TODO items before publishing");
|
|
18047
|
+
}
|
|
18048
|
+
return recommendations;
|
|
18049
|
+
}
|
|
18050
|
+
function benchmarkSkill(skillName, quality, tags = [], customCategoryStats) {
|
|
18051
|
+
const category = detectCategory(skillName, tags);
|
|
18052
|
+
const categoryStats = customCategoryStats || CATEGORY_BENCHMARKS[category] || CATEGORY_BENCHMARKS.general;
|
|
18053
|
+
const percentile = calculatePercentile(quality.overall, categoryStats);
|
|
18054
|
+
const comparisonNotes = generateComparisonNotes(quality, categoryStats);
|
|
18055
|
+
const recommendations = generateRecommendations(quality, categoryStats);
|
|
18056
|
+
return {
|
|
18057
|
+
skill: skillName,
|
|
18058
|
+
score: quality.overall,
|
|
18059
|
+
grade: getGrade(quality.overall),
|
|
18060
|
+
categoryAvg: categoryStats.avgScore,
|
|
18061
|
+
topSkillScore: categoryStats.topScore,
|
|
18062
|
+
percentile,
|
|
18063
|
+
comparisonNotes,
|
|
18064
|
+
recommendations
|
|
18065
|
+
};
|
|
18066
|
+
}
|
|
18067
|
+
function getCategoryStats(category) {
|
|
18068
|
+
return CATEGORY_BENCHMARKS[category] || null;
|
|
18069
|
+
}
|
|
18070
|
+
function getAllCategories() {
|
|
18071
|
+
return Object.keys(CATEGORY_BENCHMARKS);
|
|
18072
|
+
}
|
|
18073
|
+
|
|
18074
|
+
// src/quality/index.ts
|
|
18075
|
+
var VAGUE_TERMS = [
|
|
18076
|
+
"be helpful",
|
|
18077
|
+
"assist the user",
|
|
18078
|
+
"help with",
|
|
18079
|
+
"try to",
|
|
18080
|
+
"attempt to",
|
|
18081
|
+
"do your best",
|
|
18082
|
+
"as needed",
|
|
18083
|
+
"when appropriate",
|
|
18084
|
+
"if necessary",
|
|
18085
|
+
"general purpose",
|
|
18086
|
+
"various tasks",
|
|
18087
|
+
"many things",
|
|
18088
|
+
"etc.",
|
|
18089
|
+
"and so on",
|
|
18090
|
+
"stuff like that"
|
|
18091
|
+
];
|
|
18092
|
+
var BOUNDARY_PATTERNS = [
|
|
18093
|
+
/never\s+(?:do|use|commit|push|delete|remove)/i,
|
|
18094
|
+
/always\s+(?:do|use|check|verify|ensure)/i,
|
|
18095
|
+
/don'?t\s+(?:do|use|commit|push|delete)/i,
|
|
18096
|
+
/avoid\s+(?:using|doing|committing)/i,
|
|
18097
|
+
/must\s+(?:not|always|never)/i,
|
|
18098
|
+
/forbidden/i,
|
|
18099
|
+
/prohibited/i,
|
|
18100
|
+
/required/i
|
|
18101
|
+
];
|
|
18102
|
+
var TRIGGER_PATTERNS = [
|
|
18103
|
+
/when\s+to\s+use/i,
|
|
18104
|
+
/use\s+this\s+(?:skill|when)/i,
|
|
18105
|
+
/triggers?\s*(?:when|:)/i,
|
|
18106
|
+
/activated?\s+(?:when|by)/i,
|
|
18107
|
+
/applies?\s+(?:when|to)/i,
|
|
18108
|
+
/invoke\s+(?:when|this)/i
|
|
18109
|
+
];
|
|
18110
|
+
var COMMAND_PATTERNS = [
|
|
18111
|
+
/```(?:bash|sh|shell|zsh)[\s\S]*?```/g,
|
|
18112
|
+
/`(?:npm|pnpm|yarn|bun|npx|git|docker|kubectl)\s+[^`]+`/g,
|
|
18113
|
+
/\$\s*\w+/g
|
|
18114
|
+
];
|
|
18115
|
+
var CODE_EXAMPLE_PATTERNS = [
|
|
18116
|
+
/```(?:typescript|javascript|tsx|jsx|python|go|rust|java)[\s\S]*?```/g,
|
|
18117
|
+
/```[\s\S]{50,}?```/g
|
|
18118
|
+
];
|
|
18119
|
+
var FILE_PATTERN_PATTERNS = [
|
|
18120
|
+
/\*\*\/\*\.\w+/,
|
|
18121
|
+
/\.\w+$/m,
|
|
18122
|
+
/glob[s]?\s*[:=]/i,
|
|
18123
|
+
/include[s]?\s*[:=]/i,
|
|
18124
|
+
/pattern[s]?\s*[:=]/i
|
|
18125
|
+
];
|
|
18126
|
+
var DEPRECATED_PATTERNS = [
|
|
18127
|
+
{ pattern: /require\s*\(['"][^'"]+['"]\)/g, message: "Uses CommonJS require() instead of ES modules" },
|
|
18128
|
+
{ pattern: /React\.Component/g, message: "Uses class components instead of functional" },
|
|
18129
|
+
{ pattern: /componentDidMount|componentWillUnmount|componentDidUpdate/g, message: "Uses lifecycle methods instead of hooks" },
|
|
18130
|
+
{ pattern: /\bvar\s+\w+\s*=/g, message: "Uses var instead of const/let" },
|
|
18131
|
+
{ pattern: /\.then\s*\([^)]*\)\.catch/g, message: "Uses .then().catch() instead of async/await" },
|
|
18132
|
+
{ pattern: /new\s+Promise\s*\(/g, message: "Consider using async/await instead of new Promise()" }
|
|
18133
|
+
];
|
|
18134
|
+
var SECURITY_PATTERNS = [
|
|
18135
|
+
{ pattern: /password\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded password" },
|
|
18136
|
+
{ pattern: /api[_-]?key\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded API key" },
|
|
18137
|
+
{ pattern: /secret\s*[:=]\s*['"][^'"]+['"]/gi, message: "Potential hardcoded secret" },
|
|
18138
|
+
{ pattern: /token\s*[:=]\s*['"][A-Za-z0-9_-]{20,}['"]/gi, message: "Potential hardcoded token" },
|
|
18139
|
+
{ pattern: /\$\{[^}]*\}/g, message: "Template literal - ensure proper sanitization in shell commands" },
|
|
18140
|
+
{ pattern: /eval\s*\(/g, message: "Uses eval() - potential code injection risk" },
|
|
18141
|
+
{ pattern: /innerHTML\s*=/g, message: "Uses innerHTML - potential XSS risk" },
|
|
18142
|
+
{ pattern: /dangerouslySetInnerHTML/g, message: "Uses dangerouslySetInnerHTML - potential XSS risk" }
|
|
18143
|
+
];
|
|
18144
|
+
function extractFrontmatter4(content) {
|
|
18145
|
+
const normalizedContent = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
18146
|
+
const match = normalizedContent.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
18147
|
+
if (!match) return null;
|
|
18148
|
+
const frontmatter = {};
|
|
18149
|
+
const lines = match[1].split("\n");
|
|
18150
|
+
for (const line of lines) {
|
|
18151
|
+
const colonIndex = line.indexOf(":");
|
|
18152
|
+
if (colonIndex > 0) {
|
|
18153
|
+
const key = line.slice(0, colonIndex).trim();
|
|
18154
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
18155
|
+
frontmatter[key] = value;
|
|
18156
|
+
}
|
|
18157
|
+
}
|
|
18158
|
+
return Object.keys(frontmatter).length > 0 ? frontmatter : null;
|
|
18159
|
+
}
|
|
18160
|
+
function countTokens(text) {
|
|
18161
|
+
return Math.ceil(text.length / 4);
|
|
18162
|
+
}
|
|
18163
|
+
function countVagueTerms(content) {
|
|
18164
|
+
const lowerContent = content.toLowerCase();
|
|
18165
|
+
let count = 0;
|
|
18166
|
+
for (const term of VAGUE_TERMS) {
|
|
18167
|
+
const regex = new RegExp(term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
18168
|
+
const matches = lowerContent.match(regex);
|
|
18169
|
+
if (matches) count += matches.length;
|
|
18170
|
+
}
|
|
18171
|
+
return count;
|
|
18172
|
+
}
|
|
18173
|
+
function hasPattern(content, patterns) {
|
|
18174
|
+
return patterns.some((p) => p.test(content));
|
|
18175
|
+
}
|
|
18176
|
+
function countMatches(content, patterns) {
|
|
18177
|
+
let count = 0;
|
|
18178
|
+
for (const pattern of patterns) {
|
|
18179
|
+
const matches = content.match(pattern);
|
|
18180
|
+
if (matches) count += matches.length;
|
|
18181
|
+
}
|
|
18182
|
+
return count;
|
|
18183
|
+
}
|
|
18184
|
+
function calculateAvgSentenceLength(content) {
|
|
18185
|
+
const contentWithoutCode = content.replace(/```[\s\S]*?```/g, "");
|
|
18186
|
+
const sentences = contentWithoutCode.split(/[.!?]+/).filter((s) => s.trim().length > 0);
|
|
18187
|
+
if (sentences.length === 0) return 0;
|
|
18188
|
+
const totalWords = sentences.reduce((sum, s) => sum + s.trim().split(/\s+/).length, 0);
|
|
18189
|
+
return Math.round(totalWords / sentences.length);
|
|
18190
|
+
}
|
|
18191
|
+
function evaluateStructure(content) {
|
|
18192
|
+
const frontmatter = extractFrontmatter4(content);
|
|
18193
|
+
const hasMetadata = frontmatter !== null && Object.keys(frontmatter).length > 0;
|
|
18194
|
+
const hasDescription = !!frontmatter?.description || /^#+\s*description/im.test(content);
|
|
18195
|
+
const hasTriggers = hasPattern(content, TRIGGER_PATTERNS);
|
|
18196
|
+
const hasExamples = countMatches(content, CODE_EXAMPLE_PATTERNS) > 0;
|
|
18197
|
+
const hasBoundaries = hasPattern(content, BOUNDARY_PATTERNS);
|
|
18198
|
+
const hasWhenToUse = /when\s+to\s+use|use\s+case|scenario/i.test(content);
|
|
18199
|
+
let score = 0;
|
|
18200
|
+
if (hasMetadata) score += 15;
|
|
18201
|
+
if (hasDescription) score += 10;
|
|
18202
|
+
if (hasTriggers) score += 20;
|
|
18203
|
+
if (hasExamples) score += 20;
|
|
18204
|
+
if (hasBoundaries) score += 20;
|
|
18205
|
+
if (hasWhenToUse) score += 15;
|
|
18206
|
+
return {
|
|
18207
|
+
score: Math.min(100, score),
|
|
18208
|
+
hasMetadata,
|
|
18209
|
+
hasDescription,
|
|
18210
|
+
hasTriggers,
|
|
18211
|
+
hasExamples,
|
|
18212
|
+
hasBoundaries,
|
|
18213
|
+
hasWhenToUse
|
|
18214
|
+
};
|
|
18215
|
+
}
|
|
18216
|
+
function evaluateClarity(content) {
|
|
18217
|
+
const lines = content.split("\n");
|
|
18218
|
+
const lineCount = lines.length;
|
|
18219
|
+
const tokenCount = countTokens(content);
|
|
18220
|
+
const avgSentenceLength = calculateAvgSentenceLength(content);
|
|
18221
|
+
const hasHeaders = /^#+\s+/m.test(content);
|
|
18222
|
+
let score = 100;
|
|
18223
|
+
if (lineCount > 500) score -= 30;
|
|
18224
|
+
else if (lineCount > 300) score -= 15;
|
|
18225
|
+
else if (lineCount > 150) score -= 5;
|
|
18226
|
+
if (tokenCount > 4e3) score -= 30;
|
|
18227
|
+
else if (tokenCount > 2e3) score -= 15;
|
|
18228
|
+
else if (tokenCount > 1e3) score -= 5;
|
|
18229
|
+
if (avgSentenceLength > 30) score -= 20;
|
|
18230
|
+
else if (avgSentenceLength > 20) score -= 10;
|
|
18231
|
+
if (!hasHeaders) score -= 15;
|
|
18232
|
+
return {
|
|
18233
|
+
score: Math.max(0, score),
|
|
18234
|
+
lineCount,
|
|
18235
|
+
tokenCount,
|
|
18236
|
+
avgSentenceLength,
|
|
18237
|
+
hasHeaders
|
|
18238
|
+
};
|
|
18239
|
+
}
|
|
18240
|
+
function countCodeBlocks(content) {
|
|
18241
|
+
const fencedBlocks = content.match(/```[\s\S]*?```/g) || [];
|
|
18242
|
+
return fencedBlocks.length;
|
|
18243
|
+
}
|
|
18244
|
+
function detectDeprecatedPatterns(content) {
|
|
18245
|
+
const codeBlocks = content.match(/```[\s\S]*?```/g) || [];
|
|
18246
|
+
const codeContent = codeBlocks.join("\n");
|
|
18247
|
+
const issues = [];
|
|
18248
|
+
for (const { pattern, message } of DEPRECATED_PATTERNS) {
|
|
18249
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
18250
|
+
if (regex.test(codeContent)) {
|
|
18251
|
+
issues.push(message);
|
|
18252
|
+
}
|
|
18253
|
+
}
|
|
18254
|
+
return [...new Set(issues)];
|
|
18255
|
+
}
|
|
18256
|
+
function detectSecurityPatterns(content) {
|
|
18257
|
+
const issues = [];
|
|
18258
|
+
for (const { pattern, message } of SECURITY_PATTERNS) {
|
|
18259
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
18260
|
+
if (regex.test(content)) {
|
|
18261
|
+
if (!message.includes("Template literal") || content.includes("bash") || content.includes("shell")) {
|
|
18262
|
+
issues.push(message);
|
|
18263
|
+
}
|
|
18264
|
+
}
|
|
18265
|
+
}
|
|
18266
|
+
return [...new Set(issues)];
|
|
18267
|
+
}
|
|
18268
|
+
function detectConflictingInstructions(content) {
|
|
18269
|
+
const issues = [];
|
|
18270
|
+
const lowerContent = content.toLowerCase();
|
|
18271
|
+
const alwaysMatches = lowerContent.match(/always\s+(?:use|do|include|add)\s+(\w+)/gi) || [];
|
|
18272
|
+
const neverMatches = lowerContent.match(/never\s+(?:use|do|include|add)\s+(\w+)/gi) || [];
|
|
18273
|
+
for (const always of alwaysMatches) {
|
|
18274
|
+
const term = always.replace(/always\s+(?:use|do|include|add)\s+/i, "").toLowerCase();
|
|
18275
|
+
for (const never of neverMatches) {
|
|
18276
|
+
const neverTerm = never.replace(/never\s+(?:use|do|include|add)\s+/i, "").toLowerCase();
|
|
18277
|
+
if (term === neverTerm) {
|
|
18278
|
+
issues.push(`Conflicting instructions: "always" and "never" used with "${term}"`);
|
|
18279
|
+
}
|
|
18280
|
+
}
|
|
18281
|
+
}
|
|
18282
|
+
const mustMatches = lowerContent.match(/must\s+(\w+)/gi) || [];
|
|
18283
|
+
const mustNotMatches = lowerContent.match(/must\s+not\s+(\w+)/gi) || [];
|
|
18284
|
+
for (const must of mustMatches) {
|
|
18285
|
+
const term = must.replace(/must\s+/i, "").toLowerCase();
|
|
18286
|
+
for (const mustNot of mustNotMatches) {
|
|
18287
|
+
const notTerm = mustNot.replace(/must\s+not\s+/i, "").toLowerCase();
|
|
18288
|
+
if (term === notTerm) {
|
|
18289
|
+
issues.push(`Conflicting instructions: "must" and "must not" used with "${term}"`);
|
|
18290
|
+
}
|
|
18291
|
+
}
|
|
18292
|
+
}
|
|
18293
|
+
return [...new Set(issues)];
|
|
18294
|
+
}
|
|
18295
|
+
function assessCompleteness(content) {
|
|
18296
|
+
const todoMatches = content.match(/TODO|FIXME|XXX|HACK/gi) || [];
|
|
18297
|
+
const todoCount = todoMatches.length;
|
|
18298
|
+
const headerPositions = [];
|
|
18299
|
+
const lines = content.split("\n");
|
|
18300
|
+
let inFence = false;
|
|
18301
|
+
let offset = 0;
|
|
18302
|
+
for (const line of lines) {
|
|
18303
|
+
if (/^```|^~~~/.test(line)) {
|
|
18304
|
+
inFence = !inFence;
|
|
18305
|
+
} else if (!inFence && /^#+\s+.+$/.test(line)) {
|
|
18306
|
+
headerPositions.push({ header: line, index: offset });
|
|
18307
|
+
}
|
|
18308
|
+
offset += line.length + 1;
|
|
18309
|
+
}
|
|
18310
|
+
const emptySections = [];
|
|
18311
|
+
for (let i = 0; i < headerPositions.length - 1; i++) {
|
|
18312
|
+
const current = headerPositions[i];
|
|
18313
|
+
const next = headerPositions[i + 1];
|
|
18314
|
+
const sectionContent = content.slice(current.index + current.header.length, next.index).trim();
|
|
18315
|
+
if (sectionContent.length < 20) {
|
|
18316
|
+
const sectionName = current.header.replace(/^#+\s+/, "");
|
|
18317
|
+
emptySections.push(sectionName);
|
|
18318
|
+
}
|
|
18319
|
+
}
|
|
18320
|
+
if (headerPositions.length > 0) {
|
|
18321
|
+
const last = headerPositions[headerPositions.length - 1];
|
|
18322
|
+
const tailContent = content.slice(last.index + last.header.length).trim();
|
|
18323
|
+
if (tailContent.length < 20) {
|
|
18324
|
+
const sectionName = last.header.replace(/^#+\s+/, "");
|
|
18325
|
+
emptySections.push(sectionName);
|
|
18326
|
+
}
|
|
18327
|
+
}
|
|
18328
|
+
const codeBlocks = countCodeBlocks(content);
|
|
18329
|
+
const exampleCoverage = Math.min(100, codeBlocks * 25);
|
|
18330
|
+
let score = 100;
|
|
18331
|
+
if (todoCount > 0) score -= Math.min(30, todoCount * 10);
|
|
18332
|
+
if (emptySections.length > 0) score -= Math.min(30, emptySections.length * 10);
|
|
18333
|
+
if (codeBlocks < 2) score -= 20;
|
|
18334
|
+
else if (codeBlocks < 4) score -= 10;
|
|
18335
|
+
return {
|
|
18336
|
+
score: Math.max(0, score),
|
|
18337
|
+
hasTodos: todoCount > 0,
|
|
18338
|
+
todoCount,
|
|
18339
|
+
emptySections,
|
|
18340
|
+
exampleCoverage
|
|
18341
|
+
};
|
|
18342
|
+
}
|
|
18343
|
+
function evaluateAdvanced(content) {
|
|
18344
|
+
const deprecatedPatterns = detectDeprecatedPatterns(content);
|
|
18345
|
+
const conflictingInstructions = detectConflictingInstructions(content);
|
|
18346
|
+
const securityIssues = detectSecurityPatterns(content);
|
|
18347
|
+
const completeness = assessCompleteness(content);
|
|
18348
|
+
let score = 100;
|
|
18349
|
+
score -= Math.min(30, deprecatedPatterns.length * 10);
|
|
18350
|
+
score -= Math.min(30, conflictingInstructions.length * 15);
|
|
18351
|
+
score -= Math.min(25, securityIssues.length * 10);
|
|
18352
|
+
score -= Math.round((100 - completeness.score) * 0.15);
|
|
18353
|
+
return {
|
|
18354
|
+
score: Math.max(0, score),
|
|
18355
|
+
deprecatedPatterns,
|
|
18356
|
+
conflictingInstructions,
|
|
18357
|
+
securityIssues,
|
|
18358
|
+
completeness
|
|
18359
|
+
};
|
|
18360
|
+
}
|
|
18361
|
+
function evaluateSpecificity(content) {
|
|
18362
|
+
const hasConcreteCommands = countMatches(content, COMMAND_PATTERNS) > 0;
|
|
18363
|
+
const hasFilePatterns = hasPattern(content, FILE_PATTERN_PATTERNS);
|
|
18364
|
+
const codeBlockCount = countCodeBlocks(content);
|
|
18365
|
+
const hasCodeExamples = codeBlockCount >= 2;
|
|
18366
|
+
const vagueTermCount = countVagueTerms(content);
|
|
18367
|
+
let score = 0;
|
|
18368
|
+
if (hasConcreteCommands) score += 30;
|
|
18369
|
+
if (hasFilePatterns) score += 25;
|
|
18370
|
+
if (hasCodeExamples) score += 30;
|
|
18371
|
+
if (vagueTermCount === 0) score += 15;
|
|
18372
|
+
else if (vagueTermCount <= 2) score += 10;
|
|
18373
|
+
else if (vagueTermCount <= 5) score += 5;
|
|
18374
|
+
return {
|
|
18375
|
+
score: Math.min(100, score),
|
|
18376
|
+
hasConcreteCommands,
|
|
18377
|
+
hasFilePatterns,
|
|
18378
|
+
hasCodeExamples,
|
|
18379
|
+
vagueTermCount
|
|
18380
|
+
};
|
|
18381
|
+
}
|
|
18382
|
+
function generateWarnings(structure, clarity, specificity, advanced) {
|
|
18383
|
+
const warnings = [];
|
|
18384
|
+
if (!structure.hasMetadata) {
|
|
18385
|
+
warnings.push("Missing frontmatter metadata");
|
|
18386
|
+
}
|
|
18387
|
+
if (!structure.hasTriggers) {
|
|
18388
|
+
warnings.push("No trigger conditions defined");
|
|
18389
|
+
}
|
|
18390
|
+
if (!structure.hasBoundaries) {
|
|
18391
|
+
warnings.push("No boundaries or constraints specified");
|
|
18392
|
+
}
|
|
18393
|
+
if (clarity.lineCount > 500) {
|
|
18394
|
+
warnings.push(`Skill is too long (${clarity.lineCount} lines)`);
|
|
18395
|
+
}
|
|
18396
|
+
if (clarity.tokenCount > 4e3) {
|
|
18397
|
+
warnings.push(`High token usage (${clarity.tokenCount} tokens)`);
|
|
18398
|
+
}
|
|
18399
|
+
if (specificity.vagueTermCount > 5) {
|
|
18400
|
+
warnings.push(`Contains ${specificity.vagueTermCount} vague terms`);
|
|
18401
|
+
}
|
|
18402
|
+
if (!structure.hasExamples) {
|
|
18403
|
+
warnings.push("No code examples provided");
|
|
18404
|
+
} else if (!specificity.hasCodeExamples) {
|
|
18405
|
+
warnings.push("Only one code example provided");
|
|
18406
|
+
}
|
|
18407
|
+
for (const issue of advanced.securityIssues) {
|
|
18408
|
+
warnings.push(`Security: ${issue}`);
|
|
18409
|
+
}
|
|
18410
|
+
for (const conflict of advanced.conflictingInstructions) {
|
|
18411
|
+
warnings.push(conflict);
|
|
18412
|
+
}
|
|
18413
|
+
if (advanced.completeness.hasTodos) {
|
|
18414
|
+
warnings.push(`Contains ${advanced.completeness.todoCount} TODO/FIXME comment(s)`);
|
|
18415
|
+
}
|
|
18416
|
+
if (advanced.completeness.emptySections.length > 0) {
|
|
18417
|
+
warnings.push(`Empty sections: ${advanced.completeness.emptySections.join(", ")}`);
|
|
18418
|
+
}
|
|
18419
|
+
return warnings;
|
|
18420
|
+
}
|
|
18421
|
+
function generateSuggestions(structure, clarity, specificity, advanced) {
|
|
18422
|
+
const suggestions = [];
|
|
18423
|
+
if (!structure.hasMetadata) {
|
|
18424
|
+
suggestions.push("Add YAML frontmatter with name, description, and globs");
|
|
18425
|
+
}
|
|
18426
|
+
if (!structure.hasTriggers) {
|
|
18427
|
+
suggestions.push('Add a "When to Use" section with specific trigger conditions');
|
|
18428
|
+
}
|
|
18429
|
+
if (!structure.hasExamples) {
|
|
18430
|
+
suggestions.push("Include code examples showing expected output");
|
|
18431
|
+
}
|
|
18432
|
+
if (!structure.hasBoundaries) {
|
|
18433
|
+
suggestions.push("Define boundaries: what the agent should never do");
|
|
18434
|
+
}
|
|
18435
|
+
if (clarity.lineCount > 300) {
|
|
18436
|
+
suggestions.push("Consider splitting into multiple focused skills");
|
|
18437
|
+
}
|
|
18438
|
+
if (!clarity.hasHeaders) {
|
|
18439
|
+
suggestions.push("Use markdown headers to organize content");
|
|
18440
|
+
}
|
|
18441
|
+
if (specificity.vagueTermCount > 0) {
|
|
18442
|
+
suggestions.push("Replace vague terms with specific instructions");
|
|
18443
|
+
}
|
|
18444
|
+
if (!specificity.hasConcreteCommands) {
|
|
18445
|
+
suggestions.push("Add concrete executable commands with flags");
|
|
18446
|
+
}
|
|
18447
|
+
if (advanced.deprecatedPatterns.length > 0) {
|
|
18448
|
+
suggestions.push("Update code examples to use modern patterns (ES modules, hooks, async/await)");
|
|
18449
|
+
}
|
|
18450
|
+
if (advanced.securityIssues.length > 0) {
|
|
18451
|
+
suggestions.push("Review and remove potential security risks from examples");
|
|
18452
|
+
}
|
|
18453
|
+
if (advanced.completeness.hasTodos) {
|
|
18454
|
+
suggestions.push("Complete or remove TODO/FIXME comments");
|
|
18455
|
+
}
|
|
18456
|
+
if (advanced.completeness.emptySections.length > 0) {
|
|
18457
|
+
suggestions.push("Add content to empty sections or remove them");
|
|
18458
|
+
}
|
|
18459
|
+
if (advanced.completeness.exampleCoverage < 50) {
|
|
18460
|
+
suggestions.push("Add more code examples to improve coverage");
|
|
18461
|
+
}
|
|
18462
|
+
return suggestions;
|
|
18463
|
+
}
|
|
18464
|
+
function evaluateSkillContent(content) {
|
|
18465
|
+
const structure = evaluateStructure(content);
|
|
18466
|
+
const clarity = evaluateClarity(content);
|
|
18467
|
+
const specificity = evaluateSpecificity(content);
|
|
18468
|
+
const advanced = evaluateAdvanced(content);
|
|
18469
|
+
const overall = Math.round(
|
|
18470
|
+
structure.score * 0.35 + clarity.score * 0.25 + specificity.score * 0.25 + advanced.score * 0.15
|
|
18471
|
+
);
|
|
18472
|
+
const warnings = generateWarnings(structure, clarity, specificity, advanced);
|
|
18473
|
+
const suggestions = generateSuggestions(structure, clarity, specificity, advanced);
|
|
18474
|
+
return {
|
|
18475
|
+
overall,
|
|
18476
|
+
structure,
|
|
18477
|
+
clarity,
|
|
18478
|
+
specificity,
|
|
18479
|
+
advanced,
|
|
18480
|
+
warnings,
|
|
18481
|
+
suggestions
|
|
18482
|
+
};
|
|
18483
|
+
}
|
|
18484
|
+
function evaluateSkillFile(filePath) {
|
|
18485
|
+
if (!existsSync34(filePath)) return null;
|
|
18486
|
+
try {
|
|
18487
|
+
const content = readFileSync26(filePath, "utf-8");
|
|
18488
|
+
return evaluateSkillContent(content);
|
|
18489
|
+
} catch {
|
|
18490
|
+
return null;
|
|
18491
|
+
}
|
|
18492
|
+
}
|
|
18493
|
+
function evaluateSkillDirectory(dirPath) {
|
|
18494
|
+
const skillMdPath = join35(dirPath, "SKILL.md");
|
|
18495
|
+
if (existsSync34(skillMdPath)) {
|
|
18496
|
+
return evaluateSkillFile(skillMdPath);
|
|
18497
|
+
}
|
|
18498
|
+
const mdcFiles = ["index.mdc", `${basename12(dirPath)}.mdc`];
|
|
18499
|
+
for (const file of mdcFiles) {
|
|
18500
|
+
const mdcPath = join35(dirPath, file);
|
|
18501
|
+
if (existsSync34(mdcPath)) {
|
|
18502
|
+
return evaluateSkillFile(mdcPath);
|
|
18503
|
+
}
|
|
18504
|
+
}
|
|
18505
|
+
return null;
|
|
18506
|
+
}
|
|
18507
|
+
function getQualityGrade(score) {
|
|
18508
|
+
if (score >= 90) return "A";
|
|
18509
|
+
if (score >= 80) return "B";
|
|
18510
|
+
if (score >= 70) return "C";
|
|
18511
|
+
if (score >= 60) return "D";
|
|
18512
|
+
return "F";
|
|
18513
|
+
}
|
|
18514
|
+
function isHighQuality(score) {
|
|
18515
|
+
return score.overall >= 80 && score.warnings.length <= 2;
|
|
18516
|
+
}
|
|
17370
18517
|
export {
|
|
17371
18518
|
AGENT_CLI_CONFIGS,
|
|
17372
18519
|
AGENT_CONFIG,
|
|
@@ -17462,9 +18609,12 @@ export {
|
|
|
17462
18609
|
WORKFLOW_EXTENSION,
|
|
17463
18610
|
WindsurfTranslator,
|
|
17464
18611
|
WorkflowOrchestrator,
|
|
18612
|
+
addToManifest,
|
|
17465
18613
|
agentExists,
|
|
17466
18614
|
analyzeProject,
|
|
18615
|
+
benchmarkSkill,
|
|
17467
18616
|
buildSkillIndex,
|
|
18617
|
+
calculatePercentile,
|
|
17468
18618
|
canTranslate,
|
|
17469
18619
|
copilotTranslator,
|
|
17470
18620
|
createAPIBasedCompressor,
|
|
@@ -17502,6 +18652,7 @@ export {
|
|
|
17502
18652
|
createWorkflowOrchestrator,
|
|
17503
18653
|
createWorkflowTemplate,
|
|
17504
18654
|
cursorTranslator,
|
|
18655
|
+
detectCategory,
|
|
17505
18656
|
detectProvider,
|
|
17506
18657
|
detectSkillFormat,
|
|
17507
18658
|
discoverAgents,
|
|
@@ -17512,6 +18663,9 @@ export {
|
|
|
17512
18663
|
discoverSkills,
|
|
17513
18664
|
dryRunExecutor,
|
|
17514
18665
|
estimateTokens,
|
|
18666
|
+
evaluateSkillContent,
|
|
18667
|
+
evaluateSkillDirectory,
|
|
18668
|
+
evaluateSkillFile,
|
|
17515
18669
|
executeWithAgent,
|
|
17516
18670
|
exportBundle,
|
|
17517
18671
|
extractAgentContent,
|
|
@@ -17523,9 +18677,13 @@ export {
|
|
|
17523
18677
|
findAgent,
|
|
17524
18678
|
findAllAgents,
|
|
17525
18679
|
findAllSkills,
|
|
18680
|
+
findManifestPath,
|
|
17526
18681
|
findSkill,
|
|
17527
18682
|
formatSkillAsPrompt,
|
|
17528
18683
|
fromCanonicalAgent,
|
|
18684
|
+
generateComparisonNotes,
|
|
18685
|
+
generateManifestFromInstalled,
|
|
18686
|
+
generateRecommendations,
|
|
17529
18687
|
generateSkillsConfig,
|
|
17530
18688
|
getAgentCLIConfig,
|
|
17531
18689
|
getAgentConfigFile,
|
|
@@ -17537,16 +18695,19 @@ export {
|
|
|
17537
18695
|
getAgentStats,
|
|
17538
18696
|
getAgentTargetDirectory,
|
|
17539
18697
|
getAgentsDirectory,
|
|
18698
|
+
getAllCategories,
|
|
17540
18699
|
getAllProviders,
|
|
17541
18700
|
getAllSkillsDirs,
|
|
17542
18701
|
getAvailableCLIAgents,
|
|
17543
18702
|
getBuiltinPacksDir,
|
|
17544
18703
|
getCICDTemplate,
|
|
18704
|
+
getCategoryStats,
|
|
17545
18705
|
getConfigFile,
|
|
17546
18706
|
getConfigFormat,
|
|
17547
18707
|
getExecutionStrategy,
|
|
17548
18708
|
getGlobalConfigPath,
|
|
17549
18709
|
getGlobalSkillsDir,
|
|
18710
|
+
getGrade,
|
|
17550
18711
|
getIndexStatus,
|
|
17551
18712
|
getInstallDir,
|
|
17552
18713
|
getManualExecutionInstructions,
|
|
@@ -17554,6 +18715,7 @@ export {
|
|
|
17554
18715
|
getMemoryStatus,
|
|
17555
18716
|
getProjectConfigPath,
|
|
17556
18717
|
getProvider,
|
|
18718
|
+
getQualityGrade,
|
|
17557
18719
|
getSearchDirs,
|
|
17558
18720
|
getSkillsDir,
|
|
17559
18721
|
getStackTags,
|
|
@@ -17562,11 +18724,13 @@ export {
|
|
|
17562
18724
|
globalMemoryDirectoryExists,
|
|
17563
18725
|
importBundle,
|
|
17564
18726
|
initContext,
|
|
18727
|
+
initManifest,
|
|
17565
18728
|
initProject,
|
|
17566
18729
|
initializeMemoryDirectory,
|
|
17567
18730
|
isAgentCLIAvailable,
|
|
17568
18731
|
isAgentCompatible,
|
|
17569
18732
|
isGitUrl,
|
|
18733
|
+
isHighQuality,
|
|
17570
18734
|
isIndexStale,
|
|
17571
18735
|
isLocalPath,
|
|
17572
18736
|
isPathInside,
|
|
@@ -17576,6 +18740,7 @@ export {
|
|
|
17576
18740
|
loadConfig,
|
|
17577
18741
|
loadContext,
|
|
17578
18742
|
loadIndex,
|
|
18743
|
+
loadManifest,
|
|
17579
18744
|
loadMetadata,
|
|
17580
18745
|
loadPlugin,
|
|
17581
18746
|
loadPluginsFromDirectory,
|
|
@@ -17594,9 +18759,11 @@ export {
|
|
|
17594
18759
|
parseWorkflow,
|
|
17595
18760
|
readAgentContent,
|
|
17596
18761
|
readSkillContent,
|
|
18762
|
+
removeFromManifest,
|
|
17597
18763
|
runTestSuite,
|
|
17598
18764
|
saveConfig,
|
|
17599
18765
|
saveIndex,
|
|
18766
|
+
saveManifest,
|
|
17600
18767
|
saveSkillMetadata,
|
|
17601
18768
|
saveWorkflow,
|
|
17602
18769
|
serializeWorkflow,
|