mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-18 20:59:49 +00:00
fix(codex): defer session persistence until user activity
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { logger } from '@/ui/logger';
|
||||
import { resolve } from 'node:path';
|
||||
import { startHookServer } from '@/claude/utils/startHookServer';
|
||||
import { codexLocal } from './codexLocal';
|
||||
import type { ReasoningEffort } from './appServerTypes';
|
||||
@@ -6,9 +7,10 @@ import { CodexSession } from './session';
|
||||
import { createCodexSessionScanner, type CodexSessionScanner } from './utils/codexSessionScanner';
|
||||
import { convertCodexEvent } from './utils/codexEventConverter';
|
||||
import { buildHapiMcpBridge } from './utils/buildHapiMcpBridge';
|
||||
import { stripCodexCliOverrides } from './utils/codexCliOverrides';
|
||||
import { parseCodexCliOverrides, stripCodexCliOverrides } from './utils/codexCliOverrides';
|
||||
import { buildCodexPermissionModeCliArgs } from './utils/permissionModeConfig';
|
||||
import { BaseLocalLauncher } from '@/modules/common/launcher/BaseLocalLauncher';
|
||||
import { createCodexTranscriptLocator, type CodexTranscriptLocator } from './utils/codexTranscriptLocator';
|
||||
|
||||
export async function codexLocalLauncher(session: CodexSession): Promise<'switch' | 'exit'> {
|
||||
const resumeSessionId = session.sessionId;
|
||||
@@ -18,6 +20,7 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
let hookReady = false;
|
||||
let shuttingDown = false;
|
||||
let pendingScannerSetup: Promise<void> | null = null;
|
||||
let transcriptLocator: CodexTranscriptLocator | null = null;
|
||||
const permissionMode = session.getPermissionMode();
|
||||
const managedPermissionMode = permissionMode === 'read-only' || permissionMode === 'safe-yolo' || permissionMode === 'yolo'
|
||||
? permissionMode
|
||||
@@ -28,6 +31,8 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
...stripCodexCliOverrides(session.codexArgs)
|
||||
]
|
||||
: session.codexArgs;
|
||||
const cwdOverride = parseCodexCliOverrides(session.codexArgs).cwd;
|
||||
const effectiveCodexCwd = cwdOverride ? resolve(session.path, cwdOverride) : session.path;
|
||||
|
||||
// Start hapi hub for MCP bridge (same as remote mode)
|
||||
const { server: happyServer, mcpServers } = await buildHapiMcpBridge(session.client);
|
||||
@@ -103,6 +108,8 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
}
|
||||
if (converted?.userMessage) {
|
||||
session.sendUserMessage(converted.userMessage);
|
||||
} else if (converted?.userActivity) {
|
||||
session.notifyUserActivity();
|
||||
}
|
||||
if (converted?.message) {
|
||||
session.sendAgentMessage(converted.message);
|
||||
@@ -142,6 +149,12 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
const hookSource = typeof data.source === 'string' ? data.source : null;
|
||||
const shouldAllowSessionSwitch = hookSource === 'clear';
|
||||
|
||||
if (transcriptPath) {
|
||||
const activeLocator = transcriptLocator;
|
||||
transcriptLocator = null;
|
||||
void activeLocator?.cleanup();
|
||||
}
|
||||
|
||||
if (!transcriptPath) {
|
||||
handleSessionFound(sessionId, shouldAllowSessionSwitch);
|
||||
return;
|
||||
@@ -160,6 +173,27 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
});
|
||||
logger.debug(`[codex-local]: Started Codex SessionStart hook server on port ${hookServer.port}`);
|
||||
|
||||
if (session.client.isPending()) {
|
||||
const createdLocator = createCodexTranscriptLocator({
|
||||
cwd: effectiveCodexCwd,
|
||||
startupTimestampMs: Date.now(),
|
||||
resumeSessionId,
|
||||
onLocated: ({ sessionId, transcriptPath }) => {
|
||||
if (shuttingDown || hookReady || primaryTranscriptPath) {
|
||||
return;
|
||||
}
|
||||
transcriptLocator = null;
|
||||
bindPrimarySession(sessionId, transcriptPath);
|
||||
},
|
||||
onAmbiguous: (paths) => {
|
||||
transcriptLocator = null;
|
||||
logger.warn(`[codex-local]: Transcript fallback was ambiguous (${paths.length} active candidates)`);
|
||||
}
|
||||
});
|
||||
transcriptLocator = createdLocator;
|
||||
await createdLocator.ready;
|
||||
}
|
||||
|
||||
const launcher = new BaseLocalLauncher({
|
||||
label: 'codex-local',
|
||||
failureLabel: 'Local Codex process failed',
|
||||
@@ -204,6 +238,9 @@ export async function codexLocalLauncher(session: CodexSession): Promise<'switch
|
||||
shuttingDown = true;
|
||||
session.removeTranscriptPathCallback(handleTranscriptPathCallback);
|
||||
hookServer.stop();
|
||||
const activeLocator = transcriptLocator;
|
||||
transcriptLocator = null;
|
||||
void activeLocator?.cleanup();
|
||||
if (pendingScannerSetup) {
|
||||
await pendingScannerSetup;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user