| 449 | // Helper function to check if a rule matches the skill |
| 450 | // Normalizes both inputs by stripping leading slashes for consistent matching |
| 451 | const ruleMatches = (ruleContent: string): boolean => { |
| 452 | // Normalize rule content by stripping leading slash |
| 453 | const normalizedRule = ruleContent.startsWith('/') |
| 454 | ? ruleContent.substring(1) |
| 455 | : ruleContent |
| 456 | |
| 457 | // Check exact match (using normalized commandName) |
| 458 | if (normalizedRule === commandName) { |
| 459 | return true |
| 460 | } |
| 461 | // Check prefix match (e.g., "review:*" matches "review-pr 123") |
| 462 | if (normalizedRule.endsWith(':*')) { |
| 463 | const prefix = normalizedRule.slice(0, -2) // Remove ':*' |
| 464 | return commandName.startsWith(prefix) |
| 465 | } |
| 466 | return false |
| 467 | } |
| 468 | |
| 469 | // Check for deny rules |
| 470 | const denyRules = getRuleByContentsForTool( |