修复错误bug
This commit is contained in:
@@ -439,17 +439,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
});
|
||||
|
||||
// Debug logging
|
||||
useEffect(() => {
|
||||
console.log('[ClaudeCodeSession] State update:', {
|
||||
projectPath,
|
||||
session,
|
||||
extractedSessionInfo,
|
||||
effectiveSession,
|
||||
messagesCount: messages.length,
|
||||
isLoading
|
||||
});
|
||||
}, [projectPath, session, extractedSessionInfo, effectiveSession, messages.length, isLoading]);
|
||||
|
||||
// Load session history if resuming
|
||||
useEffect(() => {
|
||||
if (session) {
|
||||
@@ -479,7 +468,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
if (tabId && projectPath && !session) {
|
||||
// Only update for new sessions (not resumed sessions)
|
||||
// This ensures the path is saved when user selects/enters it
|
||||
console.log('[ClaudeCodeSession] Syncing projectPath to tab:', { tabId, projectPath });
|
||||
updateTab(tabId, {
|
||||
initialProjectPath: projectPath
|
||||
});
|
||||
@@ -571,7 +559,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
|
||||
if (activeSession) {
|
||||
// Session is still active, reconnect to its stream
|
||||
console.log('[ClaudeCodeSession] Found active session, reconnecting:', session.id);
|
||||
// IMPORTANT: Set claudeSessionId before reconnecting
|
||||
setClaudeSessionId(session.id);
|
||||
|
||||
@@ -588,11 +575,9 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
};
|
||||
|
||||
const reconnectToSession = async (sessionId: string) => {
|
||||
console.log('[ClaudeCodeSession] Reconnecting to session:', sessionId);
|
||||
|
||||
// Prevent duplicate listeners
|
||||
if (isListeningRef.current) {
|
||||
console.log('[ClaudeCodeSession] Already listening to session, skipping reconnect');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -609,7 +594,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
// Set up session-specific listeners
|
||||
const outputUnlisten = await listen<string>(`claude-output:${sessionId}`, async (event) => {
|
||||
try {
|
||||
console.log('[ClaudeCodeSession] Received claude-output on reconnect:', event.payload);
|
||||
|
||||
if (!isMountedRef.current) return;
|
||||
|
||||
@@ -632,7 +616,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
});
|
||||
|
||||
const completeUnlisten = await listen<boolean>(`claude-complete:${sessionId}`, async (event) => {
|
||||
console.log('[ClaudeCodeSession] Received claude-complete on reconnect:', event.payload);
|
||||
if (isMountedRef.current) {
|
||||
setIsLoading(false);
|
||||
hasActiveSessionRef.current = false;
|
||||
@@ -668,7 +651,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
};
|
||||
|
||||
const handleSendPrompt = async (prompt: string, model: "sonnet" | "opus" | "opus-plan") => {
|
||||
console.log('[ClaudeCodeSession] handleSendPrompt called with:', { prompt, model, projectPath, claudeSessionId, effectiveSession });
|
||||
|
||||
if (!projectPath) {
|
||||
setError(t('app.selectProjectFirst'));
|
||||
@@ -718,13 +700,11 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
// generic ones to prevent duplicate handling.
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
console.log('[ClaudeCodeSession] Setting up generic event listeners first');
|
||||
|
||||
let currentSessionId: string | null = claudeSessionId || effectiveSession?.id || null;
|
||||
|
||||
// Helper to attach session-specific listeners **once we are sure**
|
||||
const attachSessionSpecificListeners = async (sid: string) => {
|
||||
console.log('[ClaudeCodeSession] Attaching session-specific listeners for', sid);
|
||||
|
||||
const specificOutputUnlisten = await listen<string>(`claude-output:${sid}`, (evt) => {
|
||||
handleStreamMessage(evt.payload);
|
||||
@@ -736,7 +716,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
});
|
||||
|
||||
const specificCompleteUnlisten = await listen<boolean>(`claude-complete:${sid}`, (evt) => {
|
||||
console.log('[ClaudeCodeSession] Received claude-complete (scoped):', evt.payload);
|
||||
processComplete(evt.payload);
|
||||
});
|
||||
|
||||
@@ -754,7 +733,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
const msg = JSON.parse(event.payload) as ClaudeStreamMessage;
|
||||
if (msg.type === 'system' && msg.subtype === 'init' && msg.session_id) {
|
||||
if (!currentSessionId || currentSessionId !== msg.session_id) {
|
||||
console.log('[ClaudeCodeSession] Detected new session_id from generic listener:', msg.session_id);
|
||||
currentSessionId = msg.session_id;
|
||||
setClaudeSessionId(msg.session_id);
|
||||
|
||||
@@ -962,7 +940,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
});
|
||||
|
||||
const genericCompleteUnlisten = await listen<boolean>('claude-complete', (evt) => {
|
||||
console.log('[ClaudeCodeSession] Received claude-complete (generic):', evt.payload);
|
||||
processComplete(evt.payload);
|
||||
});
|
||||
|
||||
@@ -1029,12 +1006,10 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
|
||||
// Execute the appropriate command
|
||||
if (effectiveSession && !isFirstPrompt) {
|
||||
console.log('[ClaudeCodeSession] Resuming session:', effectiveSession.id);
|
||||
trackEvent.sessionResumed(effectiveSession.id);
|
||||
trackEvent.modelSelected(model);
|
||||
await api.resumeClaudeCode(projectPath, effectiveSession.id, prompt, model);
|
||||
} else {
|
||||
console.log('[ClaudeCodeSession] Starting new session');
|
||||
setIsFirstPrompt(false);
|
||||
trackEvent.sessionCreated(model, 'prompt_input');
|
||||
trackEvent.modelSelected(model);
|
||||
@@ -1329,7 +1304,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
};
|
||||
|
||||
const handlePreviewUrlChange = (url: string) => {
|
||||
console.log('[ClaudeCodeSession] Preview URL changed to:', url);
|
||||
openLayoutPreview(url);
|
||||
};
|
||||
|
||||
@@ -1338,7 +1312,6 @@ export const ClaudeCodeSession: React.FC<ClaudeCodeSessionProps> = ({
|
||||
isMountedRef.current = true;
|
||||
|
||||
return () => {
|
||||
console.log('[ClaudeCodeSession] Component unmounting, cleaning up listeners');
|
||||
isMountedRef.current = false;
|
||||
isListeningRef.current = false;
|
||||
|
||||
|
||||
@@ -245,8 +245,6 @@ const FloatingPromptInputInner = (
|
||||
|
||||
// Extract image paths from prompt text
|
||||
const extractImagePaths = (text: string): string[] => {
|
||||
console.log('[extractImagePaths] Input text length:', text.length);
|
||||
|
||||
// Updated regex to handle both quoted and unquoted paths
|
||||
// Pattern 1: @"path with spaces or data URLs" - quoted paths
|
||||
// Pattern 2: @path - unquoted paths (continues until @ or end)
|
||||
@@ -257,11 +255,9 @@ const FloatingPromptInputInner = (
|
||||
|
||||
// First, extract quoted paths (including data URLs)
|
||||
let matches = Array.from(text.matchAll(quotedRegex));
|
||||
console.log('[extractImagePaths] Quoted matches:', matches.length);
|
||||
|
||||
for (const match of matches) {
|
||||
const path = match[1]; // No need to trim, quotes preserve exact path
|
||||
console.log('[extractImagePaths] Processing quoted path:', path.startsWith('data:') ? 'data URL' : path);
|
||||
|
||||
// For data URLs, use as-is; for file paths, convert to absolute
|
||||
const fullPath = path.startsWith('data:')
|
||||
@@ -278,15 +274,12 @@ const FloatingPromptInputInner = (
|
||||
|
||||
// Then extract unquoted paths (typically file paths)
|
||||
matches = Array.from(textWithoutQuoted.matchAll(unquotedRegex));
|
||||
console.log('[extractImagePaths] Unquoted matches:', matches.length);
|
||||
|
||||
for (const match of matches) {
|
||||
const path = match[1].trim();
|
||||
// Skip if it looks like a data URL fragment (shouldn't happen with proper quoting)
|
||||
if (path.includes('data:')) continue;
|
||||
|
||||
console.log('[extractImagePaths] Processing unquoted path:', path);
|
||||
|
||||
// Convert relative path to absolute if needed
|
||||
const fullPath = path.startsWith('/') ? path : (projectPath ? `${projectPath}/${path}` : path);
|
||||
|
||||
@@ -295,16 +288,12 @@ const FloatingPromptInputInner = (
|
||||
}
|
||||
}
|
||||
|
||||
const uniquePaths = Array.from(pathsSet);
|
||||
console.log('[extractImagePaths] Final extracted paths (unique):', uniquePaths.length);
|
||||
return uniquePaths;
|
||||
return Array.from(pathsSet);
|
||||
};
|
||||
|
||||
// Update embedded images when prompt changes
|
||||
useEffect(() => {
|
||||
console.log('[useEffect] Prompt changed:', prompt);
|
||||
const imagePaths = extractImagePaths(prompt);
|
||||
console.log('[useEffect] Setting embeddedImages to:', imagePaths);
|
||||
setEmbeddedImages(imagePaths);
|
||||
}, [prompt, projectPath]);
|
||||
|
||||
@@ -422,7 +411,6 @@ const FloatingPromptInputInner = (
|
||||
(newCursorPosition > 1 && /\s/.test(newValue[newCursorPosition - 2]));
|
||||
|
||||
if (isStartOfCommand) {
|
||||
console.log('[FloatingPromptInput] / detected for slash command');
|
||||
setShowSlashCommandPicker(true);
|
||||
setSlashCommandQuery("");
|
||||
setCursorPosition(newCursorPosition);
|
||||
@@ -431,7 +419,6 @@ const FloatingPromptInputInner = (
|
||||
|
||||
// Check if @ was just typed
|
||||
if (projectPath?.trim() && newValue.length > prompt.length && newValue[newCursorPosition - 1] === '@') {
|
||||
console.log('[FloatingPromptInput] @ detected, projectPath:', projectPath);
|
||||
setShowFilePicker(true);
|
||||
setFilePickerQuery("");
|
||||
setCursorPosition(newCursorPosition);
|
||||
|
||||
@@ -54,21 +54,6 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
const rows = Math.max(24, Math.floor(availableHeight / lineHeight));
|
||||
|
||||
// 计算实际使用的宽度
|
||||
const usedWidth = cols * charWidth;
|
||||
const unusedWidth = availableWidth - usedWidth;
|
||||
const percentUsed = ((usedWidth / availableWidth) * 100).toFixed(1);
|
||||
|
||||
console.log('[Terminal] Size calculation:', {
|
||||
containerWidth: rect.width,
|
||||
availableWidth,
|
||||
charWidth,
|
||||
cols,
|
||||
usedWidth,
|
||||
unusedWidth,
|
||||
percentUsed: `${percentUsed}%`,
|
||||
message: unusedWidth > 10 ? `还有 ${unusedWidth.toFixed(1)}px 未使用` : '宽度使用正常'
|
||||
});
|
||||
|
||||
return { cols, rows };
|
||||
}, []);
|
||||
|
||||
@@ -87,10 +72,6 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
if (dims.actualCellWidth) actualCharWidth = dims.actualCellWidth;
|
||||
if (dims.actualCellHeight) actualLineHeight = dims.actualCellHeight;
|
||||
|
||||
console.log('[Terminal] Using actual char dimensions:', {
|
||||
actualCharWidth,
|
||||
actualLineHeight
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// 使用默认值
|
||||
@@ -108,22 +89,8 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
const newRows = Math.max(24, Math.floor(availableHeight / actualLineHeight));
|
||||
|
||||
// 计算宽度使用情况
|
||||
const usedWidth = newCols * actualCharWidth;
|
||||
const unusedWidth = availableWidth - usedWidth;
|
||||
const percentUsed = ((usedWidth / availableWidth) * 100).toFixed(1);
|
||||
|
||||
// 只有当尺寸真的改变时才调整
|
||||
if (newCols !== terminalSize.cols || newRows !== terminalSize.rows) {
|
||||
console.log('[Terminal] Resizing:', {
|
||||
from: terminalSize,
|
||||
to: { cols: newCols, rows: newRows },
|
||||
containerWidth: rect.width,
|
||||
availableWidth,
|
||||
usedWidth,
|
||||
unusedWidth,
|
||||
percentUsed: `${percentUsed}%`
|
||||
});
|
||||
|
||||
setTerminalSize({ cols: newCols, rows: newRows });
|
||||
xtermRef.current.resize(newCols, newRows);
|
||||
|
||||
@@ -163,7 +130,6 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
|
||||
const initializeTerminal = async () => {
|
||||
try {
|
||||
console.log('[Terminal] Initializing...');
|
||||
isInitializedRef.current = true;
|
||||
|
||||
// 先计算初始尺寸
|
||||
@@ -247,23 +213,11 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
const actualLineHeight = dims.actualCellHeight || dims.scaledCellHeight;
|
||||
|
||||
if (actualCharWidth && actualLineHeight) {
|
||||
console.log('[Terminal] Actual character dimensions:', {
|
||||
charWidth: actualCharWidth,
|
||||
lineHeight: actualLineHeight
|
||||
});
|
||||
|
||||
// 使用实际尺寸重新计算
|
||||
const rect = terminalRef.current.getBoundingClientRect();
|
||||
const availableWidth = rect.width - 2;
|
||||
const newCols = Math.floor(availableWidth / actualCharWidth);
|
||||
|
||||
console.log('[Terminal] Recalculating with actual dimensions:', {
|
||||
availableWidth,
|
||||
actualCharWidth,
|
||||
newCols,
|
||||
currentCols: xtermRef.current.cols
|
||||
});
|
||||
|
||||
if (newCols > xtermRef.current.cols) {
|
||||
xtermRef.current.resize(newCols, xtermRef.current.rows);
|
||||
setTerminalSize({ cols: newCols, rows: xtermRef.current.rows });
|
||||
@@ -279,7 +233,6 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
|
||||
// 如果没有有效的 projectPath,跳过创建终端会话
|
||||
if (!projectPath || projectPath.trim() === '') {
|
||||
console.log('[Terminal] Skipping session creation - no project path');
|
||||
if (xtermRef.current) {
|
||||
xtermRef.current.write('\r\n\x1b[33mNo project directory selected. Please select a project to use the terminal.\x1b[0m\r\n');
|
||||
}
|
||||
@@ -315,8 +268,6 @@ export const Terminal: React.FC<TerminalProps> = ({
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[Terminal] Initialized with session:', newSessionId);
|
||||
|
||||
} catch (error) {
|
||||
console.error('[Terminal] Failed to initialize:', error);
|
||||
if (xtermRef.current && isMounted) {
|
||||
|
||||
Reference in New Issue
Block a user