Extend the skill loader to parse <role:X> tags in skill files, load the referenced role definitions, and inject them into the skill content before returning to Claude.
Skills are loaded as plain text from SKILL.md files. See Omni/Agent/Skills.hs, specifically loadSkill and executeSkill functions.
When a skill contains <role:product> tags:
1. Parse: Find all unique <role:X> tags in the skill body
2. Load: Load each referenced role from Omni/Agent/Roles/X.md
3. Inject: Prepend role definitions to the skill body
4. Return: Pass the enriched content to Claude
Input skill (SKILL.md):
# Feature Development
<role:product>
Clarify requirements...
</role>
<role:engineer>
Implement...
</role>
Output (what Claude sees):
## Role Definitions
### Product
When thinking as Product, focus on:
- User value...
### Engineer
When thinking as Engineer, focus on:
- Correctness...
---
# Feature Development
<role:product>
Clarify requirements...
</role>
<role:engineer>
Implement...
</role>
-- New function to parse role tags
parseRoleTags :: Text -> [Text]
parseRoleTags body =
-- Find all <role:X> patterns, extract unique role names
-- e.g., "<role:product>" -> "product"
-- New function to load a role definition
loadRole :: Text -> IO (Either Text Text)
loadRole roleName = do
let path = "Omni/Agent/Roles/" <> Text.unpack (capitalize roleName) <> ".md"
-- Read file, parse frontmatter, return body
-- Modify loadSkill to inject roles
loadSkill :: Text -> Text -> IO (Either Text Skill)
loadSkill userName skillName' = do
-- ... existing code to load skill ...
let roleNames = parseRoleTags body
roleDefinitions <- traverse loadRole roleNames
let enrichedBody = formatRoleDefinitions roleDefinitions <> "\n---\n\n" <> body
-- ... return skill with enrichedBody ...
Roles are in Omni/Agent/Roles/:
Product.md (note: capitalized filenames per repo convention)Designer.mdEngineer.mdReviewer.md<role:> or <role> without name - ignore or warn1. Create a test skill with role tags
2. Verify roles are parsed correctly
3. Verify role definitions are loaded and injected
4. Verify skills without role tags still work
5. Verify missing role produces helpful error
6. Run bild --test Omni/Agent/Skills.hs
parseRoleTags extracts role names from <role:X> tagsloadRole loads role definition from Omni/Agent/Roles/X.mdloadSkill injects role definitions at top of skill body