@forge/manifest 13.2.0-next.4 → 13.2.0-next.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @forge/manifest
2
2
 
3
+ ## 13.2.0-next.5
4
+
5
+ ### Minor Changes
6
+
7
+ - 2b30ef8: Add SKILL.md file validation
8
+
3
9
  ## 13.2.0-next.4
4
10
 
5
11
  ### Patch Changes
@@ -157,6 +157,27 @@ export declare const errors: {
157
157
  skillSubdirNotFound: (module: string, subdirectory: string) => string;
158
158
  skillSubdirMissingSkillMD: (module: string, subdirectory: string) => string;
159
159
  skillPathNotUnique: (module: string, path: string) => string;
160
+ skillFileMissingFrontmatterDelimiters: (module: string) => string;
161
+ skillFileFrontmatterYamlInvalid: (module: string) => string;
162
+ skillFileNameRequired: (module: string) => string;
163
+ skillFileNameLength: (module: string) => string;
164
+ skillFileNameFormat: (module: string) => string;
165
+ skillFileNameMustMatchDirectory: (module: string, directoryName: string) => string;
166
+ skillFileDescriptionRequired: (module: string) => string;
167
+ skillFileDescriptionLength: (module: string) => string;
168
+ skillFileDescriptionTooShort: (module: string) => string;
169
+ skillFileCompatibilityMustBeString: (module: string) => string;
170
+ skillFileCompatibilityLength: (module: string) => string;
171
+ skillFileMetadataInvalid: (module: string) => string;
172
+ skillFileLicenseMustBeString: (module: string) => string;
173
+ skillFileAllowedToolsInvalid: (module: string) => string;
174
+ skillFileAllowedToolsMismatch: (module: string) => string;
175
+ skillFileReferencedFileMissing: (module: string, filePath: string) => string;
176
+ skillFileRequiredDirectoryMissing: (module: string, directoryPath: string) => string;
177
+ skillFileUnknownFrontmatterField: (module: string, field: string) => string;
178
+ skillFileBodyEmpty: (module: string) => string;
179
+ skillFileBodyTooLong: (module: string) => string;
180
+ skillFileToolsNotMentioned: (module: string) => string;
160
181
  incorrectMcp: (module: string, toolKey: string) => string;
161
182
  };
162
183
  action: {
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/text/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/text/errors.ts"],"names":[],"mappings":"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"}
@@ -171,6 +171,27 @@ exports.errors = {
171
171
  skillSubdirNotFound: (module, subdirectory) => `Directory '${subdirectory}' specified in skill ${module} does not exist from the manifest root.`,
172
172
  skillSubdirMissingSkillMD: (module, subdirectory) => `Directory '${subdirectory}' specified in skill ${module} does not contain a SKILL.md file.`,
173
173
  skillPathNotUnique: (module, path) => `Skill ${module} has a duplicate source.dir '${path}'. rovo:skill source.dir values must be unique.`,
174
+ skillFileMissingFrontmatterDelimiters: (module) => `Skill ${module} must define frontmatter with opening and closing '---' delimiters. Example:\n---\nname: my-skill\ndescription: ...\n---`,
175
+ skillFileFrontmatterYamlInvalid: (module) => `Skill ${module} has invalid YAML in SKILL.md frontmatter. Tip: frontmatter must be a YAML mapping (key: value). Check indentation and quoting.`,
176
+ skillFileNameRequired: (module) => `Skill ${module} frontmatter field 'name' is required.`,
177
+ skillFileNameLength: (module) => `Skill ${module} frontmatter field 'name' must be between 1 and 64 characters.`,
178
+ skillFileNameFormat: (module) => `Skill ${module} frontmatter field 'name' must be lowercase alphanumeric with hyphens and no leading, trailing, or consecutive hyphens.`,
179
+ skillFileNameMustMatchDirectory: (module, directoryName) => `Skill ${module} frontmatter field 'name' must match the parent directory name '${directoryName}'.`,
180
+ skillFileDescriptionRequired: (module) => `Skill ${module} frontmatter field 'description' is required.`,
181
+ skillFileDescriptionLength: (module) => `Skill ${module} frontmatter field 'description' must be between 1 and 1024 characters.`,
182
+ skillFileDescriptionTooShort: (module) => `Skill ${module} description should be at least 50 characters. Suggestion: Describe what the skill does, when to use it, and any prerequisites or limits.`,
183
+ skillFileCompatibilityMustBeString: (module) => `Skill ${module} frontmatter field 'compatibility' must be a string.`,
184
+ skillFileCompatibilityLength: (module) => `Skill ${module} frontmatter field 'compatibility' must be between 1 and 500 characters.`,
185
+ skillFileMetadataInvalid: (module) => `Skill ${module} frontmatter field 'metadata' must be a key-value mapping with string values.`,
186
+ skillFileLicenseMustBeString: (module) => `Skill ${module} frontmatter field 'license' must be a string.`,
187
+ skillFileAllowedToolsInvalid: (module) => `Skill ${module} frontmatter field 'allowed-tools' must be a space-delimited string.`,
188
+ skillFileAllowedToolsMismatch: (module) => `Skill ${module} frontmatter field 'allowed-tools' does not match manifest dependencies.tools.`,
189
+ skillFileReferencedFileMissing: (module, filePath) => `Skill ${module} references file '${filePath}' but it does not exist.`,
190
+ skillFileRequiredDirectoryMissing: (module, directoryPath) => `Skill ${module} requires directory '${directoryPath}' but it does not exist.`,
191
+ skillFileUnknownFrontmatterField: (module, field) => `Skill ${module} has unknown frontmatter field '${field}'.`,
192
+ skillFileBodyEmpty: (module) => `Skill ${module} SKILL.md body is empty.`,
193
+ skillFileBodyTooLong: (module) => `Skill ${module} SKILL.md body exceeds 500 lines. Suggestion: Move some content to reference files.`,
194
+ skillFileToolsNotMentioned: (module) => `Skill ${module} SKILL.md should document how it uses each tool declared in dependencies.tools.`,
174
195
  incorrectMcp: (module, toolKey) => `${module} references undefined action module with key '${toolKey}'.`
175
196
  },
176
197
  action: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/validators/modules-validators/rovo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AASnD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,cAAc,MAAM,EACpB,oBAAoB,MAAM,EAAE,KAC3B,eAAe,EAYjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/validators/modules-validators/rovo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAUnD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,cAAc,MAAM,EACpB,oBAAoB,MAAM,EAAE,KAC3B,eAAe,EAajB,CAAC"}
@@ -8,6 +8,7 @@ const validate_rovo_mcp_actions_1 = require("./validate-rovo-mcp-actions");
8
8
  const validate_undefined_action_name_1 = require("./validate-undefined-action-name");
9
9
  const validate_agent_connector_remote_endpoints_1 = require("./validate-agent-connector-remote-endpoints");
10
10
  const validate_skill_path_1 = require("./validate-skill-path");
11
+ const validate_skill_file_1 = require("./validate-skill-file");
11
12
  const validateRovoModules = (modules, manifestDir, yamlContentByLine) => {
12
13
  const validationErrors = [];
13
14
  validationErrors.push(...(0, validate_rovo_agent_actions_1.validateRovoAgentActions)(modules, yamlContentByLine));
@@ -17,6 +18,7 @@ const validateRovoModules = (modules, manifestDir, yamlContentByLine) => {
17
18
  validationErrors.push(...(0, validate_undefined_action_name_1.validateUndefinedActionName)(modules, yamlContentByLine));
18
19
  validationErrors.push(...(0, validate_agent_connector_remote_endpoints_1.validateAgentConnectorRemoteEndpoints)(modules, yamlContentByLine));
19
20
  validationErrors.push(...(0, validate_skill_path_1.validateSkillPath)(modules, manifestDir, yamlContentByLine));
21
+ validationErrors.push(...(0, validate_skill_file_1.validateSkillFile)(modules, manifestDir, yamlContentByLine));
20
22
  return validationErrors;
21
23
  };
22
24
  exports.validateRovoModules = validateRovoModules;
@@ -0,0 +1,30 @@
1
+ import { AllModuleTypes, ValidationError } from '../../../types';
2
+ import { Modules } from '../../../schema/manifest';
3
+ export type SkillModule = NonNullable<Modules[AllModuleTypes.RovoSkill]>[number];
4
+ export type SkillContext = {
5
+ skill: SkillModule;
6
+ skillDirectory: string;
7
+ parentDirectoryName: string;
8
+ frontmatter: Record<string, unknown>;
9
+ body: string;
10
+ bodyLines: string[];
11
+ referencedBodyFiles: string[];
12
+ dependencyTools: string[];
13
+ unknownFrontmatterFields: string[];
14
+ metadata: unknown;
15
+ metadataEntries: [string, unknown][];
16
+ allowedTools: unknown;
17
+ };
18
+ export type SkillValidator = {
19
+ check: (context: SkillContext) => boolean;
20
+ errorMessageGenerator: (context: SkillContext) => string;
21
+ errorType: ValidationError['level'];
22
+ };
23
+ export declare const allowedFrontmatterFields: Set<string>;
24
+ export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
25
+ export declare const skillValidationRules: SkillValidator[];
26
+ export declare const buildUnknownFrontmatterFieldValidators: (context: SkillContext) => SkillValidator[];
27
+ export declare const buildMetadataValueValidators: (context: SkillContext) => SkillValidator[];
28
+ export declare const buildReferencedFileValidators: (context: SkillContext) => SkillValidator[];
29
+ export declare const createAlwaysFailValidator: (errorType: ValidationError["level"], errorMessageGenerator: () => string) => SkillValidator;
30
+ //# sourceMappingURL=skill-file-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-file-rules.d.ts","sourceRoot":"","sources":["../../../../src/validators/modules-validators/rovo/skill-file-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAKnD,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,qBAAqB,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,MAAM,CAAC;IACzD,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,aAOnC,CAAC;AAeH,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACH,CAAC;AAEvE,eAAO,MAAM,oBAAoB,EAAE,cAAc,EAkJhD,CAAC;AAGF,eAAO,MAAM,sCAAsC,GAAI,SAAS,YAAY,KAAG,cAAc,EAKxF,CAAC;AAGN,eAAO,MAAM,4BAA4B,GAAI,SAAS,YAAY,KAAG,cAAc,EAK9E,CAAC;AAEN,eAAO,MAAM,6BAA6B,GAAI,SAAS,YAAY,KAAG,cAAc,EAS/E,CAAC;AAEN,eAAO,MAAM,yBAAyB,GACpC,WAAW,eAAe,CAAC,OAAO,CAAC,EACnC,uBAAuB,MAAM,MAAM,KAClC,cAID,CAAC"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAlwaysFailValidator = exports.buildReferencedFileValidators = exports.buildMetadataValueValidators = exports.buildUnknownFrontmatterFieldValidators = exports.skillValidationRules = exports.isRecord = exports.allowedFrontmatterFields = void 0;
4
+ const text_1 = require("../../../text");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ exports.allowedFrontmatterFields = new Set([
8
+ 'name',
9
+ 'description',
10
+ 'compatibility',
11
+ 'metadata',
12
+ 'license',
13
+ 'allowed-tools'
14
+ ]);
15
+ const nameRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
16
+ const normalizeTools = (tools) => [...new Set(tools.map((tool) => tool.trim()).filter(Boolean))].sort();
17
+ const parseTools = (allowedTools) => allowedTools
18
+ .split(' ')
19
+ .map((tool) => tool.trim())
20
+ .filter(Boolean);
21
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
22
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
23
+ exports.isRecord = isRecord;
24
+ exports.skillValidationRules = [
25
+ {
26
+ errorType: 'error',
27
+ check: ({ frontmatter }) => frontmatter.name !== undefined,
28
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileNameRequired(key)
29
+ },
30
+ {
31
+ errorType: 'error',
32
+ check: ({ frontmatter }) => {
33
+ const name = frontmatter.name;
34
+ return name === undefined || (typeof name === 'string' && name.length >= 1 && name.length <= 64);
35
+ },
36
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileNameLength(key)
37
+ },
38
+ {
39
+ errorType: 'error',
40
+ check: ({ frontmatter }) => {
41
+ const name = frontmatter.name;
42
+ return name === undefined || typeof name !== 'string' || nameRegex.test(name);
43
+ },
44
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileNameFormat(key)
45
+ },
46
+ {
47
+ errorType: 'error',
48
+ check: ({ frontmatter, parentDirectoryName }) => {
49
+ const name = frontmatter.name;
50
+ return name === undefined || typeof name !== 'string' || name === parentDirectoryName;
51
+ },
52
+ errorMessageGenerator: ({ skill: { key }, parentDirectoryName }) => text_1.errors.modules.rovo.skillFileNameMustMatchDirectory(key, parentDirectoryName)
53
+ },
54
+ {
55
+ errorType: 'error',
56
+ check: ({ frontmatter }) => frontmatter.description !== undefined,
57
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileDescriptionRequired(key)
58
+ },
59
+ {
60
+ errorType: 'error',
61
+ check: ({ frontmatter }) => {
62
+ const description = frontmatter.description;
63
+ return (description === undefined ||
64
+ (typeof description === 'string' && description.length >= 1 && description.length <= 1024));
65
+ },
66
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileDescriptionLength(key)
67
+ },
68
+ {
69
+ errorType: 'warning',
70
+ check: ({ frontmatter }) => {
71
+ const description = frontmatter.description;
72
+ return description === undefined || typeof description !== 'string' || description.length >= 50;
73
+ },
74
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileDescriptionTooShort(key)
75
+ },
76
+ {
77
+ errorType: 'error',
78
+ check: ({ frontmatter }) => {
79
+ const compatibility = frontmatter.compatibility;
80
+ return compatibility === undefined || typeof compatibility === 'string';
81
+ },
82
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileCompatibilityMustBeString(key)
83
+ },
84
+ {
85
+ errorType: 'error',
86
+ check: ({ frontmatter }) => {
87
+ const compatibility = frontmatter.compatibility;
88
+ return (compatibility === undefined ||
89
+ typeof compatibility !== 'string' ||
90
+ (compatibility.length >= 1 && compatibility.length <= 500));
91
+ },
92
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileCompatibilityLength(key)
93
+ },
94
+ {
95
+ errorType: 'error',
96
+ check: ({ metadata }) => metadata === undefined || (0, exports.isRecord)(metadata),
97
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileMetadataInvalid(key)
98
+ },
99
+ {
100
+ errorType: 'error',
101
+ check: ({ allowedTools }) => {
102
+ return allowedTools === undefined || (typeof allowedTools === 'string' && /^\S+(?: \S+)*$/.test(allowedTools));
103
+ },
104
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileAllowedToolsInvalid(key)
105
+ },
106
+ {
107
+ errorType: 'error',
108
+ check: ({ allowedTools, dependencyTools }) => {
109
+ if (allowedTools === undefined || typeof allowedTools !== 'string' || !/^\S+(?: \S+)*$/.test(allowedTools)) {
110
+ return true;
111
+ }
112
+ const manifestTools = normalizeTools(dependencyTools);
113
+ const frontmatterTools = normalizeTools(parseTools(allowedTools));
114
+ const allowedToolsSet = new Set(frontmatterTools);
115
+ return manifestTools.every((tool) => allowedToolsSet.has(tool));
116
+ },
117
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileAllowedToolsMismatch(key)
118
+ },
119
+ {
120
+ errorType: 'error',
121
+ check: ({ frontmatter }) => {
122
+ const license = frontmatter.license;
123
+ return license === undefined || typeof license === 'string';
124
+ },
125
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileLicenseMustBeString(key)
126
+ },
127
+ {
128
+ errorType: 'warning',
129
+ check: ({ body }) => body.trim().length > 0,
130
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileBodyEmpty(key)
131
+ },
132
+ {
133
+ errorType: 'warning',
134
+ check: ({ body, bodyLines }) => body.trim().length === 0 || bodyLines.length <= 500,
135
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileBodyTooLong(key)
136
+ },
137
+ {
138
+ errorType: 'warning',
139
+ check: ({ body, dependencyTools }) => {
140
+ if (body.trim().length === 0) {
141
+ return true;
142
+ }
143
+ const tools = normalizeTools(dependencyTools);
144
+ return tools.every((tool) => new RegExp(`\\b${escapeRegExp(tool)}\\b`).test(body));
145
+ },
146
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileToolsNotMentioned(key)
147
+ }
148
+ ];
149
+ const buildUnknownFrontmatterFieldValidators = (context) => context.unknownFrontmatterFields.map((field) => ({
150
+ check: () => false,
151
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileUnknownFrontmatterField(key, field),
152
+ errorType: 'error'
153
+ }));
154
+ exports.buildUnknownFrontmatterFieldValidators = buildUnknownFrontmatterFieldValidators;
155
+ const buildMetadataValueValidators = (context) => context.metadataEntries.map((entry) => ({
156
+ check: () => typeof entry[1] === 'string',
157
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileMetadataInvalid(key),
158
+ errorType: 'error'
159
+ }));
160
+ exports.buildMetadataValueValidators = buildMetadataValueValidators;
161
+ const buildReferencedFileValidators = (context) => context.referencedBodyFiles.map((referencedBodyFile) => ({
162
+ check: ({ skillDirectory }) => {
163
+ const referencedFilePath = (0, path_1.resolve)(skillDirectory, referencedBodyFile);
164
+ return (0, fs_1.existsSync)(referencedFilePath) && (0, fs_1.statSync)(referencedFilePath).isFile();
165
+ },
166
+ errorMessageGenerator: ({ skill: { key } }) => text_1.errors.modules.rovo.skillFileReferencedFileMissing(key, referencedBodyFile),
167
+ errorType: 'warning'
168
+ }));
169
+ exports.buildReferencedFileValidators = buildReferencedFileValidators;
170
+ const createAlwaysFailValidator = (errorType, errorMessageGenerator) => ({
171
+ check: () => false,
172
+ errorMessageGenerator: () => errorMessageGenerator(),
173
+ errorType
174
+ });
175
+ exports.createAlwaysFailValidator = createAlwaysFailValidator;
@@ -0,0 +1,4 @@
1
+ import { ValidationError } from '../../../types';
2
+ import { Modules } from '../../../schema/manifest';
3
+ export declare const validateSkillFile: (allModules: Modules, manifestDir?: string, yamlContentByLine?: string[]) => ValidationError[];
4
+ //# sourceMappingURL=validate-skill-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-skill-file.d.ts","sourceRoot":"","sources":["../../../../src/validators/modules-validators/rovo/validate-skill-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AA4FnD,eAAO,MAAM,iBAAiB,GAC5B,YAAY,OAAO,EACnB,cAAc,MAAM,EACpB,oBAAoB,MAAM,EAAE,KAC3B,eAAe,EA4KjB,CAAC"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateSkillFile = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const types_1 = require("../../../types");
6
+ const text_1 = require("../../../text");
7
+ const utils_1 = require("../../../utils");
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ const yaml_1 = tslib_1.__importDefault(require("yaml"));
11
+ const skill_file_rules_1 = require("./skill-file-rules");
12
+ const referencedFileRegex = /(?:^|[^\w/.-])((?:scripts|references|assets)\/[A-Za-z0-9_./-]+)/g;
13
+ const trailingPunctuationRegex = /[.,:;!?)]$/;
14
+ const extractReferencedBodyFiles = (body) => {
15
+ const referencedFiles = new Set();
16
+ for (const match of body.matchAll(referencedFileRegex)) {
17
+ if (match[1]) {
18
+ referencedFiles.add(match[1].replace(trailingPunctuationRegex, ''));
19
+ }
20
+ }
21
+ return [...referencedFiles];
22
+ };
23
+ const toValidationError = (skillKey, message, level, yamlContentByLine) => ({
24
+ message,
25
+ reference: text_1.References.Modules,
26
+ level,
27
+ ...(0, utils_1.findPosition)(skillKey, yamlContentByLine)
28
+ });
29
+ const collectRuleErrors = (context, validators, yamlContentByLine) => validators
30
+ .filter((validator) => !validator.check(context))
31
+ .map((validator) => {
32
+ const { skill: { key } } = context;
33
+ return toValidationError(key, validator.errorMessageGenerator(context), validator.errorType, yamlContentByLine);
34
+ });
35
+ const resolveSkillFilePath = (skill, manifestDir) => {
36
+ const sourceDir = skill.source?.dir;
37
+ if (typeof sourceDir !== 'string' || sourceDir.trim() === '' || sourceDir.startsWith('..')) {
38
+ return undefined;
39
+ }
40
+ const skillDirectory = (0, path_1.resolve)(manifestDir ?? '', sourceDir);
41
+ const skillFilePath = (0, path_1.resolve)(skillDirectory, 'SKILL.md');
42
+ if (!(0, fs_1.existsSync)(skillDirectory) || !(0, fs_1.existsSync)(skillFilePath)) {
43
+ return undefined;
44
+ }
45
+ return { skillDirectory, skillFilePath };
46
+ };
47
+ const validateSkillFile = (allModules, manifestDir, yamlContentByLine) => {
48
+ const validationErrors = [];
49
+ const rovoSkills = allModules[types_1.AllModuleTypes.RovoSkill];
50
+ rovoSkills?.forEach((skill) => {
51
+ const skillPath = resolveSkillFilePath(skill, manifestDir);
52
+ if (!skillPath) {
53
+ return;
54
+ }
55
+ const { skillDirectory, skillFilePath } = skillPath;
56
+ const skillContent = (0, fs_1.readFileSync)(skillFilePath, 'utf8');
57
+ const normalizedSkillContent = skillContent.replace(/^\uFEFF/, '');
58
+ const lines = normalizedSkillContent.split(/\r?\n/);
59
+ if (lines[0] !== '---') {
60
+ const errorContext = {
61
+ skill,
62
+ skillDirectory,
63
+ parentDirectoryName: (0, path_1.basename)(skillDirectory),
64
+ frontmatter: {},
65
+ body: '',
66
+ bodyLines: [],
67
+ referencedBodyFiles: [],
68
+ dependencyTools: [],
69
+ unknownFrontmatterFields: [],
70
+ metadata: undefined,
71
+ metadataEntries: [],
72
+ allowedTools: undefined
73
+ };
74
+ validationErrors.push(...collectRuleErrors(errorContext, [
75
+ (0, skill_file_rules_1.createAlwaysFailValidator)('error', () => text_1.errors.modules.rovo.skillFileMissingFrontmatterDelimiters(skill.key))
76
+ ], yamlContentByLine));
77
+ return;
78
+ }
79
+ const frontmatterEndIndex = lines.findIndex((line, index) => index > 0 && line === '---');
80
+ if (frontmatterEndIndex === -1) {
81
+ const errorContext = {
82
+ skill,
83
+ skillDirectory,
84
+ parentDirectoryName: (0, path_1.basename)(skillDirectory),
85
+ frontmatter: {},
86
+ body: '',
87
+ bodyLines: [],
88
+ referencedBodyFiles: [],
89
+ dependencyTools: [],
90
+ unknownFrontmatterFields: [],
91
+ metadata: undefined,
92
+ metadataEntries: [],
93
+ allowedTools: undefined
94
+ };
95
+ validationErrors.push(...collectRuleErrors(errorContext, [
96
+ (0, skill_file_rules_1.createAlwaysFailValidator)('error', () => text_1.errors.modules.rovo.skillFileMissingFrontmatterDelimiters(skill.key))
97
+ ], yamlContentByLine));
98
+ return;
99
+ }
100
+ const frontmatterContent = lines.slice(1, frontmatterEndIndex).join('\n');
101
+ const body = lines.slice(frontmatterEndIndex + 1).join('\n');
102
+ const bodyLines = body.split(/\r?\n/);
103
+ const referencedBodyFiles = extractReferencedBodyFiles(body);
104
+ let parsed;
105
+ try {
106
+ parsed = yaml_1.default.parse(frontmatterContent);
107
+ }
108
+ catch {
109
+ const errorContext = {
110
+ skill,
111
+ skillDirectory,
112
+ parentDirectoryName: (0, path_1.basename)(skillDirectory),
113
+ frontmatter: {},
114
+ body,
115
+ bodyLines,
116
+ referencedBodyFiles,
117
+ dependencyTools: [],
118
+ unknownFrontmatterFields: [],
119
+ metadata: undefined,
120
+ metadataEntries: [],
121
+ allowedTools: undefined
122
+ };
123
+ validationErrors.push(...collectRuleErrors(errorContext, [(0, skill_file_rules_1.createAlwaysFailValidator)('error', () => text_1.errors.modules.rovo.skillFileFrontmatterYamlInvalid(skill.key))], yamlContentByLine));
124
+ return;
125
+ }
126
+ if (!(0, skill_file_rules_1.isRecord)(parsed)) {
127
+ const errorContext = {
128
+ skill,
129
+ skillDirectory,
130
+ parentDirectoryName: (0, path_1.basename)(skillDirectory),
131
+ frontmatter: {},
132
+ body,
133
+ bodyLines,
134
+ referencedBodyFiles,
135
+ dependencyTools: [],
136
+ unknownFrontmatterFields: [],
137
+ metadata: undefined,
138
+ metadataEntries: [],
139
+ allowedTools: undefined
140
+ };
141
+ validationErrors.push(...collectRuleErrors(errorContext, [(0, skill_file_rules_1.createAlwaysFailValidator)('error', () => text_1.errors.modules.rovo.skillFileFrontmatterYamlInvalid(skill.key))], yamlContentByLine));
142
+ return;
143
+ }
144
+ const declaredToolDependencies = skill.dependencies?.tools;
145
+ const dependencyTools = Array.isArray(declaredToolDependencies)
146
+ ? declaredToolDependencies.filter((tool) => typeof tool === 'string')
147
+ : [];
148
+ const context = {
149
+ skill,
150
+ skillDirectory,
151
+ parentDirectoryName: (0, path_1.basename)(skillDirectory),
152
+ frontmatter: parsed,
153
+ body,
154
+ bodyLines,
155
+ referencedBodyFiles,
156
+ dependencyTools,
157
+ unknownFrontmatterFields: Object.keys(parsed).filter((field) => !skill_file_rules_1.allowedFrontmatterFields.has(field)),
158
+ metadata: parsed.metadata,
159
+ metadataEntries: (0, skill_file_rules_1.isRecord)(parsed.metadata) ? Object.entries(parsed.metadata) : [],
160
+ allowedTools: parsed['allowed-tools']
161
+ };
162
+ const unknownFieldValidators = (0, skill_file_rules_1.buildUnknownFrontmatterFieldValidators)(context);
163
+ const metadataValueValidators = (0, skill_file_rules_1.buildMetadataValueValidators)(context);
164
+ const referencedFileValidators = (0, skill_file_rules_1.buildReferencedFileValidators)(context);
165
+ const validators = [
166
+ ...unknownFieldValidators,
167
+ ...skill_file_rules_1.skillValidationRules,
168
+ ...metadataValueValidators,
169
+ ...referencedFileValidators
170
+ ];
171
+ validationErrors.push(...collectRuleErrors(context, validators, yamlContentByLine));
172
+ });
173
+ return validationErrors;
174
+ };
175
+ exports.validateSkillFile = validateSkillFile;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/manifest",
3
- "version": "13.2.0-next.4",
3
+ "version": "13.2.0-next.5",
4
4
  "description": "Definitions and validations of the Forge manifest",
5
5
  "main": "out/index.js",
6
6
  "scripts": {