@hasna/skills 0.1.24 → 0.1.26
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/README.md +21 -0
- package/bin/index.js +16289 -15676
- package/bin/mcp.js +65 -34
- package/dist/cli/commands/feedback.d.ts +2 -0
- package/dist/cli/commands/registry.d.ts +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +14296 -193
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/feedback.d.ts +15 -0
- package/dist/lib/registry-sync.d.ts +53 -0
- package/dist/lib/registry.d.ts +1 -1
- package/dist/lib/remote-registry.d.ts +19 -0
- package/dist/lib/skill-validation.d.ts +45 -0
- package/dist/types/api.d.ts +1 -0
- package/package.json +3 -3
- package/skills/_common/http-client.ts +1 -1
- package/skills/_common/installer.ts +1 -1
- package/skills/deploy/src/http-client.ts +1 -1
- package/skills/e2bswarm/src/lib/paths.ts +1 -1
- package/skills/scaffold-project/my-app/.env.example +2 -0
- package/skills/scaffold-project/my-app/README.md +72 -0
- package/skills/scaffold-project/my-app/package.json +29 -0
- package/skills/scaffold-project/my-app/src/index.ts +23 -0
- package/skills/scaffold-project/my-app/tsconfig.json +33 -0
package/bin/mcp.js
CHANGED
|
@@ -28561,9 +28561,8 @@ class StdioServerTransport {
|
|
|
28561
28561
|
}
|
|
28562
28562
|
|
|
28563
28563
|
// src/mcp/index.ts
|
|
28564
|
-
import { existsSync as
|
|
28565
|
-
import { join as
|
|
28566
|
-
import { homedir as homedir9 } from "os";
|
|
28564
|
+
import { existsSync as existsSync10, readdirSync as readdirSync7, statSync as statSync3 } from "fs";
|
|
28565
|
+
import { join as join11 } from "path";
|
|
28567
28566
|
|
|
28568
28567
|
// node_modules/@hasna/cloud/dist/index.js
|
|
28569
28568
|
import { createRequire } from "module";
|
|
@@ -38746,12 +38745,12 @@ init_adapter();
|
|
|
38746
38745
|
// package.json
|
|
38747
38746
|
var package_default = {
|
|
38748
38747
|
name: "@hasna/skills",
|
|
38749
|
-
version: "0.1.
|
|
38748
|
+
version: "0.1.26",
|
|
38750
38749
|
description: "Skills library for AI coding agents",
|
|
38751
38750
|
type: "module",
|
|
38752
38751
|
bin: {
|
|
38753
|
-
skills: "
|
|
38754
|
-
"skills-mcp": "
|
|
38752
|
+
skills: "bin/index.js",
|
|
38753
|
+
"skills-mcp": "bin/mcp.js"
|
|
38755
38754
|
},
|
|
38756
38755
|
exports: {
|
|
38757
38756
|
".": {
|
|
@@ -40529,7 +40528,7 @@ function discoverSkillsInDir(dir) {
|
|
|
40529
40528
|
const fm = parseSkillMdFrontmatter(content);
|
|
40530
40529
|
if (!fm?.name)
|
|
40531
40530
|
continue;
|
|
40532
|
-
const name = fm.name
|
|
40531
|
+
const name = fm.name;
|
|
40533
40532
|
result.push({
|
|
40534
40533
|
name,
|
|
40535
40534
|
displayName: fm.displayName || name.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
@@ -41342,6 +41341,51 @@ function removeSchedule(idOrName, targetDir) {
|
|
|
41342
41341
|
return true;
|
|
41343
41342
|
}
|
|
41344
41343
|
|
|
41344
|
+
// src/lib/feedback.ts
|
|
41345
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
41346
|
+
import { homedir as homedir9 } from "os";
|
|
41347
|
+
import { dirname as dirname3, join as join10 } from "path";
|
|
41348
|
+
function getFeedbackDbPath() {
|
|
41349
|
+
return process.env.SKILLS_FEEDBACK_DB_PATH || join10(homedir9(), ".hasna", "skills", "skills.db");
|
|
41350
|
+
}
|
|
41351
|
+
function getFeedbackDb() {
|
|
41352
|
+
const dbPath = getFeedbackDbPath();
|
|
41353
|
+
const dir = dirname3(dbPath);
|
|
41354
|
+
if (!existsSync9(dir))
|
|
41355
|
+
mkdirSync6(dir, { recursive: true });
|
|
41356
|
+
const db = new SqliteAdapter(dbPath);
|
|
41357
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
41358
|
+
db.exec([
|
|
41359
|
+
"CREATE TABLE IF NOT EXISTS feedback (",
|
|
41360
|
+
"id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),",
|
|
41361
|
+
"message TEXT NOT NULL,",
|
|
41362
|
+
"email TEXT,",
|
|
41363
|
+
"category TEXT DEFAULT 'general',",
|
|
41364
|
+
"agent TEXT,",
|
|
41365
|
+
"version TEXT,",
|
|
41366
|
+
"machine_id TEXT,",
|
|
41367
|
+
"created_at TEXT NOT NULL DEFAULT (datetime('now'))",
|
|
41368
|
+
")"
|
|
41369
|
+
].join(" "));
|
|
41370
|
+
try {
|
|
41371
|
+
db.exec("ALTER TABLE feedback ADD COLUMN agent TEXT");
|
|
41372
|
+
} catch {}
|
|
41373
|
+
return db;
|
|
41374
|
+
}
|
|
41375
|
+
function saveFeedback2(input) {
|
|
41376
|
+
const message = input.message.trim();
|
|
41377
|
+
if (!message)
|
|
41378
|
+
throw new Error("Feedback message is required");
|
|
41379
|
+
const category = input.category ?? "general";
|
|
41380
|
+
const db = getFeedbackDb();
|
|
41381
|
+
try {
|
|
41382
|
+
db.run("INSERT INTO feedback (message, email, category, agent, version) VALUES (?, ?, ?, ?, ?)", [message, input.email || null, category, input.agent || null, input.version || null]);
|
|
41383
|
+
} finally {
|
|
41384
|
+
db.close();
|
|
41385
|
+
}
|
|
41386
|
+
return { saved: true, category, path: getFeedbackDbPath() };
|
|
41387
|
+
}
|
|
41388
|
+
|
|
41345
41389
|
// src/mcp/index.ts
|
|
41346
41390
|
var server = new McpServer({
|
|
41347
41391
|
name: "skills",
|
|
@@ -41696,13 +41740,13 @@ server.registerTool("whoami", {
|
|
|
41696
41740
|
const agents = [];
|
|
41697
41741
|
for (const agent of AGENT_TARGETS) {
|
|
41698
41742
|
const agentSkillsPath = getAgentSkillsDir(agent, "global");
|
|
41699
|
-
const exists =
|
|
41743
|
+
const exists = existsSync10(agentSkillsPath);
|
|
41700
41744
|
let skillCount = 0;
|
|
41701
41745
|
if (exists) {
|
|
41702
41746
|
try {
|
|
41703
41747
|
skillCount = readdirSync7(agentSkillsPath).filter((f) => {
|
|
41704
|
-
const full =
|
|
41705
|
-
return f.startsWith("
|
|
41748
|
+
const full = join11(agentSkillsPath, f);
|
|
41749
|
+
return !f.startsWith(".") && statSync3(full).isDirectory();
|
|
41706
41750
|
}).length;
|
|
41707
41751
|
} catch {}
|
|
41708
41752
|
}
|
|
@@ -41782,17 +41826,17 @@ server.registerTool("validate_skill", {
|
|
|
41782
41826
|
}, async ({ name }) => {
|
|
41783
41827
|
const skillPath = getSkillPath(name);
|
|
41784
41828
|
const issues = [];
|
|
41785
|
-
if (!
|
|
41829
|
+
if (!existsSync10(skillPath)) {
|
|
41786
41830
|
return {
|
|
41787
41831
|
content: [{ type: "text", text: JSON.stringify({ name, valid: false, issues: [`Skill directory not found: ${skillPath}`] }) }]
|
|
41788
41832
|
};
|
|
41789
41833
|
}
|
|
41790
|
-
if (!
|
|
41834
|
+
if (!existsSync10(join11(skillPath, "SKILL.md")))
|
|
41791
41835
|
issues.push("Missing SKILL.md");
|
|
41792
|
-
if (!
|
|
41836
|
+
if (!existsSync10(join11(skillPath, "tsconfig.json")))
|
|
41793
41837
|
issues.push("Missing tsconfig.json");
|
|
41794
|
-
const pkgPath =
|
|
41795
|
-
if (!
|
|
41838
|
+
const pkgPath = join11(skillPath, "package.json");
|
|
41839
|
+
if (!existsSync10(pkgPath)) {
|
|
41796
41840
|
issues.push("Missing package.json");
|
|
41797
41841
|
} else {
|
|
41798
41842
|
try {
|
|
@@ -41803,10 +41847,10 @@ server.registerTool("validate_skill", {
|
|
|
41803
41847
|
issues.push("package.json is invalid JSON");
|
|
41804
41848
|
}
|
|
41805
41849
|
}
|
|
41806
|
-
const srcDir =
|
|
41807
|
-
if (!
|
|
41850
|
+
const srcDir = join11(skillPath, "src");
|
|
41851
|
+
if (!existsSync10(srcDir)) {
|
|
41808
41852
|
issues.push("Missing src/ directory");
|
|
41809
|
-
} else if (!
|
|
41853
|
+
} else if (!existsSync10(join11(srcDir, "index.ts"))) {
|
|
41810
41854
|
issues.push("Missing src/index.ts");
|
|
41811
41855
|
}
|
|
41812
41856
|
const valid = issues.length === 0;
|
|
@@ -41930,23 +41974,10 @@ server.tool("list_agents", "List all registered agents.", {}, async () => {
|
|
|
41930
41974
|
return { content: [{ type: "text", text: "No agents registered." }] };
|
|
41931
41975
|
return { content: [{ type: "text", text: JSON.stringify(agents, null, 2) }] };
|
|
41932
41976
|
});
|
|
41933
|
-
|
|
41934
|
-
const home = homedir9();
|
|
41935
|
-
const dbPath = join10(home, ".hasna", "skills", "skills.db");
|
|
41936
|
-
const dir = dirname3(dbPath);
|
|
41937
|
-
if (!existsSync9(dir))
|
|
41938
|
-
mkdirSync6(dir, { recursive: true });
|
|
41939
|
-
const db = new SqliteAdapter(dbPath);
|
|
41940
|
-
db.exec("PRAGMA journal_mode = WAL");
|
|
41941
|
-
db.exec("CREATE TABLE IF NOT EXISTS feedback (id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))), message TEXT NOT NULL, email TEXT, category TEXT DEFAULT 'general', version TEXT, machine_id TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')))");
|
|
41942
|
-
return db;
|
|
41943
|
-
}
|
|
41944
|
-
server.tool("send_feedback", "Send feedback about this service", { message: exports_external.string(), email: exports_external.string().optional(), category: exports_external.enum(["bug", "feature", "general"]).optional() }, async (params) => {
|
|
41977
|
+
server.tool("send_feedback", "Send feedback about this service", { message: exports_external.string(), email: exports_external.string().optional(), agent: exports_external.string().optional(), category: exports_external.enum(["bug", "feature", "general"]).optional() }, async (params) => {
|
|
41945
41978
|
try {
|
|
41946
|
-
const
|
|
41947
|
-
|
|
41948
|
-
db.close();
|
|
41949
|
-
return { content: [{ type: "text", text: "Feedback saved. Thank you!" }] };
|
|
41979
|
+
const result = saveFeedback2({ ...params, version: package_default.version });
|
|
41980
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
41950
41981
|
} catch (e) {
|
|
41951
41982
|
return { content: [{ type: "text", text: String(e) }], isError: true };
|
|
41952
41983
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,8 @@ export { SKILLS, BASIC_SKILL_NAMES, CATEGORIES, getSkill, getSkillsByCategory, s
|
|
|
11
11
|
export { installSkill, installSkills, installSkillForAgent, removeSkillForAgent, getInstalledSkills, removeSkill, skillExists, getSkillPath, getAgentSkillsDir, getAgentSkillPath, AGENT_TARGETS, type InstallResult, type InstallOptions, type AgentTarget, type AgentScope, type AgentInstallOptions, getInstallMeta, disableSkill, enableSkill, getDisabledSkills, } from "./lib/installer.js";
|
|
12
12
|
export { getSkillDocs, getSkillBestDoc, getSkillRequirements, runSkill, generateEnvExample, generateSkillMd, type SkillDocs, type SkillRequirements, } from "./lib/skillinfo.js";
|
|
13
13
|
export { loadConfig, saveConfig, getConfigPath, type SkillsConfig, type ConfigScope, } from "./lib/config.js";
|
|
14
|
+
export { buildSkillsApiUrl, getConfiguredApiUrl, loadRemoteRegistry, parseRemoteRegistryPayload, type RemoteRegistryOptions, } from "./lib/remote-registry.js";
|
|
14
15
|
export { addSchedule, listSchedules, removeSchedule, setScheduleEnabled, getDueSchedules, recordScheduleRun, validateCron, getNextRun, type SkillSchedule, } from "./lib/scheduler.js";
|
|
16
|
+
export { parseSkillFrontmatter, validateRegistryConsistency, validateSkillDirectory, type RegistryConsistencyResult, type SkillFrontmatter, type SkillValidationMessage, type SkillValidationResult, } from "./lib/skill-validation.js";
|
|
17
|
+
export { createRegistrySyncArtifact, writeRegistrySyncArtifact, type RegistrySyncArtifact, type RegistrySyncOptions, type RegistrySyncSkill, } from "./lib/registry-sync.js";
|
|
15
18
|
export type { SkillResponse, SkillDetailResponse, CategoryResponse, TagResponse, InstallResponse, RemoveResponse, VersionResponse, ExportResponse, ImportResponse, SearchResponse, CategoryInstallResponse, ErrorResponse, } from "./types/api.js";
|