[codex] restore Codex session history#536
Conversation
There was a problem hiding this comment.
Findings
- [Major] Local Codex resume replays already-imported transcript history —
runCodeximports the transcript before starting the loop when--hapi-import-historyis set, but the local launcher also passes that same flag to the scanner. Terminalhapi codex resume ... --hapi-import-history, and web resumes that later switch to local mode, will emit the persisted transcript into the HAPI session a second time. Evidencecli/src/codex/runCodex.ts:76,cli/src/codex/codexLocalLauncher.ts:73.
Suggested fix:const createdScanner = await createCodexSessionScanner({ transcriptPath, replayExistingEvents: false, onSessionId: (sessionId) => { session.onSessionFound(sessionId); }, onEvent: (event) => { // only newly appended transcript events are forwarded } });
- [Major] Session picker can resume Codex history in the wrong working directory — the selected Codex session id is sent with whatever
trimmedDirectorycurrently contains, even though the selected session summary already carries its originalpath. That can restore a thread from repo A while running future tools in repo B. Evidenceweb/src/components/NewSession/index.tsx:310.
Suggested fix:const handleCodexSessionSelect = useCallback((sessionId: string) => { setSelectedCodexSessionId(sessionId) const selected = codexSessionsState.sessions.find((session) => session.id === sessionId) if (selected?.path) { setDirectory(selected.path) } }, [codexSessionsState.sessions]) // ... onSelectSession={handleCodexSessionSelect}
Summary
- Review mode: initial
- Found two correctness regressions in the new Codex history restore flow: duplicate imported messages during local replay, and possible cwd/session mismatch from the web picker.
Testing
- Not run (automation). Suggested coverage: a local Codex resume with
--hapi-import-historyasserting no duplicate imported messages when the scanner starts, and a web NewSession selection test asserting selected Codex session path populates the spawn directory.
HAPI Bot
| } | ||
| const createdScanner = await createCodexSessionScanner({ | ||
| transcriptPath, | ||
| replayExistingEvents: session.importHistory, |
There was a problem hiding this comment.
[MAJOR] runCodex already imports the transcript before the loop starts when --hapi-import-history is set, so passing the same flag into the local scanner makes it replay the same persisted JSONL again. This duplicates the restored conversation for terminal resumes, and also after a web-restored session switches to local mode.
Suggested fix:
const createdScanner = await createCodexSessionScanner({
transcriptPath,
replayExistingEvents: false,
onSessionId: (sessionId) => {
session.onSessionFound(sessionId);
},
onEvent: (event) => {
// forward newly appended transcript events only
}
});| sessionType, | ||
| worktreeName: sessionType === 'worktree' ? (worktreeName.trim() || undefined) : undefined | ||
| worktreeName: sessionType === 'worktree' ? (worktreeName.trim() || undefined) : undefined, | ||
| resumeSessionId: agent === 'codex' && selectedCodexSessionId ? selectedCodexSessionId : undefined, |
There was a problem hiding this comment.
[MAJOR] Selecting a Codex session only sets resumeSessionId; the spawn still uses the current trimmedDirectory. Since the selected session summary includes its original path, this can restore a thread from one repo while future Codex turns run in another repo.
Suggested fix:
const handleCodexSessionSelect = useCallback((sessionId: string) => {
setSelectedCodexSessionId(sessionId)
const selected = codexSessionsState.sessions.find((session) => session.id === sessionId)
if (selected?.path) {
setDirectory(selected.path)
}
}, [codexSessionsState.sessions])
// ...
onSelectSession={handleCodexSessionSelect}
Summary
Restores existing Codex sessions with transcript history instead of starting with an empty chat when resuming from the web session picker.
Changes
--hapi-import-history.Validation
bun run test:cli -- src/codex/importHistory.test.ts src/modules/common/codexSessions.test.ts src/codex/utils/codexSessionScanner.test.ts src/commands/codex.test.ts src/runner/buildCliArgs.test.ts src/codex/utils/codexUsage.test.tsbun typecheck