fix: migrate codex context off agents injection

This commit is contained in:
Alex Newman
2026-05-06 14:24:40 -07:00
parent bb3dbfdb5a
commit 156062170d
4 changed files with 78 additions and 16 deletions
@@ -4,9 +4,11 @@ import { execFileSync, spawnSync } from 'child_process';
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { logger } from '../../utils/logger.js';
import { paths } from '../../shared/paths.js';
const CODEX_DIR = path.join(homedir(), '.codex');
const CODEX_AGENTS_MD_PATH = path.join(CODEX_DIR, 'AGENTS.md');
const CODEX_TRANSCRIPT_WATCH_CONFIG_PATH = paths.transcriptsConfig();
const MARKETPLACE_NAME = 'claude-mem-local';
const MIN_CODEX_MARKETPLACE_VERSION = '0.128.0';
const REQUIRED_MARKETPLACE_FILES = [
@@ -172,6 +174,46 @@ function readAndStripContextTags(startTag: string, endTag: string): void {
const cleanupLegacyCodexAgentsMdContext = removeCodexAgentsMdContext;
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
function isCodexTranscriptWatch(watch: Record<string, unknown>): boolean {
if (watch.name === 'codex' || watch.schema === 'codex') return true;
return typeof watch.path === 'string'
&& watch.path.includes('.codex')
&& watch.path.includes('sessions');
}
function disableCodexTranscriptAgentsContext(): boolean {
if (!existsSync(CODEX_TRANSCRIPT_WATCH_CONFIG_PATH)) return true;
try {
const parsed = JSON.parse(readFileSync(CODEX_TRANSCRIPT_WATCH_CONFIG_PATH, 'utf-8')) as unknown;
if (!isRecord(parsed) || !Array.isArray(parsed.watches)) return true;
let changed = false;
for (const watch of parsed.watches) {
if (!isRecord(watch) || !isCodexTranscriptWatch(watch)) continue;
if (!isRecord(watch.context) || watch.context.mode !== 'agents') continue;
delete watch.context;
changed = true;
}
if (changed) {
writeFileSync(CODEX_TRANSCRIPT_WATCH_CONFIG_PATH, `${JSON.stringify(parsed, null, 2)}\n`);
console.log(` Disabled legacy Codex transcript AGENTS.md context in ${CODEX_TRANSCRIPT_WATCH_CONFIG_PATH}`);
}
return true;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.warn('WORKER', 'Failed to disable Codex transcript AGENTS.md context', { error: message });
return false;
}
}
const cleanupLegacyCodexTranscriptAgentsContext = disableCodexTranscriptAgentsContext;
export async function installCodexCli(marketplaceRootOverride?: string): Promise<number> {
console.log('\nInstalling Claude-Mem for Codex CLI (native hooks)...\n');
@@ -190,6 +232,9 @@ export async function installCodexCli(marketplaceRootOverride?: string): Promise
if (!cleanupLegacyCodexAgentsMdContext()) {
console.warn(` Native Codex hooks registered, but failed to remove legacy AGENTS.md context from ${CODEX_AGENTS_MD_PATH}.`);
}
if (!cleanupLegacyCodexTranscriptAgentsContext()) {
console.warn(` Native Codex hooks registered, but failed to disable legacy transcript AGENTS.md context in ${CODEX_TRANSCRIPT_WATCH_CONFIG_PATH}.`);
}
console.log(`
Installation complete!
@@ -235,6 +280,10 @@ export function uninstallCodexCli(): number {
console.error(`\nFailed to remove legacy AGENTS.md context from ${CODEX_AGENTS_MD_PATH}.`);
failed = true;
}
if (!cleanupLegacyCodexTranscriptAgentsContext()) {
console.error(`\nFailed to disable legacy transcript AGENTS.md context in ${CODEX_TRANSCRIPT_WATCH_CONFIG_PATH}.`);
failed = true;
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error(`\nLegacy AGENTS.md cleanup failed: ${message}`);
+1 -6
View File
@@ -79,7 +79,6 @@ const CODEX_SAMPLE_SCHEMA: TranscriptSchema = {
},
{
name: 'session-end',
// TODO(#2249): delete watcher when Codex hook lifecycle migration ships
match: { path: 'payload.type', in: ['turn_aborted', 'turn_completed', 'task_complete'] },
action: 'session_end'
}
@@ -96,11 +95,7 @@ export const SAMPLE_CONFIG: TranscriptWatchConfig = {
name: 'codex',
path: '~/.codex/sessions/**/*.jsonl',
schema: 'codex',
startAtEnd: true,
context: {
mode: 'agents',
updateOn: ['session_start', 'session_end']
}
startAtEnd: true
}
],
stateFile: DEFAULT_STATE_PATH