2026-05-25 22:24:37 +09:00
import assert from "node:assert/strict" ;
2026-05-27 15:13:47 +09:00
import { readdir , readFile , stat } from "node:fs/promises" ;
import { basename , dirname , join } from "node:path" ;
2026-05-25 22:24:37 +09:00
import test from "node:test" ;
import { fileURLToPath } from "node:url" ;
const root = dirname ( dirname ( fileURLToPath ( import . meta . url ) ) ) ;
async function readJson ( relativePath ) {
return JSON . parse ( await readFile ( join ( root , relativePath ) , "utf8" ) ) ;
}
2026-05-27 15:13:47 +09:00
function findSpawnAgentTypes ( content ) {
const agentTypes = new Set ( ) ;
const regex = /spawn_agent\(agent_type="([^"]+)"/g ;
for ( const match of content . matchAll ( regex ) ) {
agentTypes . add ( match [ 1 ] ) ;
}
return [ ... agentTypes ] . sort ( ) ;
}
2026-05-25 22:24:37 +09:00
test ( "#given aggregate plugin manifest #when inspected #then it owns the omo namespace" , async ( ) => {
// given
const manifest = await readJson ( ".codex-plugin/plugin.json" ) ;
// when
const hookPath = manifest . hooks ;
const skillsPath = manifest . skills ;
const mcpPath = manifest . mcpServers ;
// then
assert . equal ( manifest . name , "omo" ) ;
assert . equal ( hookPath , "./hooks/hooks.json" ) ;
assert . equal ( skillsPath , "./skills/" ) ;
assert . equal ( mcpPath , "./.mcp.json" ) ;
} ) ;
test ( "#given isolated components #when hooks are inspected #then commands stay inside component roots" , async ( ) => {
// given
const hooks = await readJson ( "hooks/hooks.json" ) ;
const text = JSON . stringify ( hooks ) ;
// when
const componentMarkers = [
"components/comment-checker/dist/cli.js" ,
"components/lsp/dist/cli.js" ,
"components/rules/dist/cli.js" ,
2026-05-29 11:19:00 +09:00
"components/start-work-continuation/dist/cli.js" ,
2026-05-26 15:30:41 +09:00
"components/telemetry/dist/cli.js" ,
2026-05-29 12:38:22 +09:00
"components/ulw-loop/dist/cli.js" ,
2026-05-28 15:07:51 +09:00
"components/ultrawork/dist/cli.js" ,
2026-05-25 22:24:37 +09:00
] ;
// then
for ( const marker of componentMarkers ) {
assert . match ( text , new RegExp ( marker . replaceAll ( "/" , "\\/" ) ) ) ;
}
2026-05-29 12:38:22 +09:00
assert . doesNotMatch ( text , /codex-(comment-checker|lsp|rules|telemetry|ulw-loop|ultrawork)@/ ) ;
2026-05-25 22:24:37 +09:00
} ) ;
2026-05-29 12:38:22 +09:00
test ( "#given aggregate OMO plugin is enabled #when hooks are inspected #then ulw-loop guards budgeted create_goal calls" , async ( ) => {
2026-05-28 14:19:14 +09:00
// given
const hooks = await readJson ( "hooks/hooks.json" ) ;
const text = JSON . stringify ( hooks ) ;
// when
const preToolUseGroups = hooks . hooks . PreToolUse ;
// then
2026-05-29 12:38:22 +09:00
assert . match ( text , /components\/ulw-loop\/dist\/cli\.js/ ) ;
2026-05-28 14:19:14 +09:00
assert . match ( text , /hook pre-tool-use/ ) ;
assert . deepEqual ( preToolUseGroups . map ( ( group ) => group . matcher ) , [ "^create_goal$" ] ) ;
} ) ;
2026-05-29 12:18:24 +09:00
test ( "#given aggregate MCP config #when inspected #then LSP is lazy while non-lazy code MCPs reuse root packages" , async ( ) => {
2026-05-25 22:24:37 +09:00
// given
2026-05-28 15:26:18 +09:00
const packageJson = await readJson ( "package.json" ) ;
2026-05-25 22:24:37 +09:00
const mcp = await readJson ( ".mcp.json" ) ;
// when
2026-05-28 15:26:18 +09:00
const lspServer = mcp . mcpServers . lsp ;
const astGrepServer = mcp . mcpServers . ast _grep ;
const codeMcpNames = Object . keys ( mcp . mcpServers )
. filter ( ( name ) => name === "lsp" || name === "ast_grep" )
. sort ( ) ;
2026-05-25 22:24:37 +09:00
// then
2026-05-28 15:26:18 +09:00
assert . deepEqual ( codeMcpNames , [ "ast_grep" , "lsp" ] ) ;
assert . equal ( packageJson . workspaces . includes ( "components/lsp/packages/lsp-tools-mcp" ) , false ) ;
assert . equal ( packageJson . workspaces . includes ( "components/ast-grep/packages/ast-grep-mcp" ) , false ) ;
assert . match ( packageJson . scripts . build , /ast-grep-mcp/ ) ;
assert . equal ( lspServer . command , "node" ) ;
2026-05-29 12:18:24 +09:00
assert . deepEqual ( lspServer . args , [ "./components/lsp/dist/cli.js" , "mcp" ] ) ;
2026-05-28 15:26:18 +09:00
assert . equal ( lspServer . cwd , "." ) ;
assert . equal ( astGrepServer . command , "node" ) ;
assert . deepEqual ( astGrepServer . args , [ "../../ast-grep-mcp/dist/cli.js" , "mcp" ] ) ;
assert . equal ( astGrepServer . cwd , "." ) ;
2026-05-25 22:24:37 +09:00
} ) ;
2026-05-26 17:40:46 +09:00
test ( "#given aggregate plugin build script #when inspected #then telemetry sync runs before workspace builds" , async ( ) => {
// given
const packageJson = await readJson ( "package.json" ) ;
const telemetrySyncScript = await readFile ( join ( root , ".." , "scripts" , "sync-telemetry-component.mjs" ) , "utf8" ) ;
// when
const buildScript = packageJson . scripts . build ;
// then
2026-05-28 15:26:18 +09:00
assert . equal (
buildScript ,
"bun run --cwd ../../ast-grep-mcp build && node scripts/sync-skills.mjs && node ../scripts/sync-telemetry-component.mjs && npm run build --workspaces --if-present" ,
) ;
2026-05-26 17:40:46 +09:00
assert . match ( telemetrySyncScript , /syncTelemetryComponent/ ) ;
} ) ;
2026-05-27 16:43:23 +09:00
test ( "#given component directories #when scanned #then only intentional resource roots declare plugin manifests" , async ( ) => {
2026-05-25 22:24:37 +09:00
// given
const components = await readdir ( join ( root , "components" ) , { withFileTypes : true } ) ;
2026-05-27 16:43:23 +09:00
const expectedComponentManifests = new Map ( [ [ "rules" , { hooks : "./hooks/hooks.json" } ] ] ) ;
2026-05-25 22:24:37 +09:00
// when
const componentNames = components . filter ( ( entry ) => entry . isDirectory ( ) ) . map ( ( entry ) => entry . name ) . sort ( ) ;
// then
2026-05-29 11:19:00 +09:00
assert . deepEqual ( componentNames , [
"comment-checker" ,
"lsp" ,
"rules" ,
"start-work-continuation" ,
"telemetry" ,
"ultrawork" ,
2026-05-29 12:38:22 +09:00
"ulw-loop" ,
2026-05-29 11:19:00 +09:00
] ) ;
2026-05-25 22:24:37 +09:00
for ( const name of componentNames ) {
2026-05-27 16:43:23 +09:00
const expectedManifest = expectedComponentManifests . get ( name ) ;
if ( expectedManifest !== undefined ) {
assert . deepEqual ( await readJson ( join ( "components" , name , ".codex-plugin" , "plugin.json" ) ) , expectedManifest ) ;
continue ;
}
2026-05-25 22:24:37 +09:00
await assert . rejects (
readFile ( join ( root , "components" , name , ".codex-plugin" , "plugin.json" ) , "utf8" ) ,
/code: 'ENOENT'|ENOENT/ ,
) ;
}
} ) ;
2026-05-27 15:13:47 +09:00
2026-05-29 11:19:00 +09:00
test ( "#given bundled Codex agents #when components/ultrawork/agents directory is scanned #then planner support TOMLs are present and match expected schema keys" , async ( ) => {
2026-05-27 15:13:47 +09:00
const agentsDir = join ( root , "components" , "ultrawork" , "agents" ) ;
const entries = ( await readdir ( agentsDir , { withFileTypes : true } ) )
. filter ( ( entry ) => entry . isFile ( ) && entry . name . endsWith ( ".toml" ) )
. map ( ( entry ) => entry . name )
. sort ( ) ;
assert . deepEqual ( entries , [
"codex-ultrawork-reviewer.toml" ,
"explorer.toml" ,
"librarian.toml" ,
2026-05-29 11:19:00 +09:00
"metis.toml" ,
"momus.toml" ,
2026-05-27 15:13:47 +09:00
"plan.toml" ,
] ) ;
for ( const fileName of entries ) {
const content = await readFile ( join ( agentsDir , fileName ) , "utf8" ) ;
assert . match ( content , /^name\s*=\s*".+"$/m ) ;
assert . match ( content , /^description\s*=\s*".+"$/m ) ;
assert . match ( content , /^nickname_candidates\s*=\s*\[.+\]$/m ) ;
assert . match ( content , /^model\s*=\s*".+"$/m ) ;
assert . match ( content , /^model_reasoning_effort\s*=\s*".+"$/m ) ;
assert . match ( content , /^developer_instructions\s*=\s*"""/m ) ;
}
} ) ;
2026-05-29 11:19:00 +09:00
test ( "#given synced skills with Codex compatibility guidance #when a bundled agent_type is referenced #then a matching TOML is bundled" , async ( ) => {
2026-05-27 15:13:47 +09:00
const skillsDir = join ( root , "skills" ) ;
const skillEntries = await readdir ( skillsDir , { withFileTypes : true } ) ;
const skillFiles = skillEntries
. filter ( ( entry ) => entry . isDirectory ( ) )
. map ( ( entry ) => join ( skillsDir , entry . name , "SKILL.md" ) ) ;
const referencedAgentTypes = new Set ( ) ;
for ( const skillPath of skillFiles ) {
const content = await readFile ( skillPath , "utf8" ) ;
for ( const agentType of findSpawnAgentTypes ( content ) ) {
if ( agentType === "worker" || agentType === "codex-ultrawork-reviewer" ) {
continue ;
}
referencedAgentTypes . add ( agentType ) ;
}
}
const expected = [ ... referencedAgentTypes ] . sort ( ) ;
2026-05-29 11:19:00 +09:00
assert . deepEqual ( expected , [ "explorer" , "librarian" , "metis" , "momus" , "plan" ] ) ;
2026-05-27 15:13:47 +09:00
for ( const agentType of expected ) {
const tomlPath = join ( root , "components" , "ultrawork" , "agents" , ` ${ agentType } .toml ` ) ;
const fileStat = await stat ( tomlPath ) ;
assert . equal ( fileStat . isFile ( ) , true ) ;
assert . equal ( basename ( tomlPath ) , ` ${ agentType } .toml ` ) ;
}
} ) ;