@@ -1190,6 +1190,10 @@ ${prompt}
11901190 let lastAssistantUuid : string | null = null
11911191 const streamIterationStart = Date . now ( )
11921192
1193+ // Plan mode: track ExitPlanMode to stop after plan is complete
1194+ let planCompleted = false
1195+ let exitPlanModeToolCallId : string | null = null
1196+
11931197 if ( isUsingOllama ) {
11941198 console . log ( `[Ollama] ===== STARTING STREAM ITERATION =====` )
11951199 console . log ( `[Ollama] Model: ${ finalCustomConfig ?. model } ` )
@@ -1249,6 +1253,23 @@ ${prompt}
12491253 msgAny . error || msgAny . message || "Unknown SDK error"
12501254 lastError = new Error ( sdkError )
12511255
1256+ // Detailed SDK error logging in main process
1257+ console . error ( `[CLAUDE SDK ERROR] ========================================` )
1258+ console . error ( `[CLAUDE SDK ERROR] Raw error: ${ sdkError } ` )
1259+ console . error ( `[CLAUDE SDK ERROR] Message type: ${ msgAny . type } ` )
1260+ console . error ( `[CLAUDE SDK ERROR] SubChat ID: ${ input . subChatId } ` )
1261+ console . error ( `[CLAUDE SDK ERROR] Chat ID: ${ input . chatId } ` )
1262+ console . error ( `[CLAUDE SDK ERROR] CWD: ${ input . cwd } ` )
1263+ console . error ( `[CLAUDE SDK ERROR] Mode: ${ input . mode } ` )
1264+ console . error ( `[CLAUDE SDK ERROR] Session ID: ${ msgAny . session_id || 'none' } ` )
1265+ console . error ( `[CLAUDE SDK ERROR] Has custom config: ${ ! ! finalCustomConfig } ` )
1266+ console . error ( `[CLAUDE SDK ERROR] Is using Ollama: ${ isUsingOllama } ` )
1267+ console . error ( `[CLAUDE SDK ERROR] Model: ${ resolvedModel || 'default' } ` )
1268+ console . error ( `[CLAUDE SDK ERROR] Has OAuth token: ${ ! ! claudeCodeToken } ` )
1269+ console . error ( `[CLAUDE SDK ERROR] MCP servers: ${ mcpServersFiltered ? Object . keys ( mcpServersFiltered ) . join ( ', ' ) : 'none' } ` )
1270+ console . error ( `[CLAUDE SDK ERROR] Full message:` , JSON . stringify ( msgAny , null , 2 ) )
1271+ console . error ( `[CLAUDE SDK ERROR] ========================================` )
1272+
12521273 // Categorize SDK-level errors
12531274 let errorCategory = "SDK_ERROR"
12541275 let errorContext = "Claude SDK error"
@@ -1381,6 +1402,12 @@ ${prompt}
13811402 // DEBUG: Log tool calls
13821403 console . log ( `[SD] M:TOOL_CALL sub=${ subId } toolName="${ chunk . toolName } " mode=${ input . mode } callId=${ chunk . toolCallId } ` )
13831404
1405+ // Track ExitPlanMode toolCallId so we can stop when it completes
1406+ if ( input . mode === "plan" && chunk . toolName === "ExitPlanMode" ) {
1407+ console . log ( `[SD] M:PLAN_TOOL_DETECTED sub=${ subId } callId=${ chunk . toolCallId } ` )
1408+ exitPlanModeToolCallId = chunk . toolCallId
1409+ }
1410+
13841411 parts . push ( {
13851412 type : `tool-${ chunk . toolName } ` ,
13861413 toolCallId : chunk . toolCallId ,
@@ -1415,6 +1442,13 @@ ${prompt}
14151442 }
14161443 }
14171444 }
1445+
1446+ // Check if ExitPlanMode just completed - stop the stream
1447+ if ( exitPlanModeToolCallId && chunk . toolCallId === exitPlanModeToolCallId ) {
1448+ console . log ( `[SD] M:PLAN_FINISH sub=${ subId } - ExitPlanMode completed, emitting finish` )
1449+ planCompleted = true
1450+ safeEmit ( { type : "finish" } as UIMessageChunk )
1451+ }
14181452 }
14191453 break
14201454 case "message-metadata" :
@@ -1437,12 +1471,23 @@ ${prompt}
14371471 }
14381472 break
14391473 }
1474+
1475+ // Break from chunk loop if plan is done
1476+ if ( planCompleted ) {
1477+ console . log ( `[SD] M:PLAN_BREAK_CHUNK sub=${ subId } ` )
1478+ break
1479+ }
14401480 }
14411481 // Break from stream loop if observer closed (user clicked Stop)
14421482 if ( ! isObservableActive ) {
14431483 console . log ( `[SD] M:OBSERVER_CLOSED_STREAM sub=${ subId } ` )
14441484 break
14451485 }
1486+ // Break from stream loop if plan completed
1487+ if ( planCompleted ) {
1488+ console . log ( `[SD] M:PLAN_BREAK_STREAM sub=${ subId } ` )
1489+ break
1490+ }
14461491 }
14471492
14481493 // Warn if stream yielded no messages (offline mode issue)
0 commit comments