()
| 51 | } |
| 52 | |
| 53 | protected async runMainLoop(): Promise<void> { |
| 54 | const session = this.session; |
| 55 | const messageBuffer = this.messageBuffer; |
| 56 | |
| 57 | const { server: happyServer, mcpServers } = await buildHapiMcpBridge(session.client); |
| 58 | this.happyServer = happyServer; |
| 59 | |
| 60 | const backend = createCursorAcpBackend({ cwd: session.path, model: session.model }); |
| 61 | this.backend = backend; |
| 62 | |
| 63 | backend.setUsageUpdateListener((message) => this.handleAgentMessage(message)); |
| 64 | |
| 65 | backend.onStderrError((error) => { |
| 66 | logger.debug('[cursor-acp] stderr error', error); |
| 67 | session.sendSessionEvent({ type: 'message', message: error.message }); |
| 68 | messageBuffer.addMessage(error.message, 'status'); |
| 69 | }); |
| 70 | |
| 71 | try { |
| 72 | await backend.initialize(); |
| 73 | } catch (error) { |
| 74 | const errMsg = error instanceof Error ? error.message : String(error); |
| 75 | throw new Error(`${CURSOR_ACP_REQUIRED_MESSAGE} (${errMsg})`); |
| 76 | } |
| 77 | |
| 78 | await backend.authenticateIfAvailable('cursor_login'); |
| 79 | |
| 80 | const extensionAdapter = new CursorExtensionAdapter( |
| 81 | session.client, |
| 82 | backend, |
| 83 | (message) => this.handleAgentMessage(message) |
| 84 | ); |
| 85 | this.extensionAdapter = extensionAdapter; |
| 86 | |
| 87 | this.permissionAdapter = new PermissionAdapter( |
| 88 | session.client, |
| 89 | backend, |
| 90 | () => session.getPermissionMode(), |
| 91 | (response) => extensionAdapter.handlePermissionResponse(response) |
| 92 | ); |
| 93 | |
| 94 | const resumeSessionId = session.sessionId; |
| 95 | const mcpServerList = toAcpMcpServers(mcpServers); |
| 96 | let acpSessionId: string; |
| 97 | |
| 98 | if (resumeSessionId && backend.supportsLoadSession()) { |
| 99 | // Register pending cursorSessionId before awaiting session/load (Zed PR #54431). |
| 100 | session.onSessionFoundWithProtocol(resumeSessionId, 'acp'); |
| 101 | try { |
| 102 | acpSessionId = await backend.loadSession({ |
| 103 | sessionId: resumeSessionId, |
| 104 | cwd: session.path, |
| 105 | mcpServers: mcpServerList |
| 106 | }); |
| 107 | } catch (error) { |
| 108 | logger.warn('[cursor-acp] session/load failed', error); |
| 109 | throw new Error( |
| 110 | 'Failed to resume Cursor ACP session. Legacy stream-json sessions cannot be loaded via ACP.' |
nothing calls this directly
no test coverage detected