@@ -7,7 +7,7 @@ import { ReviewWebviewProvider } from './reviewWebview';
77
88// 💡: Types for IPC communication with MCP server
99interface IPCMessage {
10- type : 'present_review' | 'log' | 'get_selection' ;
10+ type : 'present_review' | 'log' | 'get_selection' | 'response' ;
1111 payload : {
1212 content : string ;
1313 mode : 'replace' | 'update-section' | 'append' ;
@@ -31,7 +31,7 @@ class DaemonClient implements vscode.Disposable {
3131 private context : vscode . ExtensionContext ,
3232 private reviewProvider : ReviewWebviewProvider ,
3333 private outputChannel : vscode . OutputChannel
34- ) { }
34+ ) { }
3535
3636 start ( ) : void {
3737 this . outputChannel . appendLine ( 'Starting daemon client...' ) ;
@@ -56,7 +56,7 @@ class DaemonClient implements vscode.Disposable {
5656
5757 this . socket . on ( 'error' , ( error ) => {
5858 // Only log at debug level to avoid spam during normal startup
59- this . outputChannel . appendLine ( `Daemon connection failed: ${ error . message } (will retry in ${ this . RECONNECT_INTERVAL_MS / 1000 } s)` ) ;
59+ this . outputChannel . appendLine ( `Daemon connection failed: ${ error . message } (will retry in ${ this . RECONNECT_INTERVAL_MS / 1000 } s)` ) ;
6060 this . scheduleReconnect ( ) ;
6161 } ) ;
6262
@@ -73,11 +73,11 @@ class DaemonClient implements vscode.Disposable {
7373
7474 this . socket . on ( 'data' , ( data ) => {
7575 this . buffer += data . toString ( ) ;
76-
76+
7777 // Process all complete messages (ending with \n)
7878 let lines = this . buffer . split ( '\n' ) ;
7979 this . buffer = lines . pop ( ) || '' ; // Keep incomplete line in buffer
80-
80+
8181 for ( const line of lines ) {
8282 if ( line . trim ( ) ) { // Skip empty lines
8383 try {
@@ -100,7 +100,7 @@ class DaemonClient implements vscode.Disposable {
100100 private async handleIncomingMessage ( message : IPCMessage ) : Promise < void > {
101101 // Extract shell PID from message payload for filtering
102102 const shellPid = this . extractShellPidFromMessage ( message ) ;
103-
103+
104104 if ( shellPid ) {
105105 // Check if this message is intended for our VSCode window
106106 const isForOurWindow = await this . isMessageForOurWindow ( shellPid ) ;
@@ -109,7 +109,6 @@ class DaemonClient implements vscode.Disposable {
109109 return ;
110110 }
111111 }
112-
113112 if ( message . type === 'present_review' ) {
114113 try {
115114 const reviewPayload = message . payload as {
@@ -119,51 +118,67 @@ class DaemonClient implements vscode.Disposable {
119118 baseUri ?: string ;
120119 terminal_shell_pid : number ;
121120 } ;
122-
121+
123122 this . reviewProvider . updateReview (
124- reviewPayload . content ,
125- reviewPayload . mode ,
123+ reviewPayload . content ,
124+ reviewPayload . mode ,
126125 reviewPayload . baseUri
127126 ) ;
128127
129128 // Send success response back through daemon
130129 this . sendResponse ( message . id , { success : true } ) ;
131130 } catch ( error ) {
132131 this . outputChannel . appendLine ( `Error handling present_review: ${ error } ` ) ;
133- this . sendResponse ( message . id , {
134- success : false ,
135- error : error instanceof Error ? error . message : String ( error )
132+ this . sendResponse ( message . id , {
133+ success : false ,
134+ error : error instanceof Error ? error . message : String ( error )
136135 } ) ;
137136 }
138137 } else if ( message . type === 'get_selection' ) {
139138 try {
140139 const selectionData = this . getCurrentSelection ( ) ;
141- this . sendResponse ( message . id , {
142- success : true ,
143- data : selectionData
140+ this . sendResponse ( message . id , {
141+ success : true ,
142+ data : selectionData
144143 } ) ;
145144 } catch ( error ) {
146145 this . outputChannel . appendLine ( `Error handling get_selection: ${ error } ` ) ;
147- this . sendResponse ( message . id , {
148- success : false ,
149- error : error instanceof Error ? error . message : String ( error )
146+ this . sendResponse ( message . id , {
147+ success : false ,
148+ error : error instanceof Error ? error . message : String ( error )
150149 } ) ;
151150 }
151+ } else if ( message . type === 'log' ) {
152+ // Handle log messages - no response needed, just display in output channel
153+ try {
154+ const logPayload = message . payload as {
155+ level : string ;
156+ message : string ;
157+ terminal_shell_pid : number ;
158+ } ;
159+
160+ const levelPrefix = logPayload . level . toUpperCase ( ) ;
161+ this . outputChannel . appendLine ( `[${ levelPrefix } ] ${ logPayload . message } ` ) ;
162+ } catch ( error ) {
163+ this . outputChannel . appendLine ( `Error handling log message: ${ error } ` ) ;
164+ }
165+ } else if ( message . type == 'response' ) {
166+ // Ignore this, response messages are messages that WE send to clients.
152167 } else {
153168 this . outputChannel . appendLine ( `Received unknown message type: ${ message . type } ` ) ;
154- this . sendResponse ( message . id , {
155- success : false ,
156- error : `Unknown message type: ${ message . type } `
169+ this . sendResponse ( message . id , {
170+ success : false ,
171+ error : `Unknown message type: ${ message . type } `
157172 } ) ;
158173 }
159174 }
160175
161176 private extractShellPidFromMessage ( message : IPCMessage ) : number | null {
162177 try {
163- if ( message . type === 'present_review' || message . type === 'get_selection' ) {
178+ if ( message . type === 'present_review' || message . type === 'get_selection' || message . type === 'log' ) {
164179 const payload = message . payload as any ;
165180 const shellPid = payload . terminal_shell_pid ;
166-
181+
167182 if ( typeof shellPid === 'number' ) {
168183 return shellPid ;
169184 } else {
@@ -181,7 +196,7 @@ class DaemonClient implements vscode.Disposable {
181196 try {
182197 // Get all terminal PIDs in the current VSCode window
183198 const terminals = vscode . window . terminals ;
184-
199+
185200 for ( const terminal of terminals ) {
186201 try {
187202 const terminalPid = await terminal . processId ;
@@ -193,7 +208,7 @@ class DaemonClient implements vscode.Disposable {
193208 continue ;
194209 }
195210 }
196-
211+
197212 return false ;
198213 } catch ( error ) {
199214 this . outputChannel . appendLine ( `Error checking if message is for our window: ${ error } ` ) ;
@@ -269,13 +284,13 @@ class DaemonClient implements vscode.Disposable {
269284 this . outputChannel . appendLine ( 'Warning: Could not discover VSCode PID, using fallback' ) ;
270285 return crypto . randomUUID ( ) ;
271286 } ) ( ) ;
272-
287+
273288 return `/tmp/dialectic-daemon-${ vscodePid } .sock` ;
274289 }
275290
276291 private scheduleReconnect ( ) : void {
277292 if ( this . isDisposed ) return ;
278-
293+
279294 this . clearReconnectTimer ( ) ;
280295 this . reconnectTimer = setTimeout ( ( ) => {
281296 this . connectToDaemon ( ) ;
@@ -292,12 +307,12 @@ class DaemonClient implements vscode.Disposable {
292307 dispose ( ) : void {
293308 this . isDisposed = true ;
294309 this . clearReconnectTimer ( ) ;
295-
310+
296311 if ( this . socket ) {
297312 this . socket . destroy ( ) ;
298313 this . socket = null ;
299314 }
300-
315+
301316 this . outputChannel . appendLine ( 'Daemon client disposed' ) ;
302317 }
303318}
@@ -495,23 +510,23 @@ function formatSelectionMessage(
495510// 💡: PID Discovery Testing - Log all relevant PIDs for debugging
496511async function logPIDDiscovery ( outputChannel : vscode . OutputChannel ) : Promise < void > {
497512 outputChannel . appendLine ( '=== PID DISCOVERY TESTING ===' ) ;
498-
513+
499514 // Extension process info
500515 outputChannel . appendLine ( `Extension process PID: ${ process . pid } ` ) ;
501516 outputChannel . appendLine ( `Extension parent PID: ${ process . ppid } ` ) ;
502-
517+
503518 // Try to find VSCode PID by walking up the process tree
504519 const vscodePid = findVSCodePID ( outputChannel ) ;
505520 if ( vscodePid ) {
506521 outputChannel . appendLine ( `Found VSCode PID: ${ vscodePid } ` ) ;
507522 } else {
508523 outputChannel . appendLine ( 'Could not find VSCode PID' ) ;
509524 }
510-
525+
511526 // Log terminal PIDs (handle the Promise properly)
512527 const terminals = vscode . window . terminals ;
513528 outputChannel . appendLine ( `Found ${ terminals . length } terminals:` ) ;
514-
529+
515530 for ( let i = 0 ; i < terminals . length ; i ++ ) {
516531 const terminal = terminals [ i ] ;
517532 try {
@@ -522,7 +537,7 @@ async function logPIDDiscovery(outputChannel: vscode.OutputChannel): Promise<voi
522537 outputChannel . appendLine ( ` Terminal ${ i } : name="${ terminal . name } ", PID=<error: ${ error } >` ) ;
523538 }
524539 }
525-
540+
526541 // Set up terminal monitoring
527542 const terminalListener = vscode . window . onDidOpenTerminal ( async ( terminal ) => {
528543 try {
@@ -532,50 +547,50 @@ async function logPIDDiscovery(outputChannel: vscode.OutputChannel): Promise<voi
532547 outputChannel . appendLine ( `NEW TERMINAL: name="${ terminal . name } ", PID=<error: ${ error } >` ) ;
533548 }
534549 } ) ;
535-
550+
536551 outputChannel . appendLine ( '=== END PID DISCOVERY ===' ) ;
537552}
538553
539554// 💡: Attempt to find VSCode PID by walking up process tree
540555function findVSCodePID ( outputChannel : vscode . OutputChannel ) : number | null {
541556 const { execSync } = require ( 'child_process' ) ;
542-
557+
543558 try {
544559 let currentPid = process . pid ;
545-
560+
546561 // Walk up the process tree
547562 for ( let i = 0 ; i < 10 ; i ++ ) { // Safety limit
548563 try {
549564 // Get process info (works on macOS/Linux)
550565 const psOutput = execSync ( `ps -p ${ currentPid } -o pid,ppid,comm,args` , { encoding : 'utf8' } ) ;
551566 const lines = psOutput . trim ( ) . split ( '\n' ) ;
552-
567+
553568 if ( lines . length < 2 ) break ;
554-
569+
555570 const processLine = lines [ 1 ] . trim ( ) ;
556571 const parts = processLine . split ( / \s + / ) ;
557572 const pid = parseInt ( parts [ 0 ] ) ;
558573 const ppid = parseInt ( parts [ 1 ] ) ;
559574 const command = parts . slice ( 3 ) . join ( ' ' ) ; // Full command line
560-
575+
561576 // Check if this looks like the main VSCode process (not helper processes)
562- if ( ( command . includes ( 'Visual Studio Code' ) || command . includes ( 'Code.app' ) || command . includes ( 'Electron' ) )
577+ if ( ( command . includes ( 'Visual Studio Code' ) || command . includes ( 'Code.app' ) || command . includes ( 'Electron' ) )
563578 && ! command . includes ( 'Code Helper' ) ) {
564579 outputChannel . appendLine ( `Found VSCode PID: ${ pid } ` ) ;
565580 return pid ;
566581 }
567-
582+
568583 currentPid = ppid ;
569584 if ( ppid <= 1 ) break ; // Reached init process
570-
585+
571586 } catch ( error ) {
572587 break ;
573588 }
574589 }
575-
590+
576591 outputChannel . appendLine ( 'Could not find VSCode PID in process tree' ) ;
577592 return null ;
578-
593+
579594 } catch ( error ) {
580595 outputChannel . appendLine ( `PID discovery error: ${ error } ` ) ;
581596 return null ;
0 commit comments