@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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +341 -0
  3. package/bin/skill-forge.js +2 -0
  4. package/dist/commands/add.d.ts +5 -0
  5. package/dist/commands/add.d.ts.map +1 -0
  6. package/dist/commands/add.js +48 -0
  7. package/dist/commands/add.js.map +1 -0
  8. package/dist/commands/call.d.ts +13 -0
  9. package/dist/commands/call.d.ts.map +1 -0
  10. package/dist/commands/call.js +75 -0
  11. package/dist/commands/call.js.map +1 -0
  12. package/dist/commands/gen.d.ts +8 -0
  13. package/dist/commands/gen.d.ts.map +1 -0
  14. package/dist/commands/gen.js +128 -0
  15. package/dist/commands/gen.js.map +1 -0
  16. package/dist/commands/list.d.ts +9 -0
  17. package/dist/commands/list.d.ts.map +1 -0
  18. package/dist/commands/list.js +25 -0
  19. package/dist/commands/list.js.map +1 -0
  20. package/dist/commands/remove.d.ts +4 -0
  21. package/dist/commands/remove.d.ts.map +1 -0
  22. package/dist/commands/remove.js +26 -0
  23. package/dist/commands/remove.js.map +1 -0
  24. package/dist/commands/update.d.ts +10 -0
  25. package/dist/commands/update.d.ts.map +1 -0
  26. package/dist/commands/update.js +64 -0
  27. package/dist/commands/update.js.map +1 -0
  28. package/dist/config/manager.d.ts +9 -0
  29. package/dist/config/manager.d.ts.map +1 -0
  30. package/dist/config/manager.js +72 -0
  31. package/dist/config/manager.js.map +1 -0
  32. package/dist/config/schema.d.ts +21 -0
  33. package/dist/config/schema.d.ts.map +1 -0
  34. package/dist/config/schema.js +2 -0
  35. package/dist/config/schema.js.map +1 -0
  36. package/dist/gen/manifest.d.ts +16 -0
  37. package/dist/gen/manifest.d.ts.map +1 -0
  38. package/dist/gen/manifest.js +32 -0
  39. package/dist/gen/manifest.js.map +1 -0
  40. package/dist/gen/reference-writer.d.ts +19 -0
  41. package/dist/gen/reference-writer.d.ts.map +1 -0
  42. package/dist/gen/reference-writer.js +41 -0
  43. package/dist/gen/reference-writer.js.map +1 -0
  44. package/dist/gen/skill-writer.d.ts +8 -0
  45. package/dist/gen/skill-writer.d.ts.map +1 -0
  46. package/dist/gen/skill-writer.js +19 -0
  47. package/dist/gen/skill-writer.js.map +1 -0
  48. package/dist/index.d.ts +2 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +20 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/tools/cli-runner.d.ts +8 -0
  53. package/dist/tools/cli-runner.d.ts.map +1 -0
  54. package/dist/tools/cli-runner.js +7 -0
  55. package/dist/tools/cli-runner.js.map +1 -0
  56. package/dist/tools/help-parser.d.ts +10 -0
  57. package/dist/tools/help-parser.d.ts.map +1 -0
  58. package/dist/tools/help-parser.js +18 -0
  59. package/dist/tools/help-parser.js.map +1 -0
  60. package/dist/tools/mcp-client.d.ts +21 -0
  61. package/dist/tools/mcp-client.d.ts.map +1 -0
  62. package/dist/tools/mcp-client.js +37 -0
  63. package/dist/tools/mcp-client.js.map +1 -0
  64. package/dist/utils/hash.d.ts +2 -0
  65. package/dist/utils/hash.d.ts.map +1 -0
  66. package/dist/utils/hash.js +20 -0
  67. package/dist/utils/hash.js.map +1 -0
  68. package/dist/utils/process.d.ts +11 -0
  69. package/dist/utils/process.d.ts.map +1 -0
  70. package/dist/utils/process.js +26 -0
  71. package/dist/utils/process.js.map +1 -0
  72. 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,2 @@
1
+ export declare function configHash(value: unknown): string;
2
+ //# sourceMappingURL=hash.d.ts.map
@@ -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
+ }