mirror of
https://github.com/EveryInc/compound-engineering-plugin.git
synced 2026-06-19 15:41:46 +02:00
refactor(tests): update fixtures for flat agents layout
Update sourcePath fixtures and expected Codex agent names across the
test suite to reflect agents now living directly under
plugins/compound-engineering/agents/ with no category subfolders:
- tests/codex-converter.test.ts: flip the namespaced-Task test to the
flat layout with bare ce-<agent> expected names. Add a new test that
pins the nested-layout fallback: any third-party plugin still using
agents/<category>/<name>.md passed through convertClaudeToCodex must
continue to produce <category>-ce-<agent> Codex agent names.
- tests/pi-writer.test.ts, tests/review-skill-contract.test.ts,
tests/legacy-cleanup.test.ts, tests/pipeline-review-contract.test.ts,
tests/kiro-writer.test.ts: strip the <category>/ segment from every
hardcoded plugins/compound-engineering/agents/* path. Several of
these (legacy-cleanup.test.ts in particular) perform live filesystem
reads and would throw ENOENT if left pointing at the old nested
locations.
- tests/review-skill-contract.test.ts: update the
stack-specific-reviewers contract test to assert bare ce-<agent>
references in SKILL.md / persona-catalog.md, matching the new
convention.
Also simplify cleanupLegacyAgentSkillDirs: the `agent.name.includes("-ce-")`
branch relied on compound names like review-ce-foo to extract a legacy
ce-<final> variant. Every current agent now starts with ce- with no
embedded -ce-, so that branch produced nonsense entries (ce-ce-<name>)
and swept nothing. Remove the dead branch; keep the primary
legacySkillNames.add(sanitizePathName(agent.name)) which still catches
stale skill directories under ~/.codex/skills/<plugin>/<agent-name>/.
bun test passes with 830 tests green. bun run release:validate reports
no drift: compound-engineering at 50 agents, 45 skills, 0 MCP servers.
Per docs/plans/2026-04-21-001-refactor-flatten-agents-directory-plan.md
Unit 5.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -299,9 +299,7 @@ async function cleanupLegacyAgentSkillDirs(
|
||||
const currentSkillSet = new Set(currentSkills)
|
||||
const legacySkillNames = new Set<string>()
|
||||
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,
|
||||
|
||||
@@ -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 <category>-<agent> naming for nested-layout plugins (dead-code fallback)", () => {
|
||||
// This test pins the behavior of getAgentCategory() for any third-party
|
||||
// plugin that still uses agents/<category>/<name>.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:")
|
||||
})
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user