diff --git a/src/targets/codex.ts b/src/targets/codex.ts index 0ed18d3a..452b42b4 100644 --- a/src/targets/codex.ts +++ b/src/targets/codex.ts @@ -299,9 +299,7 @@ async function cleanupLegacyAgentSkillDirs( const currentSkillSet = new Set(currentSkills) const legacySkillNames = new Set() for (const agent of bundle.agents ?? []) { - const finalSegment = agent.name.includes("-ce-") ? agent.name.split("-ce-").pop() : agent.name legacySkillNames.add(sanitizePathName(agent.name)) - if (finalSegment) legacySkillNames.add(`ce-${sanitizePathName(finalSegment)}`) } for (const name of getLegacyCodexArtifacts({ pluginName, diff --git a/tests/codex-converter.test.ts b/tests/codex-converter.test.ts index 6079a0df..8c8b7ef8 100644 --- a/tests/codex-converter.test.ts +++ b/tests/codex-converter.test.ts @@ -326,14 +326,59 @@ Task compound-engineering:review:ce-security-reviewer(code_diff)`, name: "ce-repo-research-analyst", description: "Repo research", body: "Research repositories.", - sourcePath: "/tmp/plugin/agents/research/ce-repo-research-analyst.agent.md", + sourcePath: "/tmp/plugin/agents/ce-repo-research-analyst.agent.md", }, { name: "ce-learnings-researcher", description: "Learning research", body: "Search learnings.", - sourcePath: "/tmp/plugin/agents/research/ce-learnings-researcher.agent.md", + sourcePath: "/tmp/plugin/agents/ce-learnings-researcher.agent.md", }, + { + name: "ce-security-reviewer", + description: "Security review", + body: "Review security.", + sourcePath: "/tmp/plugin/agents/ce-security-reviewer.agent.md", + }, + ], + skills: [], + } + + const bundle = convertClaudeToCodex(plugin, { + agentMode: "subagent", + inferTemperature: false, + permissions: "none", + codexIncludeSkills: true, + }) + + const commandSkill = bundle.generatedSkills.find((s) => s.name === "plan") + expect(commandSkill).toBeDefined() + const parsed = parseFrontmatter(commandSkill!.content) + + expect(parsed.body).toContain("Spawn the custom agent `ce-repo-research-analyst` with task: feature_description") + expect(parsed.body).toContain("Spawn the custom agent `ce-learnings-researcher` with task: feature_description") + expect(parsed.body).toContain("Spawn the custom agent `ce-security-reviewer` with task: code_diff") + + // Original namespaced Task syntax should not remain + expect(parsed.body).not.toContain("Task compound-engineering:") + }) + + test("retains - naming for nested-layout plugins (dead-code fallback)", () => { + // This test pins the behavior of getAgentCategory() for any third-party + // plugin that still uses agents//.md layout. The + // compound-engineering plugin itself is flat, but the converter must keep + // working for other plugins passed through the CLI. + const plugin: ClaudePlugin = { + ...fixturePlugin, + commands: [ + { + name: "plan", + description: "Planning with agents from a nested-layout plugin", + body: `- Task compound-engineering:review:ce-security-reviewer(code_diff)`, + sourcePath: "/tmp/plugin/commands/plan.md", + }, + ], + agents: [ { name: "ce-security-reviewer", description: "Security review", @@ -355,12 +400,7 @@ Task compound-engineering:review:ce-security-reviewer(code_diff)`, expect(commandSkill).toBeDefined() const parsed = parseFrontmatter(commandSkill!.content) - expect(parsed.body).toContain("Spawn the custom agent `research-ce-repo-research-analyst` with task: feature_description") - expect(parsed.body).toContain("Spawn the custom agent `research-ce-learnings-researcher` with task: feature_description") expect(parsed.body).toContain("Spawn the custom agent `review-ce-security-reviewer` with task: code_diff") - - // Original namespaced Task syntax should not remain - expect(parsed.body).not.toContain("Task compound-engineering:") }) test("transforms zero-argument Task calls", () => { @@ -379,7 +419,7 @@ Task compound-engineering:review:ce-security-reviewer(code_diff)`, name: "ce-code-simplicity-reviewer", description: "Simplicity review", body: "Review simplicity.", - sourcePath: "/tmp/plugin/agents/review/ce-code-simplicity-reviewer.agent.md", + sourcePath: "/tmp/plugin/agents/ce-code-simplicity-reviewer.agent.md", }, ], skills: [], @@ -395,7 +435,7 @@ Task compound-engineering:review:ce-security-reviewer(code_diff)`, const commandSkill = bundle.generatedSkills.find((s) => s.name === "review") expect(commandSkill).toBeDefined() const parsed = parseFrontmatter(commandSkill!.content) - expect(parsed.body).toContain("Spawn the custom agent `review-ce-code-simplicity-reviewer`") + expect(parsed.body).toContain("Spawn the custom agent `ce-code-simplicity-reviewer`") expect(parsed.body).not.toContain("compound-engineering:") expect(parsed.body).not.toContain("skill to:") }) diff --git a/tests/kiro-writer.test.ts b/tests/kiro-writer.test.ts index eefdce21..fd1ee1e8 100644 --- a/tests/kiro-writer.test.ts +++ b/tests/kiro-writer.test.ts @@ -38,7 +38,7 @@ describe("writeKiroBundle", () => { const kiroRoot = path.join(tempRoot, ".kiro") await fs.mkdir(path.join(kiroRoot, "agents", "prompts"), { recursive: true }) const sessionHistorianDescription = await pluginDescription( - "plugins/compound-engineering/agents/research/ce-session-historian.agent.md", + "plugins/compound-engineering/agents/ce-session-historian.agent.md", ) await fs.writeFile( diff --git a/tests/legacy-cleanup.test.ts b/tests/legacy-cleanup.test.ts index 69719318..02c53a68 100644 --- a/tests/legacy-cleanup.test.ts +++ b/tests/legacy-cleanup.test.ts @@ -257,14 +257,14 @@ describe("cleanupStaleAgents", () => { path.join(root, "adversarial-reviewer.md"), agentContent( "adversarial-reviewer", - await pluginDescription("plugins/compound-engineering/agents/review/ce-adversarial-reviewer.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-adversarial-reviewer.agent.md"), ), ) await createFile( path.join(root, "learnings-researcher.md"), agentContent( "learnings-researcher", - await pluginDescription("plugins/compound-engineering/agents/research/ce-learnings-researcher.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-learnings-researcher.agent.md"), ), ) @@ -281,14 +281,14 @@ describe("cleanupStaleAgents", () => { path.join(root, "security-sentinel.agent.md"), agentContent( "security-sentinel", - await pluginDescription("plugins/compound-engineering/agents/review/ce-security-sentinel.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-security-sentinel.agent.md"), ), ) await createFile( path.join(root, "performance-oracle.agent.md"), agentContent( "performance-oracle", - await pluginDescription("plugins/compound-engineering/agents/review/ce-performance-oracle.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-performance-oracle.agent.md"), ), ) @@ -304,14 +304,14 @@ describe("cleanupStaleAgents", () => { path.join(root, "slack-researcher.json"), kiroAgentConfigContent( "slack-researcher", - await pluginDescription("plugins/compound-engineering/agents/research/ce-slack-researcher.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-slack-researcher.agent.md"), ), ) await createFile( path.join(root, "session-historian.json"), kiroAgentConfigContent( "session-historian", - await pluginDescription("plugins/compound-engineering/agents/research/ce-session-historian.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-session-historian.agent.md"), ), ) await createFile( @@ -336,14 +336,14 @@ describe("cleanupStaleAgents", () => { path.join(root, "code-simplicity-reviewer"), skillContent( "code-simplicity-reviewer", - await pluginDescription("plugins/compound-engineering/agents/review/ce-code-simplicity-reviewer.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-code-simplicity-reviewer.agent.md"), ), ) await createDir( path.join(root, "repo-research-analyst"), skillContent( "repo-research-analyst", - await pluginDescription("plugins/compound-engineering/agents/research/ce-repo-research-analyst.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-repo-research-analyst.agent.md"), ), ) @@ -618,7 +618,7 @@ describe("idempotency", () => { path.join(root, "adversarial-reviewer.md"), agentContent( "adversarial-reviewer", - await pluginDescription("plugins/compound-engineering/agents/review/ce-adversarial-reviewer.agent.md"), + await pluginDescription("plugins/compound-engineering/agents/ce-adversarial-reviewer.agent.md"), ), ) diff --git a/tests/pi-writer.test.ts b/tests/pi-writer.test.ts index 0b4a9936..3a1d4d28 100644 --- a/tests/pi-writer.test.ts +++ b/tests/pi-writer.test.ts @@ -32,7 +32,7 @@ describe("writePiBundle", () => { const outputRoot = path.join(tempRoot, ".pi") const sessionHistorianDescription = await pluginDescription( - "plugins/compound-engineering/agents/research/ce-session-historian.agent.md", + "plugins/compound-engineering/agents/ce-session-historian.agent.md", ) await fs.mkdir(path.join(outputRoot, "skills", "session-historian"), { recursive: true }) diff --git a/tests/pipeline-review-contract.test.ts b/tests/pipeline-review-contract.test.ts index 25fe6c5e..44a8b1d7 100644 --- a/tests/pipeline-review-contract.test.ts +++ b/tests/pipeline-review-contract.test.ts @@ -597,7 +597,7 @@ describe("ce-compound frontmatter schema expansion contract", () => { describe("ce-learnings-researcher domain-agnostic contract", () => { test("agent prompt frames as domain-agnostic not bug-focused", async () => { const agent = await readRepoFile( - "plugins/compound-engineering/agents/research/ce-learnings-researcher.agent.md" + "plugins/compound-engineering/agents/ce-learnings-researcher.agent.md" ) // Domain-agnostic identity framing diff --git a/tests/review-skill-contract.test.ts b/tests/review-skill-contract.test.ts index 8c0d9d31..226a81ce 100644 --- a/tests/review-skill-contract.test.ts +++ b/tests/review-skill-contract.test.ts @@ -205,11 +205,11 @@ describe("ce-code-review contract", () => { ) for (const agent of [ - "review:ce-dhh-rails-reviewer", - "review:ce-kieran-rails-reviewer", - "review:ce-kieran-python-reviewer", - "review:ce-kieran-typescript-reviewer", - "review:ce-julik-frontend-races-reviewer", + "ce-dhh-rails-reviewer", + "ce-kieran-rails-reviewer", + "ce-kieran-python-reviewer", + "ce-kieran-typescript-reviewer", + "ce-julik-frontend-races-reviewer", ]) { expect(content).toContain(agent) expect(catalog).toContain(agent) @@ -222,23 +222,23 @@ describe("ce-code-review contract", () => { test("stack-specific reviewer agents follow the structured findings contract", async () => { const reviewers = [ { - path: "plugins/compound-engineering/agents/review/ce-dhh-rails-reviewer.agent.md", + path: "plugins/compound-engineering/agents/ce-dhh-rails-reviewer.agent.md", reviewer: "dhh-rails", }, { - path: "plugins/compound-engineering/agents/review/ce-kieran-rails-reviewer.agent.md", + path: "plugins/compound-engineering/agents/ce-kieran-rails-reviewer.agent.md", reviewer: "kieran-rails", }, { - path: "plugins/compound-engineering/agents/review/ce-kieran-python-reviewer.agent.md", + path: "plugins/compound-engineering/agents/ce-kieran-python-reviewer.agent.md", reviewer: "kieran-python", }, { - path: "plugins/compound-engineering/agents/review/ce-kieran-typescript-reviewer.agent.md", + path: "plugins/compound-engineering/agents/ce-kieran-typescript-reviewer.agent.md", reviewer: "kieran-typescript", }, { - path: "plugins/compound-engineering/agents/review/ce-julik-frontend-races-reviewer.agent.md", + path: "plugins/compound-engineering/agents/ce-julik-frontend-races-reviewer.agent.md", reviewer: "julik-frontend-races", }, ] @@ -262,7 +262,7 @@ describe("ce-code-review contract", () => { test("leaves data-migration-expert as the unstructured review format", async () => { const content = await readRepoFile( - "plugins/compound-engineering/agents/review/ce-data-migration-expert.agent.md", + "plugins/compound-engineering/agents/ce-data-migration-expert.agent.md", ) expect(content).toContain("## Reviewer Checklist") @@ -304,7 +304,7 @@ describe("ce-code-review contract", () => { describe("testing-reviewer contract", () => { test("includes behavioral-changes-with-no-test-additions check", async () => { - const content = await readRepoFile("plugins/compound-engineering/agents/review/ce-testing-reviewer.agent.md") + const content = await readRepoFile("plugins/compound-engineering/agents/ce-testing-reviewer.agent.md") // New check exists in "What you're hunting for" section expect(content).toContain("Behavioral changes with no test additions")