skillpkg-core 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/dist/adapters/base.d.ts +48 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +54 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +39 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +172 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/cline.d.ts +43 -0
- package/dist/adapters/cline.d.ts.map +1 -0
- package/dist/adapters/cline.js +157 -0
- package/dist/adapters/cline.js.map +1 -0
- package/dist/adapters/codex.d.ts +31 -0
- package/dist/adapters/codex.d.ts.map +1 -0
- package/dist/adapters/codex.js +117 -0
- package/dist/adapters/codex.js.map +1 -0
- package/dist/adapters/copilot.d.ts +44 -0
- package/dist/adapters/copilot.d.ts.map +1 -0
- package/dist/adapters/copilot.js +183 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/index.d.ts +11 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +13 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/manager.d.ts +51 -0
- package/dist/adapters/manager.d.ts.map +1 -0
- package/dist/adapters/manager.js +147 -0
- package/dist/adapters/manager.js.map +1 -0
- package/dist/adapters/types.d.ts +93 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/exporter/exporter.d.ts +54 -0
- package/dist/exporter/exporter.d.ts.map +1 -0
- package/dist/exporter/exporter.js +303 -0
- package/dist/exporter/exporter.js.map +1 -0
- package/dist/exporter/index.d.ts +6 -0
- package/dist/exporter/index.d.ts.map +1 -0
- package/dist/exporter/index.js +6 -0
- package/dist/exporter/index.js.map +1 -0
- package/dist/exporter/types.d.ts +38 -0
- package/dist/exporter/types.d.ts.map +1 -0
- package/dist/exporter/types.js +5 -0
- package/dist/exporter/types.js.map +1 -0
- package/dist/importer/importer.d.ts +37 -0
- package/dist/importer/importer.d.ts.map +1 -0
- package/dist/importer/importer.js +204 -0
- package/dist/importer/importer.js.map +1 -0
- package/dist/importer/index.d.ts +6 -0
- package/dist/importer/index.d.ts.map +1 -0
- package/dist/importer/index.js +6 -0
- package/dist/importer/index.js.map +1 -0
- package/dist/importer/types.d.ts +43 -0
- package/dist/importer/types.d.ts.map +1 -0
- package/dist/importer/types.js +2 -0
- package/dist/importer/types.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +23 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +24 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parser.d.ts +64 -0
- package/dist/parser/parser.d.ts.map +1 -0
- package/dist/parser/parser.js +121 -0
- package/dist/parser/parser.js.map +1 -0
- package/dist/parser/schema.d.ts +155 -0
- package/dist/parser/schema.d.ts.map +1 -0
- package/dist/parser/schema.js +147 -0
- package/dist/parser/schema.js.map +1 -0
- package/dist/parser/validator.d.ts +38 -0
- package/dist/parser/validator.d.ts.map +1 -0
- package/dist/parser/validator.js +125 -0
- package/dist/parser/validator.js.map +1 -0
- package/dist/registry/auth.d.ts +38 -0
- package/dist/registry/auth.d.ts.map +1 -0
- package/dist/registry/auth.js +142 -0
- package/dist/registry/auth.js.map +1 -0
- package/dist/registry/client.d.ts +80 -0
- package/dist/registry/client.d.ts.map +1 -0
- package/dist/registry/client.js +238 -0
- package/dist/registry/client.js.map +1 -0
- package/dist/registry/index.d.ts +10 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +9 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/types.d.ts +94 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +18 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/store/config.d.ts +30 -0
- package/dist/store/config.d.ts.map +1 -0
- package/dist/store/config.js +112 -0
- package/dist/store/config.js.map +1 -0
- package/dist/store/index.d.ts +21 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +24 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/manager.d.ts +113 -0
- package/dist/store/manager.d.ts.map +1 -0
- package/dist/store/manager.js +250 -0
- package/dist/store/manager.js.map +1 -0
- package/dist/store/paths.d.ts +37 -0
- package/dist/store/paths.d.ts.map +1 -0
- package/dist/store/paths.js +60 -0
- package/dist/store/paths.js.map +1 -0
- package/dist/store/registry.d.ts +34 -0
- package/dist/store/registry.d.ts.map +1 -0
- package/dist/store/registry.js +105 -0
- package/dist/store/registry.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema for skill.yaml validation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* JSON Schema for skill.yaml
|
|
6
|
+
* Using plain object instead of JSONSchemaType for flexibility
|
|
7
|
+
*/
|
|
8
|
+
export declare const skillSchema: {
|
|
9
|
+
readonly type: "object";
|
|
10
|
+
readonly properties: {
|
|
11
|
+
readonly schema: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly pattern: "^\\d+\\.\\d+$";
|
|
14
|
+
readonly description: "Schema version (e.g., \"1.0\")";
|
|
15
|
+
};
|
|
16
|
+
readonly name: {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
readonly pattern: "^[a-z][a-z0-9-]*[a-z0-9]$";
|
|
19
|
+
readonly minLength: 2;
|
|
20
|
+
readonly maxLength: 100;
|
|
21
|
+
readonly description: "Unique skill identifier in kebab-case";
|
|
22
|
+
};
|
|
23
|
+
readonly version: {
|
|
24
|
+
readonly type: "string";
|
|
25
|
+
readonly pattern: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$";
|
|
26
|
+
readonly description: "Semantic version (e.g., \"1.0.0\")";
|
|
27
|
+
};
|
|
28
|
+
readonly description: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
readonly minLength: 1;
|
|
31
|
+
readonly maxLength: 500;
|
|
32
|
+
readonly description: "Short description of the skill";
|
|
33
|
+
};
|
|
34
|
+
readonly instructions: {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly minLength: 1;
|
|
37
|
+
readonly description: "Markdown instructions for the AI agent";
|
|
38
|
+
};
|
|
39
|
+
readonly author: {
|
|
40
|
+
readonly oneOf: readonly [{
|
|
41
|
+
readonly type: "string";
|
|
42
|
+
}, {
|
|
43
|
+
readonly type: "object";
|
|
44
|
+
readonly properties: {
|
|
45
|
+
readonly name: {
|
|
46
|
+
readonly type: "string";
|
|
47
|
+
};
|
|
48
|
+
readonly email: {
|
|
49
|
+
readonly type: "string";
|
|
50
|
+
readonly format: "email";
|
|
51
|
+
};
|
|
52
|
+
readonly url: {
|
|
53
|
+
readonly type: "string";
|
|
54
|
+
readonly format: "uri";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly required: readonly ["name"];
|
|
58
|
+
readonly additionalProperties: false;
|
|
59
|
+
}];
|
|
60
|
+
readonly description: "Author name or object with name, email, url";
|
|
61
|
+
};
|
|
62
|
+
readonly license: {
|
|
63
|
+
readonly type: "string";
|
|
64
|
+
readonly description: "License identifier (e.g., \"MIT\")";
|
|
65
|
+
};
|
|
66
|
+
readonly repository: {
|
|
67
|
+
readonly type: "string";
|
|
68
|
+
readonly format: "uri";
|
|
69
|
+
readonly description: "Repository URL";
|
|
70
|
+
};
|
|
71
|
+
readonly keywords: {
|
|
72
|
+
readonly type: "array";
|
|
73
|
+
readonly items: {
|
|
74
|
+
readonly type: "string";
|
|
75
|
+
};
|
|
76
|
+
readonly description: "Keywords for search";
|
|
77
|
+
};
|
|
78
|
+
readonly triggers: {
|
|
79
|
+
readonly type: "array";
|
|
80
|
+
readonly items: {
|
|
81
|
+
readonly type: "string";
|
|
82
|
+
};
|
|
83
|
+
readonly description: "Trigger words to activate the skill";
|
|
84
|
+
};
|
|
85
|
+
readonly capabilities: {
|
|
86
|
+
readonly type: "array";
|
|
87
|
+
readonly items: {
|
|
88
|
+
readonly type: "string";
|
|
89
|
+
readonly enum: readonly ["file:read", "file:write", "shell:execute", "web:search", "web:fetch", "mcp:*"];
|
|
90
|
+
};
|
|
91
|
+
readonly description: "Required capabilities";
|
|
92
|
+
};
|
|
93
|
+
readonly platforms: {
|
|
94
|
+
readonly type: "object";
|
|
95
|
+
readonly properties: {
|
|
96
|
+
readonly 'claude-code': {
|
|
97
|
+
readonly type: "object";
|
|
98
|
+
readonly properties: {
|
|
99
|
+
readonly 'allowed-tools': {
|
|
100
|
+
readonly type: "array";
|
|
101
|
+
readonly items: {
|
|
102
|
+
readonly type: "string";
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
readonly additionalProperties: false;
|
|
107
|
+
};
|
|
108
|
+
readonly codex: {
|
|
109
|
+
readonly type: "object";
|
|
110
|
+
readonly properties: {
|
|
111
|
+
readonly sandbox: {
|
|
112
|
+
readonly type: "boolean";
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
readonly additionalProperties: false;
|
|
116
|
+
};
|
|
117
|
+
readonly copilot: {
|
|
118
|
+
readonly type: "object";
|
|
119
|
+
readonly properties: {
|
|
120
|
+
readonly mode: {
|
|
121
|
+
readonly type: "string";
|
|
122
|
+
readonly enum: readonly ["edit", "chat"];
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
readonly additionalProperties: false;
|
|
126
|
+
};
|
|
127
|
+
readonly cline: {
|
|
128
|
+
readonly type: "object";
|
|
129
|
+
readonly properties: {
|
|
130
|
+
readonly customRules: {
|
|
131
|
+
readonly type: "string";
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
readonly additionalProperties: false;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
readonly additionalProperties: false;
|
|
138
|
+
readonly description: "Platform-specific configurations";
|
|
139
|
+
};
|
|
140
|
+
readonly dependencies: {
|
|
141
|
+
readonly type: "object";
|
|
142
|
+
readonly additionalProperties: {
|
|
143
|
+
readonly type: "string";
|
|
144
|
+
};
|
|
145
|
+
readonly description: "Skill dependencies with version ranges";
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
readonly required: readonly ["schema", "name", "version", "description", "instructions"];
|
|
149
|
+
readonly additionalProperties: false;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Human-readable field descriptions for error messages
|
|
153
|
+
*/
|
|
154
|
+
export declare const fieldDescriptions: Record<string, string>;
|
|
155
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/parser/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwHd,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAcpD,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema for skill.yaml validation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* JSON Schema for skill.yaml
|
|
6
|
+
* Using plain object instead of JSONSchemaType for flexibility
|
|
7
|
+
*/
|
|
8
|
+
export const skillSchema = {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
schema: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
pattern: '^\\d+\\.\\d+$',
|
|
14
|
+
description: 'Schema version (e.g., "1.0")',
|
|
15
|
+
},
|
|
16
|
+
name: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
pattern: '^[a-z][a-z0-9-]*[a-z0-9]$',
|
|
19
|
+
minLength: 2,
|
|
20
|
+
maxLength: 100,
|
|
21
|
+
description: 'Unique skill identifier in kebab-case',
|
|
22
|
+
},
|
|
23
|
+
version: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
pattern: '^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$',
|
|
26
|
+
description: 'Semantic version (e.g., "1.0.0")',
|
|
27
|
+
},
|
|
28
|
+
description: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
minLength: 1,
|
|
31
|
+
maxLength: 500,
|
|
32
|
+
description: 'Short description of the skill',
|
|
33
|
+
},
|
|
34
|
+
instructions: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
minLength: 1,
|
|
37
|
+
description: 'Markdown instructions for the AI agent',
|
|
38
|
+
},
|
|
39
|
+
author: {
|
|
40
|
+
oneOf: [
|
|
41
|
+
{ type: 'string' },
|
|
42
|
+
{
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
name: { type: 'string' },
|
|
46
|
+
email: { type: 'string', format: 'email' },
|
|
47
|
+
url: { type: 'string', format: 'uri' },
|
|
48
|
+
},
|
|
49
|
+
required: ['name'],
|
|
50
|
+
additionalProperties: false,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
description: 'Author name or object with name, email, url',
|
|
54
|
+
},
|
|
55
|
+
license: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'License identifier (e.g., "MIT")',
|
|
58
|
+
},
|
|
59
|
+
repository: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
format: 'uri',
|
|
62
|
+
description: 'Repository URL',
|
|
63
|
+
},
|
|
64
|
+
keywords: {
|
|
65
|
+
type: 'array',
|
|
66
|
+
items: { type: 'string' },
|
|
67
|
+
description: 'Keywords for search',
|
|
68
|
+
},
|
|
69
|
+
triggers: {
|
|
70
|
+
type: 'array',
|
|
71
|
+
items: { type: 'string' },
|
|
72
|
+
description: 'Trigger words to activate the skill',
|
|
73
|
+
},
|
|
74
|
+
capabilities: {
|
|
75
|
+
type: 'array',
|
|
76
|
+
items: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
enum: ['file:read', 'file:write', 'shell:execute', 'web:search', 'web:fetch', 'mcp:*'],
|
|
79
|
+
},
|
|
80
|
+
description: 'Required capabilities',
|
|
81
|
+
},
|
|
82
|
+
platforms: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
'claude-code': {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
'allowed-tools': {
|
|
89
|
+
type: 'array',
|
|
90
|
+
items: { type: 'string' },
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
additionalProperties: false,
|
|
94
|
+
},
|
|
95
|
+
codex: {
|
|
96
|
+
type: 'object',
|
|
97
|
+
properties: {
|
|
98
|
+
sandbox: { type: 'boolean' },
|
|
99
|
+
},
|
|
100
|
+
additionalProperties: false,
|
|
101
|
+
},
|
|
102
|
+
copilot: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
mode: { type: 'string', enum: ['edit', 'chat'] },
|
|
106
|
+
},
|
|
107
|
+
additionalProperties: false,
|
|
108
|
+
},
|
|
109
|
+
cline: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
customRules: { type: 'string' },
|
|
113
|
+
},
|
|
114
|
+
additionalProperties: false,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
description: 'Platform-specific configurations',
|
|
119
|
+
},
|
|
120
|
+
dependencies: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
additionalProperties: { type: 'string' },
|
|
123
|
+
description: 'Skill dependencies with version ranges',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
required: ['schema', 'name', 'version', 'description', 'instructions'],
|
|
127
|
+
additionalProperties: false,
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Human-readable field descriptions for error messages
|
|
131
|
+
*/
|
|
132
|
+
export const fieldDescriptions = {
|
|
133
|
+
schema: 'Schema version (e.g., "1.0")',
|
|
134
|
+
name: 'Unique skill identifier in kebab-case (e.g., "my-skill")',
|
|
135
|
+
version: 'Semantic version (e.g., "1.0.0")',
|
|
136
|
+
description: 'Short description of the skill (max 500 chars)',
|
|
137
|
+
instructions: 'Markdown instructions for the AI agent',
|
|
138
|
+
author: 'Author name or object with name, email, url',
|
|
139
|
+
license: 'License identifier (e.g., "MIT")',
|
|
140
|
+
repository: 'Repository URL',
|
|
141
|
+
keywords: 'Keywords for search',
|
|
142
|
+
triggers: 'Trigger words to activate the skill',
|
|
143
|
+
capabilities: 'Required capabilities (file:read, shell:execute, etc.)',
|
|
144
|
+
platforms: 'Platform-specific configurations',
|
|
145
|
+
dependencies: 'Skill dependencies with version ranges',
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/parser/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation error with detailed information
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationError {
|
|
5
|
+
/** JSON path to the error (e.g., "/name") */
|
|
6
|
+
path: string;
|
|
7
|
+
/** Human-readable error message */
|
|
8
|
+
message: string;
|
|
9
|
+
/** Expected value/type */
|
|
10
|
+
expected?: string;
|
|
11
|
+
/** Actual value received */
|
|
12
|
+
actual?: unknown;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Validation warning (non-critical issues)
|
|
16
|
+
*/
|
|
17
|
+
export interface ValidationWarning {
|
|
18
|
+
/** JSON path to the warning */
|
|
19
|
+
path: string;
|
|
20
|
+
/** Warning message */
|
|
21
|
+
message: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validation result
|
|
25
|
+
*/
|
|
26
|
+
export interface ValidationResult {
|
|
27
|
+
/** Whether the skill is valid */
|
|
28
|
+
valid: boolean;
|
|
29
|
+
/** Validation errors (if any) */
|
|
30
|
+
errors: ValidationError[];
|
|
31
|
+
/** Validation warnings (non-critical) */
|
|
32
|
+
warnings: ValidationWarning[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate a skill object against the schema
|
|
36
|
+
*/
|
|
37
|
+
export declare function validate(skill: unknown): ValidationResult;
|
|
38
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAaD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAqGzD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill validation using JSON Schema
|
|
3
|
+
*/
|
|
4
|
+
import Ajv from 'ajv';
|
|
5
|
+
import addFormats from 'ajv-formats';
|
|
6
|
+
import { skillSchema, fieldDescriptions } from './schema.js';
|
|
7
|
+
// Create Ajv instance with formats
|
|
8
|
+
const ajv = new Ajv({
|
|
9
|
+
allErrors: true,
|
|
10
|
+
verbose: true,
|
|
11
|
+
strict: false,
|
|
12
|
+
});
|
|
13
|
+
addFormats(ajv);
|
|
14
|
+
// Compile the schema
|
|
15
|
+
const validateSkill = ajv.compile(skillSchema);
|
|
16
|
+
/**
|
|
17
|
+
* Validate a skill object against the schema
|
|
18
|
+
*/
|
|
19
|
+
export function validate(skill) {
|
|
20
|
+
const errors = [];
|
|
21
|
+
const warnings = [];
|
|
22
|
+
// Run JSON Schema validation
|
|
23
|
+
const isValid = validateSkill(skill);
|
|
24
|
+
if (!isValid && validateSkill.errors) {
|
|
25
|
+
for (const error of validateSkill.errors) {
|
|
26
|
+
const path = error.instancePath || '/';
|
|
27
|
+
const fieldName = path.split('/').pop() || 'root';
|
|
28
|
+
const description = fieldDescriptions[fieldName] || '';
|
|
29
|
+
let message = error.message || 'Validation error';
|
|
30
|
+
let expected;
|
|
31
|
+
// Enhance error messages
|
|
32
|
+
switch (error.keyword) {
|
|
33
|
+
case 'required':
|
|
34
|
+
message = `Missing required field: ${error.params.missingProperty}`;
|
|
35
|
+
expected = description || undefined;
|
|
36
|
+
break;
|
|
37
|
+
case 'pattern':
|
|
38
|
+
message = `Invalid format for "${fieldName}"`;
|
|
39
|
+
expected = getPatternDescription(fieldName);
|
|
40
|
+
break;
|
|
41
|
+
case 'enum':
|
|
42
|
+
message = `Invalid value for "${fieldName}"`;
|
|
43
|
+
expected = `One of: ${error.params.allowedValues.join(', ')}`;
|
|
44
|
+
break;
|
|
45
|
+
case 'type':
|
|
46
|
+
message = `Invalid type for "${fieldName}"`;
|
|
47
|
+
expected = error.params.type;
|
|
48
|
+
break;
|
|
49
|
+
case 'minLength':
|
|
50
|
+
message = `"${fieldName}" is too short`;
|
|
51
|
+
expected = `At least ${error.params.limit} characters`;
|
|
52
|
+
break;
|
|
53
|
+
case 'maxLength':
|
|
54
|
+
message = `"${fieldName}" is too long`;
|
|
55
|
+
expected = `At most ${error.params.limit} characters`;
|
|
56
|
+
break;
|
|
57
|
+
case 'format':
|
|
58
|
+
message = `Invalid ${error.params.format} format for "${fieldName}"`;
|
|
59
|
+
break;
|
|
60
|
+
case 'additionalProperties':
|
|
61
|
+
message = `Unknown field: ${error.params.additionalProperty}`;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
errors.push({
|
|
65
|
+
path,
|
|
66
|
+
message,
|
|
67
|
+
expected,
|
|
68
|
+
actual: error.data,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Add warnings for best practices (even if valid)
|
|
73
|
+
if (typeof skill === 'object' && skill !== null) {
|
|
74
|
+
const s = skill;
|
|
75
|
+
// Warn if no triggers defined
|
|
76
|
+
if (!s.triggers || s.triggers.length === 0) {
|
|
77
|
+
warnings.push({
|
|
78
|
+
path: '/triggers',
|
|
79
|
+
message: 'No trigger words defined. Consider adding triggers for easier activation.',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// Warn if no capabilities defined
|
|
83
|
+
if (!s.capabilities || s.capabilities.length === 0) {
|
|
84
|
+
warnings.push({
|
|
85
|
+
path: '/capabilities',
|
|
86
|
+
message: 'No capabilities declared. Consider declaring required capabilities.',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Warn if description is too short
|
|
90
|
+
if (s.description && s.description.length < 20) {
|
|
91
|
+
warnings.push({
|
|
92
|
+
path: '/description',
|
|
93
|
+
message: 'Description is very short. Consider adding more detail.',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Warn if no author
|
|
97
|
+
if (!s.author) {
|
|
98
|
+
warnings.push({
|
|
99
|
+
path: '/author',
|
|
100
|
+
message: 'No author specified. Consider adding author information.',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
valid: errors.length === 0,
|
|
106
|
+
errors,
|
|
107
|
+
warnings,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get human-readable pattern description
|
|
112
|
+
*/
|
|
113
|
+
function getPatternDescription(fieldName) {
|
|
114
|
+
switch (fieldName) {
|
|
115
|
+
case 'name':
|
|
116
|
+
return 'kebab-case (e.g., "my-skill-name")';
|
|
117
|
+
case 'version':
|
|
118
|
+
return 'Semantic version (e.g., "1.0.0")';
|
|
119
|
+
case 'schema':
|
|
120
|
+
return 'Version number (e.g., "1.0")';
|
|
121
|
+
default:
|
|
122
|
+
return '';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/parser/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth token data
|
|
3
|
+
*/
|
|
4
|
+
export interface AuthToken {
|
|
5
|
+
token: string;
|
|
6
|
+
registry: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
expiresAt?: string;
|
|
9
|
+
username?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get token for a registry URL
|
|
13
|
+
*/
|
|
14
|
+
export declare function getToken(registryUrl: string): Promise<string | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Save token for a registry URL
|
|
17
|
+
*/
|
|
18
|
+
export declare function setToken(registryUrl: string, token: string, options?: {
|
|
19
|
+
expiresIn?: number;
|
|
20
|
+
username?: string;
|
|
21
|
+
}): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Remove token for a registry URL
|
|
24
|
+
*/
|
|
25
|
+
export declare function removeToken(registryUrl: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Get all saved tokens
|
|
28
|
+
*/
|
|
29
|
+
export declare function listTokens(): Promise<AuthToken[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if authenticated for a registry
|
|
32
|
+
*/
|
|
33
|
+
export declare function isAuthenticated(registryUrl: string): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Get username for a registry
|
|
36
|
+
*/
|
|
37
|
+
export declare function getUsername(registryUrl: string): Promise<string | null>;
|
|
38
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/registry/auth.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAyDD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqB1E;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWvE;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAGvD;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAI7E"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry authentication module
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile, chmod, mkdir } from 'fs/promises';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
/**
|
|
9
|
+
* Get auth file path
|
|
10
|
+
*/
|
|
11
|
+
function getAuthPath() {
|
|
12
|
+
return join(homedir(), '.skillpkg', 'auth.json');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Load auth file
|
|
16
|
+
*/
|
|
17
|
+
async function loadAuthFile() {
|
|
18
|
+
const authPath = getAuthPath();
|
|
19
|
+
if (!existsSync(authPath)) {
|
|
20
|
+
return { tokens: {} };
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const content = await readFile(authPath, 'utf-8');
|
|
24
|
+
return JSON.parse(content);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { tokens: {} };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Save auth file with secure permissions (600)
|
|
32
|
+
*/
|
|
33
|
+
async function saveAuthFile(auth) {
|
|
34
|
+
const authPath = getAuthPath();
|
|
35
|
+
const dir = dirname(authPath);
|
|
36
|
+
// Ensure directory exists
|
|
37
|
+
if (!existsSync(dir)) {
|
|
38
|
+
await mkdir(dir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
// Write file
|
|
41
|
+
await writeFile(authPath, JSON.stringify(auth, null, 2), 'utf-8');
|
|
42
|
+
// Set secure permissions (readable/writable only by owner)
|
|
43
|
+
try {
|
|
44
|
+
await chmod(authPath, 0o600);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Ignore permission errors on Windows
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get token for a registry URL
|
|
52
|
+
*/
|
|
53
|
+
export async function getToken(registryUrl) {
|
|
54
|
+
const auth = await loadAuthFile();
|
|
55
|
+
const normalizedUrl = normalizeRegistryUrl(registryUrl);
|
|
56
|
+
const tokenData = auth.tokens[normalizedUrl];
|
|
57
|
+
if (!tokenData) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
// Check if token is expired
|
|
61
|
+
if (tokenData.expiresAt) {
|
|
62
|
+
const expiresAt = new Date(tokenData.expiresAt);
|
|
63
|
+
if (expiresAt < new Date()) {
|
|
64
|
+
// Token expired, remove it
|
|
65
|
+
delete auth.tokens[normalizedUrl];
|
|
66
|
+
await saveAuthFile(auth);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return tokenData.token;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Save token for a registry URL
|
|
74
|
+
*/
|
|
75
|
+
export async function setToken(registryUrl, token, options) {
|
|
76
|
+
const auth = await loadAuthFile();
|
|
77
|
+
const normalizedUrl = normalizeRegistryUrl(registryUrl);
|
|
78
|
+
const tokenData = {
|
|
79
|
+
token,
|
|
80
|
+
registry: normalizedUrl,
|
|
81
|
+
createdAt: new Date().toISOString(),
|
|
82
|
+
username: options?.username,
|
|
83
|
+
};
|
|
84
|
+
if (options?.expiresIn) {
|
|
85
|
+
const expiresAt = new Date();
|
|
86
|
+
expiresAt.setSeconds(expiresAt.getSeconds() + options.expiresIn);
|
|
87
|
+
tokenData.expiresAt = expiresAt.toISOString();
|
|
88
|
+
}
|
|
89
|
+
auth.tokens[normalizedUrl] = tokenData;
|
|
90
|
+
await saveAuthFile(auth);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Remove token for a registry URL
|
|
94
|
+
*/
|
|
95
|
+
export async function removeToken(registryUrl) {
|
|
96
|
+
const auth = await loadAuthFile();
|
|
97
|
+
const normalizedUrl = normalizeRegistryUrl(registryUrl);
|
|
98
|
+
if (!auth.tokens[normalizedUrl]) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
delete auth.tokens[normalizedUrl];
|
|
102
|
+
await saveAuthFile(auth);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get all saved tokens
|
|
107
|
+
*/
|
|
108
|
+
export async function listTokens() {
|
|
109
|
+
const auth = await loadAuthFile();
|
|
110
|
+
return Object.values(auth.tokens);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Check if authenticated for a registry
|
|
114
|
+
*/
|
|
115
|
+
export async function isAuthenticated(registryUrl) {
|
|
116
|
+
const token = await getToken(registryUrl);
|
|
117
|
+
return token !== null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get username for a registry
|
|
121
|
+
*/
|
|
122
|
+
export async function getUsername(registryUrl) {
|
|
123
|
+
const auth = await loadAuthFile();
|
|
124
|
+
const normalizedUrl = normalizeRegistryUrl(registryUrl);
|
|
125
|
+
return auth.tokens[normalizedUrl]?.username ?? null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Normalize registry URL (remove trailing slash, ensure https)
|
|
129
|
+
*/
|
|
130
|
+
function normalizeRegistryUrl(url) {
|
|
131
|
+
let normalized = url.trim();
|
|
132
|
+
// Add https if no protocol
|
|
133
|
+
if (!normalized.startsWith('http://') && !normalized.startsWith('https://')) {
|
|
134
|
+
normalized = `https://${normalized}`;
|
|
135
|
+
}
|
|
136
|
+
// Remove trailing slash
|
|
137
|
+
if (normalized.endsWith('/')) {
|
|
138
|
+
normalized = normalized.slice(0, -1);
|
|
139
|
+
}
|
|
140
|
+
return normalized;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=auth.js.map
|