skillpkg-mcp-server 0.3.1 → 0.5.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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/create-skill.d.ts +14 -0
- package/dist/tools/create-skill.d.ts.map +1 -0
- package/dist/tools/create-skill.js +106 -0
- package/dist/tools/create-skill.js.map +1 -0
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/install-skill.d.ts +2 -2
- package/dist/tools/install-skill.d.ts.map +1 -1
- package/dist/tools/install-skill.js +176 -113
- package/dist/tools/install-skill.js.map +1 -1
- package/dist/tools/skill-info.d.ts +4 -1
- package/dist/tools/skill-info.d.ts.map +1 -1
- package/dist/tools/skill-info.js +74 -51
- package/dist/tools/skill-info.js.map +1 -1
- package/dist/tools/skill-status.d.ts +36 -0
- package/dist/tools/skill-status.d.ts.map +1 -0
- package/dist/tools/skill-status.js +189 -0
- package/dist/tools/skill-status.js.map +1 -0
- package/dist/tools/sync-skills.d.ts +9 -0
- package/dist/tools/sync-skills.d.ts.map +1 -0
- package/dist/tools/sync-skills.js +178 -0
- package/dist/tools/sync-skills.js.map +1 -0
- package/dist/tools/uninstall-skill.d.ts +2 -1
- package/dist/tools/uninstall-skill.d.ts.map +1 -1
- package/dist/tools/uninstall-skill.js +82 -14
- package/dist/tools/uninstall-skill.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ Installs a skill from multiple sources:
|
|
|
89
89
|
"source": "commit-helper", // Registry
|
|
90
90
|
"source": "github:user/repo", // GitHub repo
|
|
91
91
|
"source": "gist:abc123", // GitHub Gist
|
|
92
|
-
"source": "https://example.com/
|
|
92
|
+
"source": "https://example.com/SKILL.md", // URL
|
|
93
93
|
"source": "./my-skill", // Local path
|
|
94
94
|
"scope": "local" // "local" | "global"
|
|
95
95
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
export declare const VERSION = "0.1.0";
|
|
17
17
|
export * from './types.js';
|
|
18
18
|
export { SkillpkgMcpServer } from './server.js';
|
|
19
|
-
export { createAllToolHandlers, createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSkillInfoHandler, createRecommendSkillHandler, } from './tools/index.js';
|
|
19
|
+
export { createAllToolHandlers, createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSyncSkillsHandler, createCreateSkillHandler, createSkillStatusHandler, createSkillInfoHandler, createRecommendSkillHandler, } from './tools/index.js';
|
|
20
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,5 +19,5 @@ export * from './types.js';
|
|
|
19
19
|
// Server
|
|
20
20
|
export { SkillpkgMcpServer } from './server.js';
|
|
21
21
|
// Tool handlers
|
|
22
|
-
export { createAllToolHandlers, createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSkillInfoHandler, createRecommendSkillHandler, } from './tools/index.js';
|
|
22
|
+
export { createAllToolHandlers, createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSyncSkillsHandler, createCreateSkillHandler, createSkillStatusHandler, createSkillInfoHandler, createRecommendSkillHandler, } from './tools/index.js';
|
|
23
23
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,gBAAgB;AAChB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,SAAS;AACT,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,gBAAgB;AAChB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: create_skill
|
|
3
|
+
*
|
|
4
|
+
* Creates a new skill with SKILL.md format.
|
|
5
|
+
* Useful for AI agents to help users create new skills.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolHandler } from '../types.js';
|
|
8
|
+
export interface CreateSkillInput {
|
|
9
|
+
name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
instructions?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function createCreateSkillHandler(): ToolHandler;
|
|
14
|
+
//# sourceMappingURL=create-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-skill.d.ts","sourceRoot":"","sources":["../../src/tools/create-skill.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAI3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAgCD,wBAAgB,wBAAwB,IAAI,WAAW,CA8EtD"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: create_skill
|
|
3
|
+
*
|
|
4
|
+
* Creates a new skill with SKILL.md format.
|
|
5
|
+
* Useful for AI agents to help users create new skills.
|
|
6
|
+
*/
|
|
7
|
+
import { successResult, errorResult, validateString } from './utils.js';
|
|
8
|
+
import { SkillCreator } from 'skillpkg-core';
|
|
9
|
+
/**
|
|
10
|
+
* Convert string to kebab-case
|
|
11
|
+
*/
|
|
12
|
+
function toKebabCase(str) {
|
|
13
|
+
return str
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
16
|
+
.replace(/^-|-$/g, '');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validate skill name
|
|
20
|
+
*/
|
|
21
|
+
function validateSkillName(name) {
|
|
22
|
+
if (!name) {
|
|
23
|
+
return 'Name is required';
|
|
24
|
+
}
|
|
25
|
+
const normalized = toKebabCase(name);
|
|
26
|
+
if (normalized.length < 2) {
|
|
27
|
+
return 'Name must be at least 2 characters';
|
|
28
|
+
}
|
|
29
|
+
if (normalized.length > 100) {
|
|
30
|
+
return 'Name must be less than 100 characters';
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
export function createCreateSkillHandler() {
|
|
35
|
+
return {
|
|
36
|
+
name: 'create_skill',
|
|
37
|
+
description: `Create a new skill with SKILL.md format.
|
|
38
|
+
|
|
39
|
+
This tool helps AI agents create new skills for users. It generates:
|
|
40
|
+
- A directory with the skill name
|
|
41
|
+
- A SKILL.md file with frontmatter and instructions
|
|
42
|
+
|
|
43
|
+
Parameters:
|
|
44
|
+
- name (required): Skill name (will be converted to kebab-case)
|
|
45
|
+
- description (optional): Short description of the skill
|
|
46
|
+
- instructions (optional): The skill instructions content
|
|
47
|
+
|
|
48
|
+
Returns the path to the created SKILL.md file.`,
|
|
49
|
+
inputSchema: {
|
|
50
|
+
type: 'object',
|
|
51
|
+
properties: {
|
|
52
|
+
name: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
description: 'Skill name (e.g., "my-helper", "code-reviewer")',
|
|
55
|
+
},
|
|
56
|
+
description: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description: 'Short description of what the skill does',
|
|
59
|
+
},
|
|
60
|
+
instructions: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
description: 'The full instructions content for the skill (markdown)',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: ['name'],
|
|
66
|
+
},
|
|
67
|
+
async execute(args) {
|
|
68
|
+
const input = args;
|
|
69
|
+
try {
|
|
70
|
+
const rawName = validateString(input.name, 'name');
|
|
71
|
+
// Validate name
|
|
72
|
+
const nameError = validateSkillName(rawName);
|
|
73
|
+
if (nameError) {
|
|
74
|
+
return errorResult(nameError);
|
|
75
|
+
}
|
|
76
|
+
const skillName = toKebabCase(rawName);
|
|
77
|
+
const description = input.description || 'A helpful skill';
|
|
78
|
+
const instructions = input.instructions;
|
|
79
|
+
const creator = new SkillCreator();
|
|
80
|
+
// Create the skill
|
|
81
|
+
const skillMdPath = await creator.create({
|
|
82
|
+
name: skillName,
|
|
83
|
+
description,
|
|
84
|
+
instructions,
|
|
85
|
+
createDir: true,
|
|
86
|
+
});
|
|
87
|
+
const lines = [
|
|
88
|
+
`✅ Created skill: ${skillName}`,
|
|
89
|
+
'',
|
|
90
|
+
`📄 File: ${skillMdPath}`,
|
|
91
|
+
'',
|
|
92
|
+
'📋 Next steps:',
|
|
93
|
+
` • Edit ${skillName}/SKILL.md to customize instructions`,
|
|
94
|
+
` • Run \`skillpkg install ./${skillName}\` to install locally`,
|
|
95
|
+
` • Run \`skillpkg sync\` to sync to AI platforms`,
|
|
96
|
+
];
|
|
97
|
+
return successResult(lines.join('\n'));
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
101
|
+
return errorResult(`Failed to create skill: ${message}`);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=create-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-skill.js","sourceRoot":"","sources":["../../src/tools/create-skill.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -12,10 +12,13 @@ import { createInstallSkillHandler } from './install-skill.js';
|
|
|
12
12
|
import { createUninstallSkillHandler } from './uninstall-skill.js';
|
|
13
13
|
import { createSkillInfoHandler } from './skill-info.js';
|
|
14
14
|
import { createRecommendSkillHandler } from './recommend-skill.js';
|
|
15
|
+
import { createSyncSkillsHandler } from './sync-skills.js';
|
|
16
|
+
import { createCreateSkillHandler } from './create-skill.js';
|
|
17
|
+
import { createSkillStatusHandler } from './skill-status.js';
|
|
15
18
|
/**
|
|
16
19
|
* Create all tool handlers
|
|
17
20
|
*/
|
|
18
21
|
export declare function createAllToolHandlers(): ToolHandler[];
|
|
19
|
-
export { createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSkillInfoHandler, createRecommendSkillHandler, };
|
|
22
|
+
export { createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSyncSkillsHandler, createCreateSkillHandler, createSkillStatusHandler, createSkillInfoHandler, createRecommendSkillHandler, };
|
|
20
23
|
export * from './utils.js';
|
|
21
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,EAAE,CAgBrD;AAGD,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,GAC5B,CAAC;AAGF,cAAc,YAAY,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -12,6 +12,9 @@ import { createInstallSkillHandler } from './install-skill.js';
|
|
|
12
12
|
import { createUninstallSkillHandler } from './uninstall-skill.js';
|
|
13
13
|
import { createSkillInfoHandler } from './skill-info.js';
|
|
14
14
|
import { createRecommendSkillHandler } from './recommend-skill.js';
|
|
15
|
+
import { createSyncSkillsHandler } from './sync-skills.js';
|
|
16
|
+
import { createCreateSkillHandler } from './create-skill.js';
|
|
17
|
+
import { createSkillStatusHandler } from './skill-status.js';
|
|
15
18
|
/**
|
|
16
19
|
* Create all tool handlers
|
|
17
20
|
*/
|
|
@@ -22,6 +25,9 @@ export function createAllToolHandlers() {
|
|
|
22
25
|
createLoadSkillHandler(),
|
|
23
26
|
createInstallSkillHandler(),
|
|
24
27
|
createUninstallSkillHandler(),
|
|
28
|
+
createSyncSkillsHandler(),
|
|
29
|
+
createCreateSkillHandler(),
|
|
30
|
+
createSkillStatusHandler(),
|
|
25
31
|
// Search & Discovery
|
|
26
32
|
createSearchSkillsHandler(),
|
|
27
33
|
createSkillInfoHandler(),
|
|
@@ -29,7 +35,7 @@ export function createAllToolHandlers() {
|
|
|
29
35
|
];
|
|
30
36
|
}
|
|
31
37
|
// Export individual handlers for selective use
|
|
32
|
-
export { createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSkillInfoHandler, createRecommendSkillHandler, };
|
|
38
|
+
export { createListSkillsHandler, createLoadSkillHandler, createSearchSkillsHandler, createInstallSkillHandler, createUninstallSkillHandler, createSyncSkillsHandler, createCreateSkillHandler, createSkillStatusHandler, createSkillInfoHandler, createRecommendSkillHandler, };
|
|
33
39
|
// Re-export utilities
|
|
34
40
|
export * from './utils.js';
|
|
35
41
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,2BAA2B;AAC3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,2BAA2B;AAC3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,wBAAwB;QACxB,uBAAuB,EAAE;QACzB,sBAAsB,EAAE;QACxB,yBAAyB,EAAE;QAC3B,2BAA2B,EAAE;QAC7B,uBAAuB,EAAE;QACzB,wBAAwB,EAAE;QAC1B,wBAAwB,EAAE;QAE1B,qBAAqB;QACrB,yBAAyB,EAAE;QAC3B,sBAAsB,EAAE;QACxB,2BAA2B,EAAE;KAC9B,CAAC;AACJ,CAAC;AAED,+CAA+C;AAC/C,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,2BAA2B,GAC5B,CAAC;AAEF,sBAAsB;AACtB,cAAc,YAAY,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool: install_skill
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* v2.0: Uses new Installer module with dependency resolution.
|
|
5
|
+
* Returns dependency info and MCP requirements.
|
|
6
6
|
*/
|
|
7
7
|
import type { ToolHandler } from '../types.js';
|
|
8
8
|
export declare function createInstallSkillHandler(): ToolHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/tools/install-skill.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/tools/install-skill.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAiC,MAAM,aAAa,CAAC;AAqN9E,wBAAgB,yBAAyB,IAAI,WAAW,CAyHvD"}
|
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool: install_skill
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* v2.0: Uses new Installer module with dependency resolution.
|
|
5
|
+
* Returns dependency info and MCP requirements.
|
|
6
6
|
*/
|
|
7
7
|
import { getStore, successResult, errorResult, validateString, validateScope } from './utils.js';
|
|
8
8
|
import { InvalidSourceError } from '../types.js';
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
* Parse source string to determine source type
|
|
12
|
-
*/
|
|
9
|
+
import matter from 'gray-matter';
|
|
10
|
+
import { detectSkillMd, fetchSkillMdContent, createInstaller, createStateManager, createConfigManager, } from 'skillpkg-core';
|
|
13
11
|
function parseSource(source) {
|
|
14
|
-
// GitHub: github:user/repo or user/repo
|
|
15
12
|
if (source.startsWith('github:')) {
|
|
16
13
|
return { type: 'github', value: source.slice(7) };
|
|
17
14
|
}
|
|
18
15
|
if (/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test(source)) {
|
|
19
16
|
return { type: 'github', value: source };
|
|
20
17
|
}
|
|
21
|
-
// Gist: gist:id
|
|
22
18
|
if (source.startsWith('gist:')) {
|
|
23
19
|
return { type: 'gist', value: source.slice(5) };
|
|
24
20
|
}
|
|
25
|
-
// URL: https:// or http://
|
|
26
21
|
if (source.startsWith('https://') || source.startsWith('http://')) {
|
|
27
22
|
return { type: 'url', value: source };
|
|
28
23
|
}
|
|
29
|
-
// Local path: starts with ./ or / or contains path separators
|
|
30
24
|
if (source.startsWith('./') || source.startsWith('/') || source.startsWith('../')) {
|
|
31
25
|
return { type: 'local', value: source };
|
|
32
26
|
}
|
|
33
|
-
// Simple skill names are no longer supported (no central registry)
|
|
34
|
-
// Suggest using github:owner/repo format instead
|
|
35
27
|
throw new InvalidSourceError(`Invalid source "${source}". Use one of: github:owner/repo, gist:id, https://url, or ./local/path`);
|
|
36
28
|
}
|
|
37
29
|
/**
|
|
@@ -45,36 +37,25 @@ async function fetchSkillFromUrl(url) {
|
|
|
45
37
|
return response.text();
|
|
46
38
|
}
|
|
47
39
|
/**
|
|
48
|
-
* Fetch skill from GitHub repo
|
|
49
|
-
* Uses shared logic from skillpkg-core
|
|
40
|
+
* Fetch skill from GitHub repo
|
|
50
41
|
*/
|
|
51
42
|
async function fetchSkillFromGitHub(repo) {
|
|
52
43
|
const token = process.env.GITHUB_TOKEN;
|
|
53
|
-
// Try SKILL.md first using core's detection
|
|
54
44
|
const detection = await detectSkillMd(repo, token);
|
|
55
45
|
if (detection.hasSkill && detection.skillFile) {
|
|
56
46
|
const content = await fetchSkillMdContent(repo, detection.skillFile, token);
|
|
57
47
|
if (content) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
for (const branch of branches) {
|
|
66
|
-
for (const path of skillYamlPaths) {
|
|
67
|
-
const url = `https://raw.githubusercontent.com/${repo}/${branch}/${path}`;
|
|
68
|
-
try {
|
|
69
|
-
const yamlContent = await fetchSkillFromUrl(url);
|
|
70
|
-
return yamlContent;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// Try next path/branch
|
|
74
|
-
}
|
|
48
|
+
return {
|
|
49
|
+
schema: '1.0',
|
|
50
|
+
name: content.name,
|
|
51
|
+
version: content.version,
|
|
52
|
+
description: content.description,
|
|
53
|
+
instructions: content.instructions,
|
|
54
|
+
};
|
|
75
55
|
}
|
|
76
56
|
}
|
|
77
|
-
|
|
57
|
+
// No SKILL.md found in standard locations
|
|
58
|
+
return null;
|
|
78
59
|
}
|
|
79
60
|
/**
|
|
80
61
|
* Fetch skill from Gist
|
|
@@ -86,13 +67,25 @@ async function fetchSkillFromGist(gistId) {
|
|
|
86
67
|
throw new Error(`Failed to fetch gist ${gistId}: ${response.status}`);
|
|
87
68
|
}
|
|
88
69
|
const gist = (await response.json());
|
|
89
|
-
// Look for
|
|
70
|
+
// Look for SKILL.md in Gist files
|
|
90
71
|
for (const [filename, file] of Object.entries(gist.files)) {
|
|
91
|
-
if (filename === '
|
|
92
|
-
|
|
72
|
+
if (filename === 'SKILL.md' || filename === 'skill.md') {
|
|
73
|
+
try {
|
|
74
|
+
const { data, content: body } = matter(file.content);
|
|
75
|
+
return {
|
|
76
|
+
schema: '1.0',
|
|
77
|
+
name: data.name || '',
|
|
78
|
+
version: data.version || '1.0.0',
|
|
79
|
+
description: data.description || '',
|
|
80
|
+
instructions: body.trim(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Invalid frontmatter
|
|
85
|
+
}
|
|
93
86
|
}
|
|
94
87
|
}
|
|
95
|
-
|
|
88
|
+
return null;
|
|
96
89
|
}
|
|
97
90
|
/**
|
|
98
91
|
* Fetch skill from local path
|
|
@@ -101,40 +94,117 @@ async function fetchSkillFromLocal(path) {
|
|
|
101
94
|
const fs = await import('fs/promises');
|
|
102
95
|
const nodePath = await import('path');
|
|
103
96
|
let skillPath = path;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
97
|
+
try {
|
|
98
|
+
const stat = await fs.stat(path);
|
|
99
|
+
if (stat.isDirectory()) {
|
|
100
|
+
// Only SKILL.md format is supported
|
|
101
|
+
const candidates = ['SKILL.md', 'skill.md'];
|
|
102
|
+
for (const candidate of candidates) {
|
|
103
|
+
const fullPath = nodePath.join(path, candidate);
|
|
104
|
+
try {
|
|
105
|
+
await fs.access(fullPath);
|
|
106
|
+
skillPath = fullPath;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Try next
|
|
111
|
+
}
|
|
114
112
|
}
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
}
|
|
114
|
+
// Only process SKILL.md files
|
|
115
|
+
if (!skillPath.toLowerCase().endsWith('.md')) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const content = await fs.readFile(skillPath, 'utf-8');
|
|
119
|
+
const { data, content: body } = matter(content);
|
|
120
|
+
return {
|
|
121
|
+
schema: '1.0',
|
|
122
|
+
name: data.name || '',
|
|
123
|
+
version: data.version || '1.0.0',
|
|
124
|
+
description: data.description || '',
|
|
125
|
+
instructions: body.trim(),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a SkillFetcherAdapter
|
|
134
|
+
*/
|
|
135
|
+
function createFetcher() {
|
|
136
|
+
return {
|
|
137
|
+
async fetchMetadata(source) {
|
|
138
|
+
const skill = await fetchSkillBySource(source);
|
|
139
|
+
if (!skill)
|
|
140
|
+
return null;
|
|
141
|
+
return {
|
|
142
|
+
name: skill.name,
|
|
143
|
+
version: skill.version,
|
|
144
|
+
dependencies: skill.dependencies,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
async fetchSkill(source) {
|
|
148
|
+
return fetchSkillBySource(source);
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
async function fetchSkillBySource(source) {
|
|
153
|
+
try {
|
|
154
|
+
const { type, value } = parseSource(source);
|
|
155
|
+
switch (type) {
|
|
156
|
+
case 'github':
|
|
157
|
+
return fetchSkillFromGitHub(value);
|
|
158
|
+
case 'gist':
|
|
159
|
+
return fetchSkillFromGist(value);
|
|
160
|
+
case 'url': {
|
|
161
|
+
const content = await fetchSkillFromUrl(value);
|
|
162
|
+
// Parse as SKILL.md format with gray-matter
|
|
163
|
+
try {
|
|
164
|
+
const { data, content: body } = matter(content);
|
|
165
|
+
return {
|
|
166
|
+
schema: '1.0',
|
|
167
|
+
name: data.name || '',
|
|
168
|
+
version: data.version || '1.0.0',
|
|
169
|
+
description: data.description || '',
|
|
170
|
+
instructions: body.trim(),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
117
176
|
}
|
|
177
|
+
case 'local':
|
|
178
|
+
return fetchSkillFromLocal(value);
|
|
118
179
|
}
|
|
119
180
|
}
|
|
120
|
-
|
|
181
|
+
catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
121
184
|
}
|
|
122
185
|
export function createInstallSkillHandler() {
|
|
123
186
|
return {
|
|
124
187
|
name: 'install_skill',
|
|
125
|
-
description: `Install a skill from various sources
|
|
188
|
+
description: `Install a skill from various sources with dependency resolution.
|
|
189
|
+
|
|
190
|
+
Supports SKILL.md format (industry standard for Claude Code and OpenAI Codex).
|
|
126
191
|
|
|
127
192
|
Supported source formats:
|
|
128
193
|
• GitHub: github:user/repo or user/repo (e.g., "anthropics/claude-code-skills")
|
|
129
194
|
• Gist: gist:id (e.g., "gist:abc123")
|
|
130
|
-
• URL: https://... (direct link to SKILL.md
|
|
131
|
-
• Local: ./path or /absolute/path (local file or directory)
|
|
195
|
+
• URL: https://... (direct link to SKILL.md)
|
|
196
|
+
• Local: ./path or /absolute/path (local file or directory)
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
• List of installed skills (including dependencies)
|
|
200
|
+
• MCP servers required by the skill
|
|
201
|
+
• Suggestions for next steps`,
|
|
132
202
|
inputSchema: {
|
|
133
203
|
type: 'object',
|
|
134
204
|
properties: {
|
|
135
205
|
source: {
|
|
136
206
|
type: 'string',
|
|
137
|
-
description: 'Source to install from:
|
|
207
|
+
description: 'Source to install from: github:user/repo, gist:id, URL, or local path',
|
|
138
208
|
},
|
|
139
209
|
scope: {
|
|
140
210
|
type: 'string',
|
|
@@ -150,70 +220,63 @@ Supported source formats:
|
|
|
150
220
|
try {
|
|
151
221
|
const sourceStr = validateString(input.source, 'source');
|
|
152
222
|
const scope = validateScope(input.scope, 'local');
|
|
153
|
-
//
|
|
223
|
+
// Normalize source
|
|
154
224
|
const { type, value } = parseSource(sourceStr);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
break;
|
|
167
|
-
case 'local':
|
|
168
|
-
skillContent = await fetchSkillFromLocal(value);
|
|
169
|
-
break;
|
|
225
|
+
const normalizedSource = type === 'github' ? `github:${value}` : sourceStr;
|
|
226
|
+
// Get project path (cwd for MCP server context)
|
|
227
|
+
const cwd = process.cwd();
|
|
228
|
+
// Create installer
|
|
229
|
+
const stateManager = createStateManager();
|
|
230
|
+
const configManager = createConfigManager();
|
|
231
|
+
const storeManager = getStore(scope);
|
|
232
|
+
const fetcher = createFetcher();
|
|
233
|
+
// Initialize store if needed
|
|
234
|
+
if (!(await storeManager.isInitialized())) {
|
|
235
|
+
await storeManager.init();
|
|
170
236
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
237
|
+
const installer = createInstaller(stateManager, configManager, storeManager, fetcher);
|
|
238
|
+
// Run installation
|
|
239
|
+
const result = await installer.install(cwd, normalizedSource);
|
|
240
|
+
if (!result.success) {
|
|
241
|
+
const errors = result.errors.join('; ');
|
|
242
|
+
return errorResult(`Installation failed: ${errors}`);
|
|
176
243
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
244
|
+
// Build response
|
|
245
|
+
const installed = result.skills.filter((s) => s.action === 'installed');
|
|
246
|
+
const updated = result.skills.filter((s) => s.action === 'updated');
|
|
247
|
+
const skipped = result.skills.filter((s) => s.action === 'skipped');
|
|
248
|
+
const lines = [];
|
|
249
|
+
if (installed.length > 0) {
|
|
250
|
+
lines.push(`✅ Installed ${installed.length} skill(s):`);
|
|
251
|
+
for (const skill of installed) {
|
|
252
|
+
const note = skill.transitive ? ` (dependency of ${skill.requiredBy})` : '';
|
|
253
|
+
lines.push(` • ${skill.name} v${skill.version}${note}`);
|
|
254
|
+
}
|
|
182
255
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
success: true,
|
|
189
|
-
skill: {
|
|
190
|
-
id: `${scope}:${skill.name}`,
|
|
191
|
-
name: skill.name,
|
|
192
|
-
version: skill.version,
|
|
193
|
-
source: sourceStr,
|
|
194
|
-
installedAt: new Date().toISOString(),
|
|
195
|
-
},
|
|
196
|
-
message: `Updated "${skill.name}" to v${skill.version} in ${scope} scope.`,
|
|
197
|
-
};
|
|
198
|
-
return successResult(output.message);
|
|
256
|
+
if (updated.length > 0) {
|
|
257
|
+
lines.push(`🔄 Updated ${updated.length} skill(s):`);
|
|
258
|
+
for (const skill of updated) {
|
|
259
|
+
lines.push(` • ${skill.name} v${skill.version}`);
|
|
260
|
+
}
|
|
199
261
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
262
|
+
if (skipped.length > 0) {
|
|
263
|
+
lines.push(`⏭️ Skipped ${skipped.length} already installed skill(s)`);
|
|
264
|
+
}
|
|
265
|
+
// MCP requirements
|
|
266
|
+
if (result.mcpRequired.length > 0) {
|
|
267
|
+
lines.push('');
|
|
268
|
+
lines.push('⚠️ MCP servers required:');
|
|
269
|
+
for (const mcp of result.mcpRequired) {
|
|
270
|
+
lines.push(` • ${mcp}`);
|
|
271
|
+
}
|
|
272
|
+
lines.push(' Configure these in your skillpkg.json or install manually.');
|
|
273
|
+
}
|
|
274
|
+
// Next steps
|
|
275
|
+
lines.push('');
|
|
276
|
+
lines.push('📋 Next steps:');
|
|
277
|
+
lines.push(' • Run `skillpkg sync` to sync to AI platforms');
|
|
278
|
+
lines.push(' • Run `skillpkg tree` to see dependency tree');
|
|
279
|
+
return successResult(lines.join('\n'));
|
|
217
280
|
}
|
|
218
281
|
catch (error) {
|
|
219
282
|
if (error instanceof InvalidSourceError) {
|