feat: fix skill transformation pipeline across all targets (#334)

This commit is contained in:
Trevin Chow
2026-03-21 19:45:20 -07:00
committed by GitHub
parent 0f6448d81c
commit 4087e1df82
33 changed files with 624 additions and 86 deletions

View File

@@ -29,14 +29,16 @@ export function transformContentForCodex(
const skillTargets = targets?.skillTargets ?? {}
const unknownSlashBehavior = options.unknownSlashBehavior ?? "prompt"
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]+)\)/gm
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
// For namespaced calls like "compound-engineering:research:repo-research-analyst",
// use only the final segment as the skill name.
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
const skillName = normalizeCodexName(finalSegment)
const trimmedArgs = args.trim()
return `${prefix}Use the $${skillName} skill to: ${trimmedArgs}`
return trimmedArgs
? `${prefix}Use the $${skillName} skill to: ${trimmedArgs}`
: `${prefix}Use the $${skillName} skill`
})
const slashCommandPattern = /(?<![:\w])\/([a-z][a-z0-9_:-]*?)(?=[\s,."')\]}`]|$)/gi

View File

@@ -104,3 +104,34 @@ export async function copyDir(sourceDir: string, targetDir: string): Promise<voi
}
}
}
/**
* Copy a skill directory, optionally transforming SKILL.md content.
* All other files are copied verbatim. Used by target writers to apply
* platform-specific content transforms to pass-through skills.
*/
export async function copySkillDir(
sourceDir: string,
targetDir: string,
transformSkillContent?: (content: string) => string,
): Promise<void> {
await ensureDir(targetDir)
const entries = await fs.readdir(sourceDir, { withFileTypes: true })
for (const entry of entries) {
const sourcePath = path.join(sourceDir, entry.name)
const targetPath = path.join(targetDir, entry.name)
if (entry.isDirectory()) {
await copySkillDir(sourcePath, targetPath, transformSkillContent)
} else if (entry.isFile()) {
if (entry.name === "SKILL.md" && transformSkillContent) {
const content = await readText(sourcePath)
await writeText(targetPath, transformSkillContent(content))
} else {
await ensureDir(path.dirname(targetPath))
await fs.copyFile(sourcePath, targetPath)
}
}
}
}