* Parse workflow metadata from a standalone .md workflow file * @param {string} filePath - Path to the workflow .md file * @returns {object|null} Workflow metadata or null on error
(filePath)
| 260 | * @returns {object|null} Workflow metadata or null on error |
| 261 | */ |
| 262 | function parseWorkflowMetadata(filePath) { |
| 263 | return safeFileOperation( |
| 264 | () => { |
| 265 | if (!fs.existsSync(filePath)) { |
| 266 | return null; |
| 267 | } |
| 268 | |
| 269 | const frontmatter = parseFrontmatter(filePath); |
| 270 | |
| 271 | // Validate required fields |
| 272 | if (!frontmatter?.name || !frontmatter?.description) { |
| 273 | console.warn( |
| 274 | `Invalid workflow at ${filePath}: missing name or description in frontmatter` |
| 275 | ); |
| 276 | return null; |
| 277 | } |
| 278 | |
| 279 | // Extract triggers from the 'on' field (top-level keys) |
| 280 | const onField = frontmatter.on; |
| 281 | const triggers = []; |
| 282 | if (onField && typeof onField === "object") { |
| 283 | triggers.push(...Object.keys(onField)); |
| 284 | } else if (typeof onField === "string") { |
| 285 | triggers.push(onField); |
| 286 | } |
| 287 | |
| 288 | return { |
| 289 | name: frontmatter.name, |
| 290 | description: frontmatter.description, |
| 291 | triggers, |
| 292 | path: filePath, |
| 293 | }; |
| 294 | }, |
| 295 | filePath, |
| 296 | null |
| 297 | ); |
| 298 | } |
| 299 | |
| 300 | /** |
| 301 | * Parse a generic YAML file (used for tools.yml and other config files) |
no test coverage detected