MCPcopy Create free account
hub / github.com/tiann/hapi / codexLocalLauncher

Function codexLocalLauncher

cli/src/codex/codexLocalLauncher.ts:13–220  ·  view source on GitHub ↗
(session: CodexSession)

Source from the content-addressed store, hash-verified

11import { BaseLocalLauncher } from '@/modules/common/launcher/BaseLocalLauncher';
12
13export async function codexLocalLauncher(session: CodexSession): Promise<'switch' | 'exit'> {
14 const resumeSessionId = session.sessionId;
15 let primarySessionId = resumeSessionId;
16 let primaryTranscriptPath: string | null = null;
17 let scanner: CodexSessionScanner | null = null;
18 let hookReady = false;
19 let shuttingDown = false;
20 let pendingScannerSetup: Promise<void> | null = null;
21 const permissionMode = session.getPermissionMode();
22 const managedPermissionMode = permissionMode === 'read-only' || permissionMode === 'safe-yolo' || permissionMode === 'yolo'
23 ? permissionMode
24 : null;
25 const codexArgs = managedPermissionMode
26 ? [
27 ...buildCodexPermissionModeCliArgs(managedPermissionMode),
28 ...stripCodexCliOverrides(session.codexArgs)
29 ]
30 : session.codexArgs;
31
32 // Start hapi hub for MCP bridge (same as remote mode)
33 const { server: happyServer, mcpServers } = await buildHapiMcpBridge(session.client);
34 logger.debug(`[codex-local]: Started hapi MCP bridge server at ${happyServer.url}`);
35
36 const reportTranscriptSyncFailure = (transcriptPath: string, error: unknown): void => {
37 const detail = error instanceof Error ? error.message : String(error);
38 const message = `Codex transcript sync failed for ${transcriptPath}: ${detail}`;
39 logger.warn(`[codex-local]: ${message}`);
40 session.sendSessionEvent({
41 type: 'message',
42 message: `${message} Keeping local Codex running; remote transcript sync is unavailable for this launch.`
43 });
44 };
45
46 const handleSessionFound = (sessionId: string, allowSwitch = false): void => {
47 if (primarySessionId && primarySessionId !== sessionId && !allowSwitch) {
48 logger.debug(`[codex-local]: Ignoring non-primary Codex session id ${sessionId}; primary is ${primarySessionId}`);
49 return;
50 }
51 primarySessionId = sessionId;
52 session.onSessionFound(sessionId);
53 };
54
55 const isPrimarySessionId = (sessionId: string): boolean => {
56 return primarySessionId === null || primarySessionId === sessionId;
57 };
58
59 const bindPrimarySession = (sessionId: string, transcriptPath: string, allowSwitch = false): void => {
60 if (primarySessionId && primarySessionId !== sessionId && !allowSwitch) {
61 logger.debug(`[codex-local]: Ignoring non-primary SessionStart hook ${sessionId}; primary is ${primarySessionId}`);
62 return;
63 }
64 primarySessionId = sessionId;
65 primaryTranscriptPath = transcriptPath;
66 session.onSessionFound(sessionId);
67 hookReady = true;
68 session.onTranscriptPathFound(transcriptPath);
69 };
70

Callers 1

Calls 15

runMethod · 0.95
stripCodexCliOverridesFunction · 0.90
buildHapiMcpBridgeFunction · 0.90
startHookServerFunction · 0.90
codexLocalFunction · 0.90
handleSessionHookFunction · 0.85
debugMethod · 0.80
sendSessionEventMethod · 0.80
resetTranscriptPathMethod · 0.80
stopMethod · 0.65

Tested by

no test coverage detected