MCPcopy Create free account
hub / github.com/github/awesome-copilot / parseHookMetadata

Function parseHookMetadata

eng/yaml-parser.mjs:185–255  ·  view source on GitHub ↗

* Parse hook metadata from a hook folder (similar to skills) * @param {string} hookPath - Path to the hook folder * @returns {object|null} Hook metadata or null on error

(hookPath)

Source from the content-addressed store, hash-verified

183 * @returns {object|null} Hook metadata or null on error
184 */
185function parseHookMetadata(hookPath) {
186 return safeFileOperation(
187 () => {
188 const readmeFile = path.join(hookPath, "README.md");
189 if (!fs.existsSync(readmeFile)) {
190 return null;
191 }
192
193 const frontmatter = parseFrontmatter(readmeFile);
194
195 // Validate required fields
196 if (!frontmatter?.name || !frontmatter?.description) {
197 console.warn(
198 `Invalid hook at ${hookPath}: missing name or description in frontmatter`
199 );
200 return null;
201 }
202
203 // Extract hook events from hooks.json if it exists
204 let hookEvents = [];
205 const hooksJsonPath = path.join(hookPath, "hooks.json");
206 if (fs.existsSync(hooksJsonPath)) {
207 try {
208 const hooksJsonContent = fs.readFileSync(hooksJsonPath, "utf8");
209 const hooksConfig = JSON.parse(hooksJsonContent);
210 // Extract all hook event names from the hooks object
211 if (hooksConfig.hooks && typeof hooksConfig.hooks === "object") {
212 hookEvents = Object.keys(hooksConfig.hooks);
213 }
214 } catch (error) {
215 console.warn(
216 `Failed to parse hooks.json at ${hookPath}: ${error.message}`
217 );
218 }
219 }
220
221 // List bundled assets (all files except README.md), recursing through subdirectories
222 const getAllFiles = (dirPath, arrayOfFiles = []) => {
223 const files = fs.readdirSync(dirPath);
224
225 files.forEach((file) => {
226 const filePath = path.join(dirPath, file);
227 if (fs.statSync(filePath).isDirectory()) {
228 arrayOfFiles = getAllFiles(filePath, arrayOfFiles);
229 } else {
230 const relativePath = path.relative(hookPath, filePath);
231 if (relativePath !== "README.md") {
232 // Normalize path separators to forward slashes for cross-platform consistency
233 arrayOfFiles.push(relativePath.replace(/\\/g, "/"));
234 }
235 }
236 });
237
238 return arrayOfFiles;
239 };
240
241 const assets = getAllFiles(hookPath).sort();
242

Callers 2

generateHooksDataFunction · 0.90
generateHooksSectionFunction · 0.90

Calls 3

parseFrontmatterFunction · 0.85
getAllFilesFunction · 0.85
safeFileOperationFunction · 0.70

Tested by

no test coverage detected