fix: stabilize compound-engineering component counts (#299)
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "compound-engineering",
|
"name": "compound-engineering",
|
||||||
"description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes 29 specialized agents and 44 skills.",
|
"description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last.",
|
||||||
"version": "2.42.0",
|
"version": "2.42.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kieran Klaassen",
|
"name": "Kieran Klaassen",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "compound-engineering",
|
"name": "compound-engineering",
|
||||||
"version": "2.42.0",
|
"version": "2.42.0",
|
||||||
"description": "AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
"description": "AI-powered development tools for code review, research, design, and workflow automation.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kieran Klaassen",
|
"name": "Kieran Klaassen",
|
||||||
"email": "kieran@every.to",
|
"email": "kieran@every.to",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "compound-engineering",
|
"name": "compound-engineering",
|
||||||
"displayName": "Compound Engineering",
|
"displayName": "Compound Engineering",
|
||||||
"version": "2.42.0",
|
"version": "2.42.0",
|
||||||
"description": "AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
"description": "AI-powered development tools for code review, research, design, and workflow automation.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kieran Klaassen",
|
"name": "Kieran Klaassen",
|
||||||
"email": "kieran@every.to",
|
"email": "kieran@every.to",
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ AI-powered development tools that get smarter with every use. Make each unit of
|
|||||||
|
|
||||||
| Component | Count |
|
| Component | Count |
|
||||||
|-----------|-------|
|
|-----------|-------|
|
||||||
| Agents | 29 |
|
| Agents | 25+ |
|
||||||
| Skills | 44 |
|
| Skills | 40+ |
|
||||||
| MCP Servers | 1 |
|
| MCP Servers | 1 |
|
||||||
|
|
||||||
## Agents
|
## Agents
|
||||||
|
|
||||||
Agents are organized into categories for easier discovery.
|
Agents are organized into categories for easier discovery.
|
||||||
|
|
||||||
### Review (15)
|
### Review
|
||||||
|
|
||||||
| Agent | Description |
|
| Agent | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
@@ -34,7 +34,7 @@ Agents are organized into categories for easier discovery.
|
|||||||
| `schema-drift-detector` | Detect unrelated schema.rb changes in PRs |
|
| `schema-drift-detector` | Detect unrelated schema.rb changes in PRs |
|
||||||
| `security-sentinel` | Security audits and vulnerability assessments |
|
| `security-sentinel` | Security audits and vulnerability assessments |
|
||||||
|
|
||||||
### Research (6)
|
### Research
|
||||||
|
|
||||||
| Agent | Description |
|
| Agent | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
@@ -45,7 +45,7 @@ Agents are organized into categories for easier discovery.
|
|||||||
| `learnings-researcher` | Search institutional learnings for relevant past solutions |
|
| `learnings-researcher` | Search institutional learnings for relevant past solutions |
|
||||||
| `repo-research-analyst` | Research repository structure and conventions |
|
| `repo-research-analyst` | Research repository structure and conventions |
|
||||||
|
|
||||||
### Design (3)
|
### Design
|
||||||
|
|
||||||
| Agent | Description |
|
| Agent | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
@@ -53,7 +53,7 @@ Agents are organized into categories for easier discovery.
|
|||||||
| `design-iterator` | Iteratively refine UI through systematic design iterations |
|
| `design-iterator` | Iteratively refine UI through systematic design iterations |
|
||||||
| `figma-design-sync` | Synchronize web implementations with Figma designs |
|
| `figma-design-sync` | Synchronize web implementations with Figma designs |
|
||||||
|
|
||||||
### Workflow (4)
|
### Workflow
|
||||||
|
|
||||||
| Agent | Description |
|
| Agent | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
@@ -62,7 +62,7 @@ Agents are organized into categories for easier discovery.
|
|||||||
| `pr-comment-resolver` | Address PR comments and implement fixes |
|
| `pr-comment-resolver` | Address PR comments and implement fixes |
|
||||||
| `spec-flow-analyzer` | Analyze user flows and identify gaps in specifications |
|
| `spec-flow-analyzer` | Analyze user flows and identify gaps in specifications |
|
||||||
|
|
||||||
### Docs (1)
|
### Docs
|
||||||
|
|
||||||
| Agent | Description |
|
| Agent | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
#!/usr/bin/env bun
|
#!/usr/bin/env bun
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { validateReleasePleaseConfig } from "../../src/release/config"
|
import { validateReleasePleaseConfig } from "../../src/release/config"
|
||||||
import { syncReleaseMetadata } from "../../src/release/metadata"
|
import { getCompoundEngineeringCounts, syncReleaseMetadata } from "../../src/release/metadata"
|
||||||
import { readJson } from "../../src/utils/files"
|
import { readJson } from "../../src/utils/files"
|
||||||
|
|
||||||
const releasePleaseConfig = await readJson<{ packages: Record<string, unknown> }>(
|
const releasePleaseConfig = await readJson<{ packages: Record<string, unknown> }>(
|
||||||
path.join(process.cwd(), ".github", "release-please-config.json"),
|
path.join(process.cwd(), ".github", "release-please-config.json"),
|
||||||
)
|
)
|
||||||
const configErrors = validateReleasePleaseConfig(releasePleaseConfig)
|
const configErrors = validateReleasePleaseConfig(releasePleaseConfig)
|
||||||
|
const counts = await getCompoundEngineeringCounts(process.cwd())
|
||||||
const result = await syncReleaseMetadata({ write: false })
|
const result = await syncReleaseMetadata({ write: false })
|
||||||
const changed = result.updates.filter((update) => update.changed)
|
const changed = result.updates.filter((update) => update.changed)
|
||||||
|
|
||||||
if (configErrors.length === 0 && changed.length === 0) {
|
if (configErrors.length === 0 && changed.length === 0) {
|
||||||
console.log("Release metadata is in sync.")
|
console.log(
|
||||||
|
`Release metadata is in sync. compound-engineering currently has ${counts.agents} agents, ${counts.skills} skills, and ${counts.mcpServers} MCP server${counts.mcpServers === 1 ? "" : "s"}.`,
|
||||||
|
)
|
||||||
process.exit(0)
|
process.exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,5 +31,8 @@ if (changed.length > 0) {
|
|||||||
for (const update of changed) {
|
for (const update of changed) {
|
||||||
console.error(`- ${update.path}`)
|
console.error(`- ${update.path}`)
|
||||||
}
|
}
|
||||||
|
console.error(
|
||||||
|
`Current compound-engineering counts: ${counts.agents} agents, ${counts.skills} skills, ${counts.mcpServers} MCP server${counts.mcpServers === 1 ? "" : "s"}.`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
|||||||
@@ -41,6 +41,18 @@ export type MetadataSyncResult = {
|
|||||||
updates: FileUpdate[]
|
updates: FileUpdate[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CompoundEngineeringCounts = {
|
||||||
|
agents: number
|
||||||
|
skills: number
|
||||||
|
mcpServers: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const COMPOUND_ENGINEERING_DESCRIPTION =
|
||||||
|
"AI-powered development tools for code review, research, design, and workflow automation."
|
||||||
|
|
||||||
|
const COMPOUND_ENGINEERING_MARKETPLACE_DESCRIPTION =
|
||||||
|
"AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last."
|
||||||
|
|
||||||
function resolveExpectedVersion(
|
function resolveExpectedVersion(
|
||||||
explicitVersion: string | undefined,
|
explicitVersion: string | undefined,
|
||||||
fallbackVersion: string,
|
fallbackVersion: string,
|
||||||
@@ -90,12 +102,23 @@ export async function countMcpServers(pluginRoot: string): Promise<number> {
|
|||||||
return Object.keys(manifest.mcpServers ?? {}).length
|
return Object.keys(manifest.mcpServers ?? {}).length
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function buildCompoundEngineeringDescription(root: string): Promise<string> {
|
export async function getCompoundEngineeringCounts(root: string): Promise<CompoundEngineeringCounts> {
|
||||||
const pluginRoot = path.join(root, "plugins", "compound-engineering")
|
const pluginRoot = path.join(root, "plugins", "compound-engineering")
|
||||||
const agents = await countMarkdownFiles(path.join(pluginRoot, "agents"))
|
const [agents, skills, mcpServers] = await Promise.all([
|
||||||
const skills = await countSkillDirectories(path.join(pluginRoot, "skills"))
|
countMarkdownFiles(path.join(pluginRoot, "agents")),
|
||||||
const mcpServers = await countMcpServers(pluginRoot)
|
countSkillDirectories(path.join(pluginRoot, "skills")),
|
||||||
return `AI-powered development tools. ${agents} agents, ${skills} skills, ${mcpServers} MCP server${mcpServers === 1 ? "" : "s"} for code review, research, design, and workflow automation.`
|
countMcpServers(pluginRoot),
|
||||||
|
])
|
||||||
|
|
||||||
|
return { agents, skills, mcpServers }
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buildCompoundEngineeringDescription(_root: string): Promise<string> {
|
||||||
|
return COMPOUND_ENGINEERING_DESCRIPTION
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buildCompoundEngineeringMarketplaceDescription(_root: string): Promise<string> {
|
||||||
|
return COMPOUND_ENGINEERING_MARKETPLACE_DESCRIPTION
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function syncReleaseMetadata(options: SyncOptions = {}): Promise<MetadataSyncResult> {
|
export async function syncReleaseMetadata(options: SyncOptions = {}): Promise<MetadataSyncResult> {
|
||||||
@@ -105,6 +128,7 @@ export async function syncReleaseMetadata(options: SyncOptions = {}): Promise<Me
|
|||||||
const updates: FileUpdate[] = []
|
const updates: FileUpdate[] = []
|
||||||
|
|
||||||
const compoundDescription = await buildCompoundEngineeringDescription(root)
|
const compoundDescription = await buildCompoundEngineeringDescription(root)
|
||||||
|
const compoundMarketplaceDescription = await buildCompoundEngineeringMarketplaceDescription(root)
|
||||||
|
|
||||||
const compoundClaudePath = path.join(root, "plugins", "compound-engineering", ".claude-plugin", "plugin.json")
|
const compoundClaudePath = path.join(root, "plugins", "compound-engineering", ".claude-plugin", "plugin.json")
|
||||||
const compoundCursorPath = path.join(root, "plugins", "compound-engineering", ".cursor-plugin", "plugin.json")
|
const compoundCursorPath = path.join(root, "plugins", "compound-engineering", ".cursor-plugin", "plugin.json")
|
||||||
@@ -178,8 +202,8 @@ export async function syncReleaseMetadata(options: SyncOptions = {}): Promise<Me
|
|||||||
plugin.version = expectedCompoundVersion
|
plugin.version = expectedCompoundVersion
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
if (plugin.description !== `AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes ${await countMarkdownFiles(path.join(root, "plugins", "compound-engineering", "agents"))} specialized agents and ${await countSkillDirectories(path.join(root, "plugins", "compound-engineering", "skills"))} skills.`) {
|
if (plugin.description !== compoundMarketplaceDescription) {
|
||||||
plugin.description = `AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes ${await countMarkdownFiles(path.join(root, "plugins", "compound-engineering", "agents"))} specialized agents and ${await countSkillDirectories(path.join(root, "plugins", "compound-engineering", "skills"))} skills.`
|
plugin.description = compoundMarketplaceDescription
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { mkdtemp, mkdir, writeFile } from "fs/promises"
|
|||||||
import os from "os"
|
import os from "os"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { afterEach, describe, expect, test } from "bun:test"
|
import { afterEach, describe, expect, test } from "bun:test"
|
||||||
import { buildCompoundEngineeringDescription, syncReleaseMetadata } from "../src/release/metadata"
|
import {
|
||||||
|
buildCompoundEngineeringDescription,
|
||||||
|
getCompoundEngineeringCounts,
|
||||||
|
syncReleaseMetadata,
|
||||||
|
} from "../src/release/metadata"
|
||||||
|
|
||||||
const tempRoots: string[] = []
|
const tempRoots: string[] = []
|
||||||
|
|
||||||
@@ -83,10 +87,24 @@ async function makeFixtureRoot(): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("release metadata", () => {
|
describe("release metadata", () => {
|
||||||
test("builds the current compound-engineering manifest description from repo counts", async () => {
|
test("reports current compound-engineering counts from the repo", async () => {
|
||||||
|
const counts = await getCompoundEngineeringCounts(process.cwd())
|
||||||
|
|
||||||
|
expect(counts).toEqual({
|
||||||
|
agents: expect.any(Number),
|
||||||
|
skills: expect.any(Number),
|
||||||
|
mcpServers: expect.any(Number),
|
||||||
|
})
|
||||||
|
expect(counts.agents).toBeGreaterThan(0)
|
||||||
|
expect(counts.skills).toBeGreaterThan(0)
|
||||||
|
expect(counts.mcpServers).toBeGreaterThanOrEqual(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("builds a stable compound-engineering manifest description", async () => {
|
||||||
const description = await buildCompoundEngineeringDescription(process.cwd())
|
const description = await buildCompoundEngineeringDescription(process.cwd())
|
||||||
|
|
||||||
expect(description).toBe(
|
expect(description).toBe(
|
||||||
"AI-powered development tools. 29 agents, 44 skills, 1 MCP server for code review, research, design, and workflow automation.",
|
"AI-powered development tools for code review, research, design, and workflow automation.",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user