2026-05-30 19:12:07 +09:00
import assert from "node:assert/strict" ;
import { readdir , readFile , stat } from "node:fs/promises" ;
import { basename , dirname , join } from "node:path" ;
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" ) ) ;
}
async function readComponentHookManifests ( ) {
const components = await readdir ( join ( root , "components" ) , { withFileTypes : true } ) ;
const manifests = [ ] ;
for ( const entry of components ) {
if ( ! entry . isDirectory ( ) ) continue ;
const source = join ( "components" , entry . name , "hooks" , "hooks.json" ) ;
manifests . push ( { source , hooks : await readJson ( source ) } ) ;
}
return manifests . sort ( ( left , right ) => left . source . localeCompare ( right . source ) ) ;
}
function collectCommandHooks ( hooks , source ) {
const config = hooks . hooks ;
if ( typeof config !== "object" || config === null || Array . isArray ( config ) ) {
throw new TypeError ( ` Invalid hooks manifest: ${ source } ` ) ;
}
const commandHooks = [ ] ;
for ( const [ eventName , groups ] of Object . entries ( config ) ) {
if ( ! Array . isArray ( groups ) ) {
throw new TypeError ( ` Invalid hook groups in ${ source } : ${ eventName } ` ) ;
}
groups . forEach ( ( group , groupIndex ) => {
if ( typeof group !== "object" || group === null || ! Array . isArray ( group . hooks ) ) {
throw new TypeError ( ` Invalid hook group in ${ source } : ${ eventName } : ${ groupIndex } ` ) ;
}
group . hooks . forEach ( ( handler , handlerIndex ) => {
if ( typeof handler !== "object" || handler === null || handler . type !== "command" ) return ;
commandHooks . push ( { source , eventName , groupIndex , handlerIndex , handler } ) ;
} ) ;
} ) ;
}
return commandHooks ;
}
function hookLocation ( { source , eventName , groupIndex , handlerIndex , handler } ) {
return ` ${ source } : ${ eventName } : ${ groupIndex } : ${ handlerIndex } : ${ handler . command } ` ;
}
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 ( ) ;
}
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 aggregate plugin metadata #when inspected #then ulw-loop is the public loop name" , async ( ) => {
// given
const manifestText = await readFile ( join ( root , ".codex-plugin" , "plugin.json" ) , "utf8" ) ;
const manifest = JSON . parse ( manifestText ) ;
// when
const longDescription = String ( manifest . interface ? . longDescription ? ? "" ) ;
// then
assert . match ( longDescription , /ulw-loop/ ) ;
} ) ;
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" ,
"components/start-work-continuation/dist/cli.js" ,
"components/telemetry/dist/cli.js" ,
"components/ulw-loop/dist/cli.js" ,
"components/ultrawork/dist/cli.js" ,
] ;
// then
for ( const marker of componentMarkers ) {
assert . match ( text , new RegExp ( marker . replaceAll ( "/" , "\\/" ) ) ) ;
}
assert . doesNotMatch ( text , /codex-(comment-checker|lsp|rules|telemetry|ulw-loop|ultrawork)@/ ) ;
} ) ;
test ( "#given aggregate hook commands #when inspected #then every command exposes a Codex status message" , async ( ) => {
// given
const hooks = await readJson ( "hooks/hooks.json" ) ;
// when
const commandHooks = collectCommandHooks ( hooks , "hooks/hooks.json" ) ;
const missingStatusMessages = commandHooks
. filter ( ( { handler } ) => typeof handler . statusMessage !== "string" || handler . statusMessage . trim ( ) === "" )
. map ( hookLocation ) ;
// then
assert . deepEqual ( missingStatusMessages , [ ] ) ;
} ) ;
test ( "#given component hook commands #when inspected #then standalone packages expose Codex status messages" , async ( ) => {
// given
const componentHooks = await readComponentHookManifests ( ) ;
// when
const missingStatusMessages = componentHooks
. flatMap ( ( { source , hooks } ) => collectCommandHooks ( hooks , source ) )
. filter ( ( { handler } ) => typeof handler . statusMessage !== "string" || handler . statusMessage . trim ( ) === "" )
. map ( hookLocation ) ;
// then
assert . deepEqual ( missingStatusMessages , [ ] ) ;
} ) ;
test ( "#given hook status messages #when inspected #then labels describe OMO responsibilities instead of the hook runner" , async ( ) => {
// given
const aggregateHooks = await readJson ( "hooks/hooks.json" ) ;
const componentHooks = await readComponentHookManifests ( ) ;
// when
const commandHooks = [
... collectCommandHooks ( aggregateHooks , "hooks/hooks.json" ) ,
... componentHooks . flatMap ( ( { source , hooks } ) => collectCommandHooks ( hooks , source ) ) ,
] ;
const genericStatusMessages = commandHooks
. filter ( ( { handler } ) => typeof handler . statusMessage !== "string" || /\bhook\b/i . test ( handler . statusMessage ) )
. map ( hookLocation ) ;
// then
assert . deepEqual ( genericStatusMessages , [ ] ) ;
} ) ;
2026-05-31 13:23:24 +09:00
test ( "#given aggregate OMO plugin is enabled #when hooks are inspected #then shell guidance and ulw-loop guard are registered" , async ( ) => {
2026-05-30 19:12:07 +09:00
// given
const hooks = await readJson ( "hooks/hooks.json" ) ;
const text = JSON . stringify ( hooks ) ;
// when
const preToolUseGroups = hooks . hooks . PreToolUse ;
// then
2026-05-31 13:23:24 +09:00
assert . match ( text , /components\/git-bash\/dist\/cli\.js/ ) ;
assert . match ( text , /Recommending Git Bash Mcp/ ) ;
assert . match ( text , /hook post-compact/ ) ;
assert . match ( text , /Resetting Git Bash Mcp Reminder/ ) ;
2026-05-30 19:12:07 +09:00
assert . match ( text , /components\/ulw-loop\/dist\/cli\.js/ ) ;
assert . match ( text , /hook pre-tool-use/ ) ;
2026-05-31 13:23:24 +09:00
assert . deepEqual ( preToolUseGroups . map ( ( group ) => group . matcher ) , [ "^Bash$" , "^create_goal$" ] ) ;
2026-05-30 19:12:07 +09:00
} ) ;
test ( "#given aggregate MCP config #when inspected #then code MCPs reference package runtimes without package names" , async ( ) => {
// given
const packageJson = await readJson ( "package.json" ) ;
const mcp = await readJson ( ".mcp.json" ) ;
const lspSources = await readdir ( join ( root , "components" , "lsp" , "src" ) ) ;
2026-05-31 00:18:21 +09:00
const bundledMcpBuildScript = await readFile ( join ( root , "scripts" , "build-bundled-mcp-runtimes.mjs" ) , "utf8" ) ;
2026-05-30 19:12:07 +09:00
// when
const lspServer = mcp . mcpServers . lsp ;
const astGrepServer = mcp . mcpServers . ast _grep ;
2026-05-31 13:23:24 +09:00
const gitBashServer = mcp . mcpServers . git _bash ;
2026-05-30 19:12:07 +09:00
const codeMcpNames = Object . keys ( mcp . mcpServers )
2026-05-31 13:23:24 +09:00
. filter ( ( name ) => name === "lsp" || name === "ast_grep" || name === "git_bash" )
2026-05-30 19:12:07 +09:00
. sort ( ) ;
const componentLocalMcpSources = lspSources . filter ( ( name ) => name . startsWith ( "lazy-mcp" ) || name === "lazy-lsp-mcp.ts" ) ;
// then
2026-05-31 13:23:24 +09:00
assert . deepEqual ( codeMcpNames , [ "ast_grep" , "git_bash" , "lsp" ] ) ;
2026-05-30 19:12:07 +09:00
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 . deepEqual ( packageJson . dependencies , { "@oh-my-opencode/shared-skills" : "file:../../shared-skills" } ) ;
2026-05-31 00:18:21 +09:00
assert . match ( bundledMcpBuildScript , /ast-grep-mcp/ ) ;
2026-05-31 13:23:24 +09:00
assert . match ( bundledMcpBuildScript , /git-bash-mcp/ ) ;
2026-05-30 19:12:07 +09:00
assert . doesNotMatch ( packageJson . scripts . build , /--workspaces/ ) ;
assert . equal ( lspServer . command , "node" ) ;
assert . deepEqual ( lspServer . args , [ "../../lsp-tools-mcp/dist/cli.js" , "mcp" ] ) ;
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-31 13:23:24 +09:00
assert . equal ( gitBashServer . command , "node" ) ;
assert . deepEqual ( gitBashServer . args , [ "../../git-bash-mcp/dist/cli.js" , "mcp" ] ) ;
assert . equal ( gitBashServer . cwd , "." ) ;
2026-05-30 19:12:07 +09:00
assert . deepEqual ( componentLocalMcpSources , [ ] ) ;
} ) ;
test ( "#given package-level MCP CLIs #when package metadata is inspected #then bin names use the omo prefix" , async ( ) => {
// given
const lspPackageJson = await readJson ( "../../lsp-tools-mcp/package.json" ) ;
const astGrepPackageJson = await readJson ( "../../ast-grep-mcp/package.json" ) ;
2026-05-31 13:23:24 +09:00
const gitBashPackageJson = await readJson ( "../../git-bash-mcp/package.json" ) ;
2026-05-30 19:12:07 +09:00
// when
2026-05-31 13:23:24 +09:00
const binNames = [
... Object . keys ( lspPackageJson . bin ? ? { } ) ,
... Object . keys ( astGrepPackageJson . bin ? ? { } ) ,
... Object . keys ( gitBashPackageJson . bin ? ? { } ) ,
] . sort ( ) ;
2026-05-30 19:12:07 +09:00
// then
2026-05-31 13:23:24 +09:00
assert . deepEqual ( binNames , [ "omo-ast-grep" , "omo-git-bash" , "omo-lsp" ] ) ;
2026-05-30 19:12:07 +09:00
for ( const name of binNames ) {
assert . match ( name , /^omo-/ ) ;
}
} ) ;
2026-05-31 11:53:18 +09:00
test ( "#given aggregate plugin build script #when inspected #then hook status and telemetry sync run before workspace builds" , async ( ) => {
2026-05-30 19:12:07 +09:00
// 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
assert . equal (
buildScript ,
2026-05-31 11:53:18 +09:00
"node scripts/sync-hook-status-messages.mjs && node scripts/build-bundled-mcp-runtimes.mjs && node scripts/sync-skills.mjs && node ../scripts/sync-telemetry-component.mjs && node scripts/build-components.mjs" ,
2026-05-30 19:12:07 +09:00
) ;
assert . match ( telemetrySyncScript , /syncTelemetryComponent/ ) ;
} ) ;
test ( "#given omo-codex package build script #when inspected #then delegates to the aggregate plugin package" , async ( ) => {
// given
const packageJson = JSON . parse ( await readFile ( join ( root , ".." , "package.json" ) , "utf8" ) ) ;
// when
const buildPluginScript = packageJson . scripts [ "build:plugin" ] ;
// then
assert . equal ( buildPluginScript , "bun run --cwd plugin build" ) ;
} ) ;
test ( "#given component directories #when scanned #then only intentional resource roots declare plugin manifests" , async ( ) => {
// given
const components = await readdir ( join ( root , "components" ) , { withFileTypes : true } ) ;
const expectedComponentManifests = new Map ( [ [ "rules" , { hooks : "./hooks/hooks.json" } ] ] ) ;
// when
const componentNames = components . filter ( ( entry ) => entry . isDirectory ( ) ) . map ( ( entry ) => entry . name ) . sort ( ) ;
// then
assert . deepEqual ( componentNames , [
"comment-checker" ,
2026-05-31 13:23:24 +09:00
"git-bash" ,
2026-05-30 19:12:07 +09:00
"lsp" ,
"rules" ,
"start-work-continuation" ,
"telemetry" ,
"ultrawork" ,
"ulw-loop" ,
] ) ;
for ( const name of componentNames ) {
const expectedManifest = expectedComponentManifests . get ( name ) ;
if ( expectedManifest !== undefined ) {
assert . deepEqual ( await readJson ( join ( "components" , name , ".codex-plugin" , "plugin.json" ) ) , expectedManifest ) ;
continue ;
}
await assert . rejects (
readFile ( join ( root , "components" , name , ".codex-plugin" , "plugin.json" ) , "utf8" ) ,
/code: 'ENOENT'|ENOENT/ ,
) ;
}
} ) ;
test ( "#given bundled Codex agents #when components/ultrawork/agents directory is scanned #then planner support TOMLs are present and match expected schema keys" , async ( ) => {
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" ,
"metis.toml" ,
"momus.toml" ,
"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 ) ;
}
} ) ;
test ( "#given synced skills with Codex compatibility guidance #when a bundled agent_type is referenced #then a matching TOML is bundled" , async ( ) => {
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 ( ) ;
assert . deepEqual ( expected , [ "explorer" , "librarian" , "metis" , "momus" , "plan" ] ) ;
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 ` ) ;
}
} ) ;