@codemcp/agentskills-core 1.3.2 → 1.4.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/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { Skill, SkillMetadata, ParseResult, ParseSuccess, ParseFailure, ParseError, ParseErrorCode, ValidationResult, ValidationError, ValidationWarning, ValidationErrorCode, ValidationWarningCode, LoadResult, RegistryState, InstallResult, InstallSuccess, InstallFailure, InstallAllResult, InstallError, InstallErrorCode, SkillManifest, SkillLockFile, SkillLockEntry, PackageConfig, McpClientType, McpConfig, McpServerConfig, McpServerDependency, McpParameterSpec, McpDependencyCheckResult, McpDependencyInfo, ParameterValues } from "./types.js";
1
+ export type { Skill, SkillMetadata, ParseResult, ParseSuccess, ParseFailure, ParseError, ParseErrorCode, ValidationResult, ValidationError, ValidationWarning, LoadResult, RegistryState, InstallResult, InstallSuccess, InstallFailure, InstallAllResult, InstallError, InstallErrorCode, SkillManifest, SkillLockFile, SkillLockEntry, PackageConfig, McpClientType, McpConfig, McpServerConfig, McpServerDependency, McpParameterSpec, McpDependencyCheckResult, McpDependencyInfo, ParameterValues } from "./types.js";
2
2
  export { parseSkill, parseSkillContent } from "./parser.js";
3
3
  export { validateSkill } from "./validator.js";
4
4
  export { SkillRegistry } from "./registry.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,KAAK,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,175 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft-07/schema#",
3
+ "$id": "https://mrsimpson.github.io/agentskills-mcp/skill-frontmatter-schema.json",
4
+ "title": "Agent Skill Frontmatter",
5
+ "description": "YAML frontmatter schema for Agent Skills (SKILL.md files). See https://mrsimpson.github.io/agentskills-mcp/reference/skill-format for full documentation.",
6
+ "type": "object",
7
+ "required": ["name", "description"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "name": {
11
+ "type": "string",
12
+ "description": "Unique skill identifier. Lowercase letters, numbers, and hyphens only. No leading/trailing/consecutive hyphens.",
13
+ "minLength": 1,
14
+ "maxLength": 64,
15
+ "allOf": [
16
+ { "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$" },
17
+ { "not": { "pattern": "--" } }
18
+ ]
19
+ },
20
+ "description": {
21
+ "type": "string",
22
+ "description": "Short summary of the skill shown in tool descriptions.",
23
+ "minLength": 1,
24
+ "maxLength": 1024
25
+ },
26
+ "license": {
27
+ "type": "string",
28
+ "description": "SPDX license identifier (e.g. MIT, Apache-2.0). Recommended for published skills."
29
+ },
30
+ "compatibility": {
31
+ "type": "string",
32
+ "description": "Agent compatibility string.",
33
+ "maxLength": 500
34
+ },
35
+ "metadata": {
36
+ "type": "object",
37
+ "description": "Arbitrary key-value metadata.",
38
+ "additionalProperties": true
39
+ },
40
+ "allowedTools": {
41
+ "type": "array",
42
+ "description": "Tools this skill is permitted to use.",
43
+ "items": {
44
+ "type": "string"
45
+ }
46
+ },
47
+ "disableModelInvocation": {
48
+ "type": "boolean",
49
+ "description": "If true, the skill is excluded from the use_skill tool enum and cannot be invoked via MCP."
50
+ },
51
+ "userInvocable": {
52
+ "type": "boolean",
53
+ "description": "If true, the skill is designed for direct user invocation (e.g. via /skill-name)."
54
+ },
55
+ "argumentHint": {
56
+ "type": "string",
57
+ "description": "Hint shown to users about expected arguments, e.g. \"<pr-url>\" or \"<target> [options]\"."
58
+ },
59
+ "context": {
60
+ "type": "string",
61
+ "description": "Execution context hint for the agent."
62
+ },
63
+ "agent": {
64
+ "type": "string",
65
+ "description": "Target agent identifier this skill is optimized for."
66
+ },
67
+ "model": {
68
+ "type": "string",
69
+ "description": "Preferred model for executing this skill."
70
+ },
71
+ "hooks": {
72
+ "type": "object",
73
+ "description": "Lifecycle hook definitions keyed by hook name.",
74
+ "additionalProperties": {
75
+ "type": "string"
76
+ }
77
+ },
78
+ "requiresMcpServers": {
79
+ "type": "array",
80
+ "description": "MCP servers that must be configured for this skill to work. Used by 'agentskills install --agent' for validation and auto-configuration.",
81
+ "items": {
82
+ "$ref": "#/$defs/McpServerDependency"
83
+ }
84
+ }
85
+ },
86
+ "$defs": {
87
+ "McpServerDependency": {
88
+ "type": "object",
89
+ "description": "An MCP server that this skill depends on.",
90
+ "required": ["name", "description", "command"],
91
+ "additionalProperties": false,
92
+ "properties": {
93
+ "name": {
94
+ "type": "string",
95
+ "description": "Server identifier. Lowercase letters, numbers, and hyphens. Must start and end with alphanumeric.",
96
+ "allOf": [
97
+ { "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$" },
98
+ { "not": { "pattern": "--" } }
99
+ ]
100
+ },
101
+ "package": {
102
+ "type": "string",
103
+ "description": "npm package name used for auto-installation (e.g. \"@modelcontextprotocol/server-filesystem\")."
104
+ },
105
+ "description": {
106
+ "type": "string",
107
+ "description": "Why this MCP server is needed by the skill."
108
+ },
109
+ "command": {
110
+ "type": "string",
111
+ "description": "Executable to run (e.g. \"npx\", \"node\", \"/usr/local/bin/my-server\")."
112
+ },
113
+ "args": {
114
+ "type": "array",
115
+ "description": "Arguments passed to the command. May contain {{PARAM_NAME}} placeholders resolved at install time.",
116
+ "items": {
117
+ "type": "string"
118
+ }
119
+ },
120
+ "env": {
121
+ "type": "object",
122
+ "description": "Environment variables to set when running the server.",
123
+ "additionalProperties": {
124
+ "type": "string"
125
+ }
126
+ },
127
+ "cwd": {
128
+ "type": "string",
129
+ "description": "Working directory for the server process."
130
+ },
131
+ "parameters": {
132
+ "type": "object",
133
+ "description": "Parameter definitions for {{PARAM}} placeholders used in args or env.",
134
+ "propertyNames": {
135
+ "allOf": [
136
+ { "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$" },
137
+ { "not": { "pattern": "--" } }
138
+ ]
139
+ },
140
+ "additionalProperties": {
141
+ "$ref": "#/$defs/McpParameterSpec"
142
+ }
143
+ }
144
+ }
145
+ },
146
+ "McpParameterSpec": {
147
+ "type": "object",
148
+ "description": "Definition of a parameter placeholder used in an MCP server dependency.",
149
+ "required": ["description", "required"],
150
+ "additionalProperties": false,
151
+ "properties": {
152
+ "description": {
153
+ "type": "string",
154
+ "description": "What this parameter configures."
155
+ },
156
+ "required": {
157
+ "type": "boolean",
158
+ "description": "Whether the user must supply this parameter."
159
+ },
160
+ "sensitive": {
161
+ "type": "boolean",
162
+ "description": "If true, treat as a secret or credential (mask in output, do not log)."
163
+ },
164
+ "default": {
165
+ "type": "string",
166
+ "description": "Default value used when the parameter is not supplied."
167
+ },
168
+ "example": {
169
+ "type": "string",
170
+ "description": "Example value shown to guide users."
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
package/dist/types.d.ts CHANGED
@@ -60,29 +60,17 @@ export interface ParseFailure {
60
60
  * Result of parsing a skill (discriminated union)
61
61
  */
62
62
  export type ParseResult = ParseSuccess | ParseFailure;
63
- /**
64
- * Error codes for validation failures
65
- */
66
- export type ValidationErrorCode = "MISSING_FIELD" | "INVALID_NAME_LENGTH" | "INVALID_NAME_FORMAT" | "INVALID_DESCRIPTION_LENGTH" | "INVALID_COMPATIBILITY_LENGTH" | "INVALID_FIELD_TYPE";
67
- /**
68
- * Warning codes for non-blocking validation issues
69
- */
70
- export type ValidationWarningCode = "MISSING_RECOMMENDED_FIELD" | "SHORT_DESCRIPTION" | "LONG_CONTENT";
71
63
  /**
72
64
  * Validation error information
73
65
  */
74
66
  export interface ValidationError {
75
- code: ValidationErrorCode;
76
67
  message: string;
77
- field?: string;
78
68
  }
79
69
  /**
80
- * Validation warning information
70
+ * Validation warning information (reserved for future use)
81
71
  */
82
72
  export interface ValidationWarning {
83
- code: ValidationWarningCode;
84
73
  message: string;
85
- field?: string;
86
74
  }
87
75
  /**
88
76
  * Result of validating a skill
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,3 @@
1
- /**
2
- * Skill Validator
3
- *
4
- * Validates Agent Skills format against specification.
5
- * This is a stub implementation - tests define the expected behavior.
6
- *
7
- * Implementation to be completed following TDD approach.
8
- */
9
1
  import type { Skill, ValidationResult } from "./types.js";
10
- /**
11
- * Validate a skill against Agent Skills specification
12
- *
13
- * Validates:
14
- * - Required fields: name (1-64 chars, lowercase-hyphens), description (1-1024 chars)
15
- * - Optional fields: license, compatibility (1-500 chars), metadata, allowedTools
16
- * - Name format: lowercase letters, numbers, hyphens only, no leading/trailing/consecutive hyphens
17
- *
18
- * Returns ValidationResult with:
19
- * - valid: boolean indicating if skill passes validation
20
- * - errors: array of blocking validation errors
21
- * - warnings: array of non-blocking issues
22
- *
23
- * @param skill - The skill to validate
24
- * @returns ValidationResult with validation status, errors, and warnings
25
- */
26
2
  export declare function validateSkill(skill: Skill): ValidationResult;
27
3
  //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,gBAAgB,CAqY5D"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAW1D,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,gBAAgB,CAW5D"}
package/dist/validator.js CHANGED
@@ -1,359 +1,20 @@
1
- /**
2
- * Skill Validator
3
- *
4
- * Validates Agent Skills format against specification.
5
- * This is a stub implementation - tests define the expected behavior.
6
- *
7
- * Implementation to be completed following TDD approach.
8
- */
9
- /**
10
- * Validate a skill against Agent Skills specification
11
- *
12
- * Validates:
13
- * - Required fields: name (1-64 chars, lowercase-hyphens), description (1-1024 chars)
14
- * - Optional fields: license, compatibility (1-500 chars), metadata, allowedTools
15
- * - Name format: lowercase letters, numbers, hyphens only, no leading/trailing/consecutive hyphens
16
- *
17
- * Returns ValidationResult with:
18
- * - valid: boolean indicating if skill passes validation
19
- * - errors: array of blocking validation errors
20
- * - warnings: array of non-blocking issues
21
- *
22
- * @param skill - The skill to validate
23
- * @returns ValidationResult with validation status, errors, and warnings
24
- */
1
+ import Ajv from "ajv";
2
+ import schema from "./skill-frontmatter.schema.json" with { type: "json" };
3
+ // AJV v8 lacks an exports field, so moduleResolution:NodeNext sees the full CJS
4
+ // module namespace rather than the default export — cast once at construction.
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ const ajv = new Ajv({ validateSchema: false });
7
+ const validateFrontmatter = ajv.compile(schema);
25
8
  export function validateSkill(skill) {
26
- const errors = [];
27
- const warnings = [];
28
- // Extract metadata for validation
29
- const { name, description, compatibility, metadata, allowedTools, license } = skill.metadata;
30
- // Validate name - required field
31
- if (name === undefined || name === null) {
32
- errors.push({
33
- code: "MISSING_FIELD",
34
- field: "name",
35
- message: "Field 'name' is required"
36
- });
37
- }
38
- else {
39
- const trimmedName = name.trim();
40
- // Check name length (after trimming)
41
- if (trimmedName.length < 1 || trimmedName.length > 64) {
42
- errors.push({
43
- code: "INVALID_NAME_LENGTH",
44
- field: "name",
45
- message: "Name must be between 1 and 64 characters"
46
- });
47
- }
48
- // Check name format if not empty
49
- if (trimmedName.length > 0) {
50
- // Check for leading hyphen
51
- if (trimmedName.startsWith("-")) {
52
- errors.push({
53
- code: "INVALID_NAME_FORMAT",
54
- field: "name",
55
- message: "Name must not start with a leading hyphen"
56
- });
57
- }
58
- // Check for trailing hyphen
59
- if (trimmedName.endsWith("-")) {
60
- errors.push({
61
- code: "INVALID_NAME_FORMAT",
62
- field: "name",
63
- message: "Name must not end with a trailing hyphen"
64
- });
65
- }
66
- // Check for consecutive hyphens
67
- if (trimmedName.includes("--")) {
68
- errors.push({
69
- code: "INVALID_NAME_FORMAT",
70
- field: "name",
71
- message: "Name must not contain consecutive hyphens"
72
- });
73
- }
74
- // Check for valid characters (lowercase letters, numbers, hyphens only)
75
- const validNamePattern = /^[a-z0-9-]+$/;
76
- if (!validNamePattern.test(trimmedName)) {
77
- errors.push({
78
- code: "INVALID_NAME_FORMAT",
79
- field: "name",
80
- message: "Name must contain only lowercase letters, numbers, and hyphens"
81
- });
82
- }
83
- }
84
- }
85
- // Validate description - required field
86
- if (description === undefined || description === null) {
87
- errors.push({
88
- code: "MISSING_FIELD",
89
- field: "description",
90
- message: "Field 'description' is required"
91
- });
92
- }
93
- else {
94
- const trimmedDescription = description.trim();
95
- // Check description length (after trimming)
96
- if (trimmedDescription.length < 1 || trimmedDescription.length > 1024) {
97
- errors.push({
98
- code: "INVALID_DESCRIPTION_LENGTH",
99
- field: "description",
100
- message: "Description must be between 1 and 1024 characters"
101
- });
102
- }
103
- // Warning: short description
104
- if (trimmedDescription.length > 0 && trimmedDescription.length < 50) {
105
- warnings.push({
106
- code: "SHORT_DESCRIPTION",
107
- field: "description",
108
- message: "Description should be at least 50 characters for clarity"
109
- });
110
- }
111
- }
112
- // Validate compatibility - optional field
113
- if (compatibility !== undefined) {
114
- if (compatibility.length > 500) {
115
- errors.push({
116
- code: "INVALID_COMPATIBILITY_LENGTH",
117
- field: "compatibility",
118
- message: "Compatibility must not exceed 500 characters"
119
- });
120
- }
121
- }
122
- // Validate metadata - optional field, must be object if present
123
- if (metadata !== undefined) {
124
- if (metadata === null ||
125
- Array.isArray(metadata) ||
126
- typeof metadata !== "object") {
127
- errors.push({
128
- code: "INVALID_FIELD_TYPE",
129
- field: "metadata",
130
- message: "Metadata must be an object"
131
- });
132
- }
133
- }
134
- // Validate allowedTools - optional field, must be array if present
135
- if (allowedTools !== undefined) {
136
- if (allowedTools === null || !Array.isArray(allowedTools)) {
137
- errors.push({
138
- code: "INVALID_FIELD_TYPE",
139
- field: "allowedTools",
140
- message: "AllowedTools must be an array"
141
- });
142
- }
143
- }
144
- // Warning: missing license (recommended field)
145
- if (license === undefined) {
146
- warnings.push({
147
- code: "MISSING_RECOMMENDED_FIELD",
148
- field: "license",
149
- message: "License field is recommended for skills"
150
- });
151
- }
152
- // Warning: long body content (> 20000 chars ≈ 5000 tokens)
153
- if (skill.body && skill.body.length > 20000) {
154
- warnings.push({
155
- code: "LONG_CONTENT",
156
- message: "Body content exceeds 5000 tokens estimate, which may impact performance"
157
- });
158
- }
159
- // Validate requiresMcpServers - optional field
160
- if (skill.metadata.requiresMcpServers !== undefined) {
161
- const mcpServers = skill.metadata.requiresMcpServers;
162
- // Must be an array
163
- if (!Array.isArray(mcpServers)) {
164
- errors.push({
165
- code: "INVALID_FIELD_TYPE",
166
- field: "requiresMcpServers",
167
- message: "RequiresMcpServers must be an array"
168
- });
169
- }
170
- else {
171
- // Validate each server in the array
172
- mcpServers.forEach((server, index) => {
173
- const serverPrefix = `requiresMcpServers[${index}]`;
174
- // Check if server is an object
175
- if (!server || typeof server !== "object" || Array.isArray(server)) {
176
- errors.push({
177
- code: "INVALID_FIELD_TYPE",
178
- field: serverPrefix,
179
- message: `Server at index ${index} must be an object`
180
- });
181
- return;
182
- }
183
- // Validate required fields: name, command, description
184
- if (!server.name) {
185
- errors.push({
186
- code: "MISSING_FIELD",
187
- field: `${serverPrefix}.name`,
188
- message: "Server name is required"
189
- });
190
- }
191
- else if (typeof server.name === "string") {
192
- // Validate server name format (lowercase-hyphens, no leading/trailing/consecutive hyphens)
193
- const hasConsecutiveHyphens = server.name.includes("--");
194
- const serverNamePattern = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
195
- if (hasConsecutiveHyphens || !serverNamePattern.test(server.name)) {
196
- errors.push({
197
- code: "INVALID_NAME_FORMAT",
198
- field: `${serverPrefix}.name`,
199
- message: "Server name must contain only lowercase letters, numbers, and hyphens; must start and end with alphanumeric; no consecutive hyphens"
200
- });
201
- }
202
- }
203
- if (!server.command) {
204
- errors.push({
205
- code: "MISSING_FIELD",
206
- field: `${serverPrefix}.command`,
207
- message: "Server command is required"
208
- });
209
- }
210
- if (!server.description) {
211
- errors.push({
212
- code: "MISSING_FIELD",
213
- field: `${serverPrefix}.description`,
214
- message: "Server description is required"
215
- });
216
- }
217
- // Validate optional fields
218
- if (server.args !== undefined) {
219
- if (!Array.isArray(server.args)) {
220
- errors.push({
221
- code: "INVALID_FIELD_TYPE",
222
- field: `${serverPrefix}.args`,
223
- message: "Server args must be an array"
224
- });
225
- }
226
- }
227
- if (server.env !== undefined) {
228
- if (!server.env ||
229
- typeof server.env !== "object" ||
230
- Array.isArray(server.env)) {
231
- errors.push({
232
- code: "INVALID_FIELD_TYPE",
233
- field: `${serverPrefix}.env`,
234
- message: "Server env must be an object"
235
- });
236
- }
237
- }
238
- if (server.parameters !== undefined) {
239
- if (!server.parameters ||
240
- typeof server.parameters !== "object" ||
241
- Array.isArray(server.parameters)) {
242
- errors.push({
243
- code: "INVALID_FIELD_TYPE",
244
- field: `${serverPrefix}.parameters`,
245
- message: "Server parameters must be an object"
246
- });
247
- }
248
- else {
249
- // Validate each parameter
250
- Object.entries(server.parameters).forEach(([paramName, paramSpec]) => {
251
- const paramPrefix = `${serverPrefix}.parameters.${paramName}`;
252
- // Validate parameter name format (lowercase-hyphens, no consecutive hyphens)
253
- const hasConsecutiveHyphens = paramName.includes("--");
254
- const paramNamePattern = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
255
- if (hasConsecutiveHyphens ||
256
- !paramNamePattern.test(paramName)) {
257
- errors.push({
258
- code: "INVALID_NAME_FORMAT",
259
- field: paramPrefix,
260
- message: "Parameter name must contain only lowercase letters, numbers, and hyphens; must start and end with alphanumeric; no consecutive hyphens"
261
- });
262
- }
263
- // Validate parameter spec
264
- if (!paramSpec || typeof paramSpec !== "object") {
265
- errors.push({
266
- code: "INVALID_FIELD_TYPE",
267
- field: paramPrefix,
268
- message: "Parameter spec must be an object"
269
- });
270
- return;
271
- }
272
- // Required fields: description, required
273
- if (paramSpec.description === undefined) {
274
- errors.push({
275
- code: "MISSING_FIELD",
276
- field: `${paramPrefix}.description`,
277
- message: "Parameter description is required"
278
- });
279
- }
280
- if (paramSpec.required === undefined) {
281
- errors.push({
282
- code: "MISSING_FIELD",
283
- field: `${paramPrefix}.required`,
284
- message: "Parameter required field is required"
285
- });
286
- }
287
- // Validate optional fields
288
- if (paramSpec.default !== undefined &&
289
- typeof paramSpec.default !== "string") {
290
- errors.push({
291
- code: "INVALID_FIELD_TYPE",
292
- field: `${paramPrefix}.default`,
293
- message: "Parameter default must be a string"
294
- });
295
- }
296
- if (paramSpec.example !== undefined &&
297
- typeof paramSpec.example !== "string") {
298
- errors.push({
299
- code: "INVALID_FIELD_TYPE",
300
- field: `${paramPrefix}.example`,
301
- message: "Parameter example must be a string"
302
- });
303
- }
304
- if (paramSpec.sensitive !== undefined &&
305
- typeof paramSpec.sensitive !== "boolean") {
306
- errors.push({
307
- code: "INVALID_FIELD_TYPE",
308
- field: `${paramPrefix}.sensitive`,
309
- message: "Parameter sensitive must be a boolean"
310
- });
311
- }
312
- // Check for additional properties
313
- const allowedKeys = [
314
- "description",
315
- "required",
316
- "default",
317
- "example",
318
- "sensitive"
319
- ];
320
- const extraKeys = Object.keys(paramSpec).filter((key) => !allowedKeys.includes(key));
321
- if (extraKeys.length > 0) {
322
- errors.push({
323
- code: "INVALID_FIELD_TYPE",
324
- field: paramPrefix,
325
- message: `Parameter has unexpected fields: ${extraKeys.join(", ")}`
326
- });
327
- }
328
- });
329
- }
330
- }
331
- // Check for additional properties on server
332
- const allowedServerKeys = [
333
- "name",
334
- "package",
335
- "description",
336
- "command",
337
- "args",
338
- "env",
339
- "cwd",
340
- "parameters"
341
- ];
342
- const extraServerKeys = Object.keys(server).filter((key) => !allowedServerKeys.includes(key));
343
- if (extraServerKeys.length > 0) {
344
- errors.push({
345
- code: "INVALID_FIELD_TYPE",
346
- field: serverPrefix,
347
- message: `Server has unexpected fields: ${extraServerKeys.join(", ")}`
348
- });
349
- }
350
- });
351
- }
352
- }
9
+ const valid = validateFrontmatter(skill.metadata);
353
10
  return {
354
- valid: errors.length === 0,
355
- errors,
356
- warnings
11
+ valid,
12
+ errors: valid
13
+ ? []
14
+ : (validateFrontmatter.errors ?? []).map((e) => ({
15
+ message: e.message ?? "Validation error"
16
+ })),
17
+ warnings: []
357
18
  };
358
19
  }
359
20
  //# sourceMappingURL=validator.js.map