feat: fix skill transformation pipeline across all targets (#334)
This commit is contained in:
@@ -106,11 +106,15 @@ function convertCommandToSkill(
|
||||
export function transformContentForCopilot(body: string): string {
|
||||
let result = body
|
||||
|
||||
// 1. Transform Task agent calls
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||
// 1. Transform Task agent calls (supports namespaced names like compound-engineering:research:agent-name)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
|
||||
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||
const skillName = normalizeName(agentName)
|
||||
return `${prefix}Use the ${skillName} skill to: ${args.trim()}`
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const skillName = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim()
|
||||
return trimmedArgs
|
||||
? `${prefix}Use the ${skillName} skill to: ${trimmedArgs}`
|
||||
: `${prefix}Use the ${skillName} skill`
|
||||
})
|
||||
|
||||
// 2. Transform slash command references (replace colons with hyphens)
|
||||
|
||||
@@ -119,15 +119,19 @@ function mapAgentTools(agent: ClaudeAgent): string[] | undefined {
|
||||
* 2. Task agent calls: Task agent-name(args) → Task agent-name: args
|
||||
* 3. Agent references: @agent-name → the agent-name droid
|
||||
*/
|
||||
function transformContentForDroid(body: string): string {
|
||||
export function transformContentForDroid(body: string): string {
|
||||
let result = body
|
||||
|
||||
// 1. Transform Task agent calls
|
||||
// Match: Task repo-research-analyst(feature_description)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||
// Match: Task repo-research-analyst(args) or Task compound-engineering:research:repo-research-analyst(args)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
|
||||
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||
const name = normalizeName(agentName)
|
||||
return `${prefix}Task ${name}: ${args.trim()}`
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const name = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim()
|
||||
return trimmedArgs
|
||||
? `${prefix}Task ${name}: ${trimmedArgs}`
|
||||
: `${prefix}Task ${name}`
|
||||
})
|
||||
|
||||
// 2. Transform slash command references
|
||||
|
||||
@@ -86,11 +86,15 @@ function convertCommand(command: ClaudeCommand, usedNames: Set<string>): GeminiC
|
||||
export function transformContentForGemini(body: string): string {
|
||||
let result = body
|
||||
|
||||
// 1. Transform Task agent calls
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||
// 1. Transform Task agent calls (supports namespaced names like compound-engineering:research:agent-name)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
|
||||
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||
const skillName = normalizeName(agentName)
|
||||
return `${prefix}Use the ${skillName} skill to: ${args.trim()}`
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const skillName = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim()
|
||||
return trimmedArgs
|
||||
? `${prefix}Use the ${skillName} skill to: ${trimmedArgs}`
|
||||
: `${prefix}Use the ${skillName} skill`
|
||||
})
|
||||
|
||||
// 2. Rewrite .claude/ paths to .gemini/
|
||||
|
||||
@@ -135,10 +135,15 @@ function convertCommandToSkill(
|
||||
export function transformContentForKiro(body: string, knownAgentNames: string[] = []): string {
|
||||
let result = body
|
||||
|
||||
// 1. Transform Task agent calls
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||
// 1. Transform Task agent calls (supports namespaced names like compound-engineering:research:agent-name)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
|
||||
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||
return `${prefix}Use the use_subagent tool to delegate to the ${normalizeName(agentName)} agent: ${args.trim()}`
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const agentRef = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim()
|
||||
return trimmedArgs
|
||||
? `${prefix}Use the use_subagent tool to delegate to the ${agentRef} agent: ${trimmedArgs}`
|
||||
: `${prefix}Use the use_subagent tool to delegate to the ${agentRef} agent`
|
||||
})
|
||||
|
||||
// 2. Rewrite .claude/ paths to .kiro/ (with word-boundary-like lookbehind)
|
||||
|
||||
@@ -90,16 +90,19 @@ function convertAgent(agent: ClaudeAgent, usedNames: Set<string>): PiGeneratedSk
|
||||
}
|
||||
}
|
||||
|
||||
function transformContentForPi(body: string): string {
|
||||
export function transformContentForPi(body: string): string {
|
||||
let result = body
|
||||
|
||||
// Task repo-research-analyst(feature_description)
|
||||
// Task repo-research-analyst(feature_description) or Task compound-engineering:research:repo-research-analyst(args)
|
||||
// -> Run subagent with agent="repo-research-analyst" and task="feature_description"
|
||||
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) => {
|
||||
const skillName = normalizeName(agentName)
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const skillName = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim().replace(/\s+/g, " ")
|
||||
return `${prefix}Run subagent with agent=\"${skillName}\" and task=\"${trimmedArgs}\".`
|
||||
return trimmedArgs
|
||||
? `${prefix}Run subagent with agent=\"${skillName}\" and task=\"${trimmedArgs}\".`
|
||||
: `${prefix}Run subagent with agent=\"${skillName}\".`
|
||||
})
|
||||
|
||||
// Claude-specific tool references
|
||||
|
||||
@@ -122,10 +122,15 @@ export function transformContentForWindsurf(body: string, knownAgentNames: strin
|
||||
// In Windsurf, @skill-name is the native invocation syntax for skills.
|
||||
// Since agents are now mapped to skills, @agent-name already works correctly.
|
||||
|
||||
// 4. Transform Task agent calls to skill references
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9-]*)\(([^)]+)\)/gm
|
||||
// 4. Transform Task agent calls to skill references (supports namespaced names)
|
||||
const taskPattern = /^(\s*-?\s*)Task\s+([a-z][a-z0-9:-]*)\(([^)]*)\)/gm
|
||||
result = result.replace(taskPattern, (_match, prefix: string, agentName: string, args: string) => {
|
||||
return `${prefix}Use the @${normalizeName(agentName)} skill: ${args.trim()}`
|
||||
const finalSegment = agentName.includes(":") ? agentName.split(":").pop()! : agentName
|
||||
const skillRef = normalizeName(finalSegment)
|
||||
const trimmedArgs = args.trim()
|
||||
return trimmedArgs
|
||||
? `${prefix}Use the @${skillRef} skill: ${trimmedArgs}`
|
||||
: `${prefix}Use the @${skillRef} skill`
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user