@sloop-dev/skill-forge 0.1.0
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/LICENSE +21 -0
- package/README.md +341 -0
- package/bin/skill-forge.js +2 -0
- package/dist/commands/add.d.ts +5 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +48 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/call.d.ts +13 -0
- package/dist/commands/call.d.ts.map +1 -0
- package/dist/commands/call.js +75 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/gen.d.ts +8 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +128 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/list.d.ts +9 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +25 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/remove.d.ts +4 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +26 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +64 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config/manager.d.ts +9 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +72 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/schema.d.ts +21 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/gen/manifest.d.ts +16 -0
- package/dist/gen/manifest.d.ts.map +1 -0
- package/dist/gen/manifest.js +32 -0
- package/dist/gen/manifest.js.map +1 -0
- package/dist/gen/reference-writer.d.ts +19 -0
- package/dist/gen/reference-writer.d.ts.map +1 -0
- package/dist/gen/reference-writer.js +41 -0
- package/dist/gen/reference-writer.js.map +1 -0
- package/dist/gen/skill-writer.d.ts +8 -0
- package/dist/gen/skill-writer.d.ts.map +1 -0
- package/dist/gen/skill-writer.js +19 -0
- package/dist/gen/skill-writer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/cli-runner.d.ts +8 -0
- package/dist/tools/cli-runner.d.ts.map +1 -0
- package/dist/tools/cli-runner.js +7 -0
- package/dist/tools/cli-runner.js.map +1 -0
- package/dist/tools/help-parser.d.ts +10 -0
- package/dist/tools/help-parser.d.ts.map +1 -0
- package/dist/tools/help-parser.js +18 -0
- package/dist/tools/help-parser.js.map +1 -0
- package/dist/tools/mcp-client.d.ts +21 -0
- package/dist/tools/mcp-client.d.ts.map +1 -0
- package/dist/tools/mcp-client.js +37 -0
- package/dist/tools/mcp-client.js.map +1 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +20 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/process.d.ts +11 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +26 -0
- package/dist/utils/process.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
// MCP client wrapper with lifecycle management (connect, listTools, callTool, disconnect).
|
|
4
|
+
export class McpClient {
|
|
5
|
+
client;
|
|
6
|
+
transport;
|
|
7
|
+
options;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.client = new Client({ name: 'skill-forge', version: '1.0.0' }, { capabilities: {} });
|
|
11
|
+
this.transport = new StdioClientTransport({
|
|
12
|
+
command: options.command,
|
|
13
|
+
args: options.args,
|
|
14
|
+
env: options.env,
|
|
15
|
+
stderr: 'pipe',
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async connect() {
|
|
19
|
+
await this.client.connect(this.transport);
|
|
20
|
+
}
|
|
21
|
+
async listTools() {
|
|
22
|
+
const result = await this.client.listTools();
|
|
23
|
+
return result.tools.map((t) => ({
|
|
24
|
+
name: t.name,
|
|
25
|
+
description: t.description,
|
|
26
|
+
inputSchema: t.inputSchema,
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
async callTool(name, args) {
|
|
30
|
+
const result = await this.client.callTool({ name, arguments: args });
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
async disconnect() {
|
|
34
|
+
await this.client.close();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/tools/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AASjF,2FAA2F;AAC3F,MAAM,OAAO,SAAS;IACZ,MAAM,CAAS;IACf,SAAS,CAAuB;IAChC,OAAO,CAAmB;IAElC,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,EACzC,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,oBAAoB,CAAC;YACxC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAA6B;QACxD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAgBA,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
// Recursively sort object keys for deterministic serialization.
|
|
3
|
+
function deepSortKeys(value) {
|
|
4
|
+
if (Array.isArray(value))
|
|
5
|
+
return value.map(deepSortKeys);
|
|
6
|
+
if (value !== null && typeof value === 'object') {
|
|
7
|
+
const sorted = {};
|
|
8
|
+
for (const key of Object.keys(value).sort()) {
|
|
9
|
+
sorted[key] = deepSortKeys(value[key]);
|
|
10
|
+
}
|
|
11
|
+
return sorted;
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
// Compute a short SHA-256 hash of a JSON-serializable value. Deep-sorts keys.
|
|
16
|
+
export function configHash(value) {
|
|
17
|
+
const json = JSON.stringify(deepSortKeys(value));
|
|
18
|
+
return createHash('sha256').update(json).digest('hex').slice(0, 8);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,gEAAgE;AAChE,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SpawnResult {
|
|
2
|
+
stdout: string;
|
|
3
|
+
stderr: string;
|
|
4
|
+
exitCode: number | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function spawnWithTimeout(command: string, args: string[], options: {
|
|
7
|
+
timeout: number;
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
shell?: boolean;
|
|
10
|
+
}): Promise<SpawnResult>;
|
|
11
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAGD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAC/B,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1E,OAAO,CAAC,WAAW,CAAC,CAmBtB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
// Spawn a process with timeout. On timeout, sends SIGTERM, then SIGKILL after 3s.
|
|
3
|
+
export function spawnWithTimeout(command, args, options) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const env = options.env ? { ...process.env, ...options.env } : process.env;
|
|
6
|
+
const child = spawn(command, args, { env, shell: options.shell ?? false, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
7
|
+
let stdout = '', stderr = '', killed = false;
|
|
8
|
+
child.stdout.on('data', (d) => { stdout += d.toString(); });
|
|
9
|
+
child.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
10
|
+
const timer = setTimeout(() => {
|
|
11
|
+
killed = true;
|
|
12
|
+
child.kill('SIGTERM');
|
|
13
|
+
setTimeout(() => { if (!child.killed)
|
|
14
|
+
child.kill('SIGKILL'); }, 3000);
|
|
15
|
+
}, options.timeout);
|
|
16
|
+
child.on('close', (code) => {
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
if (killed)
|
|
19
|
+
reject(new Error(`Process timed out after ${options.timeout}ms`));
|
|
20
|
+
else
|
|
21
|
+
resolve({ stdout, stderr, exitCode: code });
|
|
22
|
+
});
|
|
23
|
+
child.on('error', (err) => { clearTimeout(timer); reject(err); });
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQ3C,kFAAkF;AAClF,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EAAE,IAAc,EAC/B,OAA2E;IAE3E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;QAC3E,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5G,IAAI,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC;QAC7C,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;;gBACzE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sloop-dev/skill-forge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A CLI middleware that bridges AI agents to MCP servers and CLI tools via skill files",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"skill-forge": "./bin/skill-forge.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"lint": "tsc --noEmit",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"cli",
|
|
22
|
+
"ai-agent",
|
|
23
|
+
"skill",
|
|
24
|
+
"claude"
|
|
25
|
+
],
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/sloop-dev/skill-forge.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/sloop-dev/skill-forge#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/sloop-dev/skill-forge/issues"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18.0.0"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"bin",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
46
|
+
"commander": "^14.0.3"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^25.5.0",
|
|
50
|
+
"typescript": "^5.9.3",
|
|
51
|
+
"vitest": "^4.1.0"
|
|
52
|
+
}
|
|
53
|
+
}
|