@hasna/skills 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/index.js +58 -16
- package/bin/mcp.js +1 -1
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1878,7 +1878,7 @@ var package_default;
|
|
|
1878
1878
|
var init_package = __esm(() => {
|
|
1879
1879
|
package_default = {
|
|
1880
1880
|
name: "@hasna/skills",
|
|
1881
|
-
version: "0.1.
|
|
1881
|
+
version: "0.1.12",
|
|
1882
1882
|
description: "Skills library for AI coding agents",
|
|
1883
1883
|
type: "module",
|
|
1884
1884
|
bin: {
|
|
@@ -35253,6 +35253,18 @@ function json2(data, status = 200) {
|
|
|
35253
35253
|
function isValidSkillName(name) {
|
|
35254
35254
|
return /^[a-z0-9-]+$/.test(name);
|
|
35255
35255
|
}
|
|
35256
|
+
function pickFields(obj, fields) {
|
|
35257
|
+
if (fields.length === 0)
|
|
35258
|
+
return obj;
|
|
35259
|
+
const rec = obj;
|
|
35260
|
+
return Object.fromEntries(fields.filter((f) => (f in rec)).map((f) => [f, rec[f]]));
|
|
35261
|
+
}
|
|
35262
|
+
function parseFields(searchParams) {
|
|
35263
|
+
const raw = searchParams.get("fields");
|
|
35264
|
+
if (!raw)
|
|
35265
|
+
return [];
|
|
35266
|
+
return raw.split(",").map((f) => f.trim()).filter(Boolean);
|
|
35267
|
+
}
|
|
35256
35268
|
function getAllSkillsWithStatus() {
|
|
35257
35269
|
const installed = new Set(getInstalledSkills());
|
|
35258
35270
|
return SKILLS.map((meta3) => {
|
|
@@ -35289,7 +35301,9 @@ function createFetchHandler(options) {
|
|
|
35289
35301
|
const path = url2.pathname;
|
|
35290
35302
|
const method = req.method;
|
|
35291
35303
|
if (path === "/api/skills" && method === "GET") {
|
|
35292
|
-
|
|
35304
|
+
const fields = parseFields(url2.searchParams);
|
|
35305
|
+
const skills = getAllSkillsWithStatus();
|
|
35306
|
+
return json2(fields.length ? skills.map((s) => pickFields(s, fields)) : skills);
|
|
35293
35307
|
}
|
|
35294
35308
|
if (path === "/api/categories" && method === "GET") {
|
|
35295
35309
|
const counts = CATEGORIES.map((cat) => ({
|
|
@@ -35312,12 +35326,13 @@ function createFetchHandler(options) {
|
|
|
35312
35326
|
const query = url2.searchParams.get("q") || "";
|
|
35313
35327
|
if (!query.trim())
|
|
35314
35328
|
return json2([]);
|
|
35329
|
+
const fields = parseFields(url2.searchParams);
|
|
35315
35330
|
const results = searchSkills(query);
|
|
35316
35331
|
const installed = new Set(getInstalledSkills());
|
|
35317
|
-
|
|
35332
|
+
const mapped = results.map((meta3) => {
|
|
35318
35333
|
const reqs = getSkillRequirements(meta3.name);
|
|
35319
35334
|
const envVars = reqs?.envVars || [];
|
|
35320
|
-
|
|
35335
|
+
const obj = {
|
|
35321
35336
|
name: meta3.name,
|
|
35322
35337
|
displayName: meta3.displayName,
|
|
35323
35338
|
description: meta3.description,
|
|
@@ -35329,7 +35344,9 @@ function createFetchHandler(options) {
|
|
|
35329
35344
|
systemDeps: reqs?.systemDeps || [],
|
|
35330
35345
|
cliCommand: reqs?.cliCommand || null
|
|
35331
35346
|
};
|
|
35332
|
-
|
|
35347
|
+
return fields.length ? pickFields(obj, fields) : obj;
|
|
35348
|
+
});
|
|
35349
|
+
return json2(mapped);
|
|
35333
35350
|
}
|
|
35334
35351
|
const singleMatch = path.match(/^\/api\/skills\/([^/]+)$/);
|
|
35335
35352
|
if (singleMatch && method === "GET") {
|
|
@@ -35339,11 +35356,12 @@ function createFetchHandler(options) {
|
|
|
35339
35356
|
const meta3 = getSkill(name);
|
|
35340
35357
|
if (!meta3)
|
|
35341
35358
|
return json2({ error: `Skill '${name}' not found` }, 404);
|
|
35359
|
+
const fields = parseFields(url2.searchParams);
|
|
35342
35360
|
const reqs = getSkillRequirements(name);
|
|
35343
35361
|
const docs = getSkillBestDoc(name);
|
|
35344
35362
|
const installed = new Set(getInstalledSkills());
|
|
35345
35363
|
const envVars = reqs?.envVars || [];
|
|
35346
|
-
|
|
35364
|
+
const obj = {
|
|
35347
35365
|
name: meta3.name,
|
|
35348
35366
|
displayName: meta3.displayName,
|
|
35349
35367
|
description: meta3.description,
|
|
@@ -35355,7 +35373,8 @@ function createFetchHandler(options) {
|
|
|
35355
35373
|
systemDeps: reqs?.systemDeps || [],
|
|
35356
35374
|
cliCommand: reqs?.cliCommand || null,
|
|
35357
35375
|
docs: docs || null
|
|
35358
|
-
}
|
|
35376
|
+
};
|
|
35377
|
+
return json2(fields.length ? pickFields(obj, fields) : obj);
|
|
35359
35378
|
}
|
|
35360
35379
|
const docsMatch = path.match(/^\/api\/skills\/([^/]+)\/docs$/);
|
|
35361
35380
|
if (docsMatch && method === "GET") {
|
|
@@ -35383,18 +35402,13 @@ function createFetchHandler(options) {
|
|
|
35383
35402
|
const results = agents.map((agent) => installSkillForAgent(name, { agent, scope }, generateSkillMd));
|
|
35384
35403
|
const allSuccess = results.every((r) => r.success);
|
|
35385
35404
|
const errors4 = results.filter((r) => !r.success).map((r) => r.error);
|
|
35386
|
-
return json2({
|
|
35387
|
-
skill: name,
|
|
35388
|
-
success: allSuccess,
|
|
35389
|
-
results,
|
|
35390
|
-
...errors4.length > 0 ? { error: errors4.join("; ") } : {}
|
|
35391
|
-
}, allSuccess ? 200 : 400);
|
|
35405
|
+
return json2(allSuccess ? { skill: name, success: true } : { skill: name, success: false, results, error: errors4.join("; ") }, allSuccess ? 200 : 400);
|
|
35392
35406
|
} catch (e) {
|
|
35393
35407
|
return json2({ skill: name, success: false, error: e instanceof Error ? e.message : "Unknown error" }, 400);
|
|
35394
35408
|
}
|
|
35395
35409
|
} else {
|
|
35396
35410
|
const result = installSkill(name);
|
|
35397
|
-
return json2(result, result.success ? 200 : 400);
|
|
35411
|
+
return json2(result.success ? { skill: name, success: true } : { skill: name, success: false, error: result.error }, result.success ? 200 : 400);
|
|
35398
35412
|
}
|
|
35399
35413
|
}
|
|
35400
35414
|
if (path === "/api/skills/install-category" && method === "POST") {
|
|
@@ -36859,8 +36873,9 @@ Skills installed to .skills/`));
|
|
|
36859
36873
|
process.exitCode = 1;
|
|
36860
36874
|
}
|
|
36861
36875
|
});
|
|
36862
|
-
program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-i, --installed", "Show only installed skills", false).option("-t, --tags <tags>", "Filter by comma-separated tags (OR logic, case-insensitive)").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).description("List available or installed skills").action((options) => {
|
|
36876
|
+
program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-i, --installed", "Show only installed skills", false).option("-t, --tags <tags>", "Filter by comma-separated tags (OR logic, case-insensitive)").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,description)").description("List available or installed skills").action((options) => {
|
|
36863
36877
|
const brief = options.brief && !options.json;
|
|
36878
|
+
const fmt = !options.json ? options.format : undefined;
|
|
36864
36879
|
if (options.installed) {
|
|
36865
36880
|
const installed = getInstalledSkills();
|
|
36866
36881
|
if (options.json) {
|
|
@@ -36940,6 +36955,19 @@ Skills matching tags [${tagFilter.join(", ")}] (${skills.length}):
|
|
|
36940
36955
|
console.log(JSON.stringify(SKILLS, null, 2));
|
|
36941
36956
|
return;
|
|
36942
36957
|
}
|
|
36958
|
+
if (fmt === "compact") {
|
|
36959
|
+
for (const s of SKILLS)
|
|
36960
|
+
console.log(s.name);
|
|
36961
|
+
return;
|
|
36962
|
+
}
|
|
36963
|
+
if (fmt === "csv") {
|
|
36964
|
+
console.log("name,category,description");
|
|
36965
|
+
for (const s of SKILLS) {
|
|
36966
|
+
const desc = s.description.replace(/"/g, '""');
|
|
36967
|
+
console.log(`${s.name},${s.category},"${desc}"`);
|
|
36968
|
+
}
|
|
36969
|
+
return;
|
|
36970
|
+
}
|
|
36943
36971
|
if (brief) {
|
|
36944
36972
|
const sorted = [...SKILLS].sort((a, b) => {
|
|
36945
36973
|
const catCmp = a.category.localeCompare(b.category);
|
|
@@ -36962,7 +36990,7 @@ Available skills (${SKILLS.length}):
|
|
|
36962
36990
|
console.log();
|
|
36963
36991
|
}
|
|
36964
36992
|
});
|
|
36965
|
-
program2.command("search").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("-c, --category <category>", "Filter results by category").option("-t, --tags <tags>", "Filter results by comma-separated tags (OR logic, case-insensitive)").description("Search for skills").action((query, options) => {
|
|
36993
|
+
program2.command("search").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,description)").option("-c, --category <category>", "Filter results by category").option("-t, --tags <tags>", "Filter results by comma-separated tags (OR logic, case-insensitive)").description("Search for skills").action((query, options) => {
|
|
36966
36994
|
let results = searchSkills(query);
|
|
36967
36995
|
if (options.category) {
|
|
36968
36996
|
const category = CATEGORIES.find((c) => c.toLowerCase() === options.category.toLowerCase());
|
|
@@ -36979,6 +37007,7 @@ program2.command("search").argument("<query>", "Search term").option("--json", "
|
|
|
36979
37007
|
results = results.filter((s) => s.tags.some((tag) => tagFilter.includes(tag.toLowerCase())));
|
|
36980
37008
|
}
|
|
36981
37009
|
const brief = options.brief && !options.json;
|
|
37010
|
+
const fmt = !options.json ? options.format : undefined;
|
|
36982
37011
|
if (options.json) {
|
|
36983
37012
|
console.log(JSON.stringify(results, null, 2));
|
|
36984
37013
|
return;
|
|
@@ -36987,6 +37016,19 @@ program2.command("search").argument("<query>", "Search term").option("--json", "
|
|
|
36987
37016
|
console.log(chalk2.dim(`No skills found for "${query}"`));
|
|
36988
37017
|
return;
|
|
36989
37018
|
}
|
|
37019
|
+
if (fmt === "compact") {
|
|
37020
|
+
for (const s of results)
|
|
37021
|
+
console.log(s.name);
|
|
37022
|
+
return;
|
|
37023
|
+
}
|
|
37024
|
+
if (fmt === "csv") {
|
|
37025
|
+
console.log("name,category,description");
|
|
37026
|
+
for (const s of results) {
|
|
37027
|
+
const desc = s.description.replace(/"/g, '""');
|
|
37028
|
+
console.log(`${s.name},${s.category},"${desc}"`);
|
|
37029
|
+
}
|
|
37030
|
+
return;
|
|
37031
|
+
}
|
|
36990
37032
|
if (brief) {
|
|
36991
37033
|
for (const s of results) {
|
|
36992
37034
|
console.log(`${s.name} \u2014 ${s.description} [${s.category}]`);
|
package/bin/mcp.js
CHANGED
|
@@ -28604,7 +28604,7 @@ import { homedir as homedir2 } from "os";
|
|
|
28604
28604
|
// package.json
|
|
28605
28605
|
var package_default = {
|
|
28606
28606
|
name: "@hasna/skills",
|
|
28607
|
-
version: "0.1.
|
|
28607
|
+
version: "0.1.12",
|
|
28608
28608
|
description: "Skills library for AI coding agents",
|
|
28609
28609
|
type: "module",
|
|
28610
28610
|
bin: {
|