fix(codex): make mem-search MCP startup self-locating
This commit is contained in:
@@ -37,8 +37,12 @@ describe('Plugin Distribution - Skills', () => {
|
||||
describe('Plugin Distribution - Required Files', () => {
|
||||
const requiredFiles = [
|
||||
'plugin/hooks/hooks.json',
|
||||
'plugin/hooks/codex-hooks.json',
|
||||
'plugin/.claude-plugin/plugin.json',
|
||||
'plugin/.codex-plugin/plugin.json',
|
||||
'plugin/.mcp.json',
|
||||
'plugin/skills/mem-search/SKILL.md',
|
||||
'.agents/plugins/marketplace.json',
|
||||
];
|
||||
|
||||
for (const filePath of requiredFiles) {
|
||||
@@ -49,6 +53,25 @@ describe('Plugin Distribution - Required Files', () => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('Plugin Distribution - Codex Marketplace', () => {
|
||||
it('points Codex at the bundled plugin root', () => {
|
||||
const marketplacePath = path.join(projectRoot, '.agents/plugins/marketplace.json');
|
||||
const marketplace = JSON.parse(readFileSync(marketplacePath, 'utf-8'));
|
||||
|
||||
expect(marketplace.plugins[0].source.path).toBe('./plugin');
|
||||
});
|
||||
|
||||
it('MCP launcher can recover without plugin root environment variables', () => {
|
||||
const mcpPath = path.join(projectRoot, 'plugin/.mcp.json');
|
||||
const mcp = JSON.parse(readFileSync(mcpPath, 'utf-8'));
|
||||
const command = mcp.mcpServers['mcp-search'].args.join(' ');
|
||||
|
||||
expect(command).toContain('.codex/plugins/cache/claude-mem-local/claude-mem');
|
||||
expect(command).toContain('.claude/plugins/cache/thedotmack/claude-mem');
|
||||
expect(command).toContain('claude-mem MCP server not found');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Plugin Distribution - hooks.json Integrity', () => {
|
||||
it('should have valid JSON in hooks.json', () => {
|
||||
const hooksPath = path.join(projectRoot, 'plugin/hooks/hooks.json');
|
||||
@@ -108,11 +131,15 @@ describe('Plugin Distribution - hooks.json Integrity', () => {
|
||||
});
|
||||
|
||||
describe('Plugin Distribution - package.json Files Field', () => {
|
||||
it('should include "plugin" in root package.json files field', () => {
|
||||
it('should include bundled plugin entries in root package.json files field', () => {
|
||||
const packageJsonPath = path.join(projectRoot, 'package.json');
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
||||
expect(packageJson.files).toBeDefined();
|
||||
expect(packageJson.files).toContain('plugin');
|
||||
expect(packageJson.files).toContain('plugin/.codex-plugin');
|
||||
expect(packageJson.files).toContain('plugin/.mcp.json');
|
||||
expect(packageJson.files).toContain('plugin/hooks');
|
||||
expect(packageJson.files).toContain('plugin/skills');
|
||||
expect(packageJson.files).toContain('plugin/scripts/*.cjs');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -103,6 +103,13 @@ describe('Install Non-TTY Support', () => {
|
||||
expect(copyRegion).toContain("'.mcp.json'");
|
||||
});
|
||||
|
||||
it('validates the bundled plugin as the Codex marketplace source', () => {
|
||||
expect(codexInstallerSource).toContain("path.join('plugin', '.codex-plugin', 'plugin.json')");
|
||||
expect(codexInstallerSource).toContain("path.join('plugin', '.mcp.json')");
|
||||
expect(codexInstallerSource).toContain("path.join('plugin', 'hooks', 'codex-hooks.json')");
|
||||
expect(codexInstallerSource).toContain("path.join('plugin', 'skills', 'mem-search', 'SKILL.md')");
|
||||
});
|
||||
|
||||
it('does not exclude MCP manifests during local marketplace sync', () => {
|
||||
const gitignoreExcludeRegion = syncMarketplaceSource.slice(
|
||||
syncMarketplaceSource.indexOf('function getGitignoreExcludes'),
|
||||
@@ -116,6 +123,24 @@ describe('Install Non-TTY Support', () => {
|
||||
expect(installSource).toContain('installCodexCli(marketplaceDirectory())');
|
||||
});
|
||||
|
||||
it('refreshes Codex marketplace cache after registration', () => {
|
||||
const installRegion = codexInstallerSource.slice(
|
||||
codexInstallerSource.indexOf('export async function installCodexCli'),
|
||||
codexInstallerSource.indexOf('export function uninstallCodexCli'),
|
||||
);
|
||||
expect(installRegion).toContain("['plugin', 'marketplace', 'upgrade', MARKETPLACE_NAME]");
|
||||
expect(installRegion).toContain('installed plugin cache');
|
||||
});
|
||||
|
||||
it('enables Codex plugin hooks during install', () => {
|
||||
const installRegion = codexInstallerSource.slice(
|
||||
codexInstallerSource.indexOf('export async function installCodexCli'),
|
||||
codexInstallerSource.indexOf('export function uninstallCodexCli'),
|
||||
);
|
||||
expect(installRegion).toContain("['features', 'enable', 'plugin_hooks']");
|
||||
expect(installRegion).toContain('codex features enable plugin_hooks');
|
||||
});
|
||||
|
||||
it('captures Codex CLI output for install failure reporting', () => {
|
||||
const runCodexRegion = codexInstallerSource.slice(
|
||||
codexInstallerSource.indexOf('function runCodex'),
|
||||
|
||||
Reference in New Issue
Block a user