fix: comprehensive community bug fixes - empty repo sync, API error UX, Windows scroll, auth guidance

This commit is contained in:
Jay
2026-04-21 10:58:05 +09:00
parent f8ae0c2a4f
commit 70be9d2c43
+61 -13
View File
@@ -1048,18 +1048,57 @@ class SidebarChatProvider implements vscode.WebviewViewProvider {
// 원격 저장소 추가(오류 무시) 후 fetch & 강제 reset (untracked 파일은 보존됨!)
await execAsync(`git remote remove origin`, { cwd: brainDir }).catch(() => {});
await execAsync(`git remote add origin ${cleanRepo}`, { cwd: brainDir });
await execAsync(`git fetch origin`, { cwd: brainDir });
try {
await execAsync(`git fetch origin`, { cwd: brainDir });
} catch (fetchErr: any) {
// Private 레포 또는 인증 실패 시 사용자 친화적 안내
const msg = fetchErr.message || '';
if (msg.includes('Authentication') || msg.includes('403') || msg.includes('404') || msg.includes('could not read')) {
throw new Error('깃허브 저장소에 접근할 수 없습니다. 저장소가 Public(공개)인지 확인하고, URL이 정확한지 다시 확인해주세요.');
}
throw fetchErr;
}
// 빈 저장소(새로 만든 깃허브 레포)인 경우 graceful 처리
try {
await execAsync(`git reset --hard origin/main`, { cwd: brainDir });
} catch {
await execAsync(`git reset --hard origin/master`, { cwd: brainDir });
try {
await execAsync(`git reset --hard origin/master`, { cwd: brainDir });
} catch {
// 빈 레포지토리 — 브랜치가 아예 없는 경우 (새로 만든 깃허브)
// 로컬에서 첫 커밋을 자동 생성하여 연결 완료
const readmePath = path.join(brainDir, 'README.md');
if (!fs.existsSync(readmePath)) {
fs.writeFileSync(readmePath, '# 🧠 Second Brain\n\nConnect AI 지식 저장소입니다.\n', 'utf-8');
}
await execAsync(`git add .`, { cwd: brainDir });
await execAsync(`git commit -m "Initial commit: Second Brain 초기화"`, { cwd: brainDir });
try {
await execAsync(`git branch -M main`, { cwd: brainDir });
await execAsync(`git push -u origin main`, { cwd: brainDir });
} catch { /* push 실패해도 로컬 연결은 완료 */ }
}
}
// 연동 완료 후 자동으로 지식 모드 ON
this._brainEnabled = true;
this._ctx.globalState.update('brainEnabled', true);
vscode.window.showInformationMessage('🧠 Second Brain 지식 연동 완료!');
this._view.webview.postMessage({ type: 'response', value: '✅ **Second Brain 업데이트 완료! 이제 회원님의 뇌(문서)를 바탕으로 특화된 코딩을 진행합니다.**' });
this._view.webview.postMessage({ type: 'response', value: '✅ **Second Brain 업데이트 완료! 이제 회원님의 뇌(문서)를 바탕으로 특화된 코딩을 진행합니다. (지식 모드: 🟢 ON)**' });
} catch (error: any) {
vscode.window.showErrorMessage(`Second Brain 동기화 실패: ${error.message}`);
this._view.webview.postMessage({ type: 'error', value: `⚠️ 동기화 실패: ${error.message}` });
// 사용자 친화적 에러 메시지 분기
const errMsg = error.message || '';
let userMsg = errMsg;
if (errMsg.includes('not found') || errMsg.includes('does not exist')) {
userMsg = '깃허브 저장소를 찾을 수 없습니다. URL을 다시 확인해주세요.';
} else if (errMsg.includes('Authentication') || errMsg.includes('permission')) {
userMsg = '깃허브 인증에 실패했습니다. 저장소가 Public(공개)인지 확인해주세요.';
}
vscode.window.showErrorMessage(`Second Brain 동기화 실패: ${userMsg}`);
this._view.webview.postMessage({ type: 'error', value: `⚠️ 동기화 실패: ${userMsg}\n\n💡 **해결 방법:**\n1. 깃허브 저장소가 **Public(공개)** 상태인지 확인\n2. URL 형식: \`https://github.com/사용자이름/저장소이름\`\n3. 새로 만든 빈 저장소도 연결 가능합니다!` });
} finally {
this._isSyncingBrain = false;
}
@@ -1388,11 +1427,20 @@ class SidebarChatProvider implements vscode.WebviewViewProvider {
const isLM = ollamaBase.includes('1234') || ollamaBase.includes('v1');
const targetName = isLM ? "LM Studio" : "Ollama";
let errMsg = error.code === 'ECONNREFUSED'
? `⚠️ ${targetName} 서버에 연결할 수 없습니다.\n앱에서 로컬 서버가 켜져 있는지(Start Server) 확인해주세요.`
: (error.response?.status === 400 || error.response?.status === 413)
? `⚠️ 컨텍스트 용량 초과 또거나 지원하지 않는 형식입니다. (에러 400/413) 이미지가 지원되는 Vision 모델인지 확인해주세요.`
: `⚠️ 오류: ${error.message}`;
let errMsg = '';
if (error.code === 'ECONNREFUSED' || error.code === 'ECONNRESET') {
errMsg = `⚠️ ${targetName} 서버에 연결할 수 없습니다.\n\n**해결 방법:**\n1. ${targetName} 앱을 열고 서버가 켜져 있는지(Start Server) 확인\n2. Settings > 모델 기본 URL이 올바른지 확인 (기본: http://127.0.0.1:${isLM ? '1234' : '11434'})`;
} else if (error.response?.status === 400) {
errMsg = `⚠️ 모델 요청 오류 (400)\n\n**원인:** 모델 이름이 올바르지 않거나, 컨텍스트 길이 초과\n**해결:** 좌측 모델 선택 드롭다운에서 정확한 모델을 선택하세요.\n${isLM ? '• LM Studio의 경우 모델을 먼저 로드(Load)한 후 시도하세요.' : '• Ollama: ollama list 로 설치된 모델 확인'}`;
} else if (error.response?.status === 404) {
errMsg = `⚠️ 모델을 찾을 수 없습니다 (404)\n\n**원인:** 선택한 모델이 ${targetName}에 로드되지 않았습니다.\n**해결:** ${isLM ? 'LM Studio에서 해당 모델을 먼저 다운로드 후 Load 해주세요.' : 'ollama pull 모델이름 으로 먼저 다운로드하세요.'}`;
} else if (error.response?.status === 413) {
errMsg = `⚠️ 컨텍스트 용량 초과 (413)\n\n**해결:** 🧠 지식 모드를 일시적으로 OFF 하거나, + 버튼으로 새 대화를 시작하세요.`;
} else if (error.code === 'ETIMEDOUT' || error.message?.includes('timeout')) {
errMsg = `⚠️ AI 응답 시간 초과\n\n모델이 문제를 처리하는 데 시간이 너무 오래 걸렸습니다.\n**해결:** 더 작은 모델을 선택하거나, 질문을 짧게 줄여보세요.`;
} else {
errMsg = `⚠️ 오류: ${error.message}`;
}
this._view.webview.postMessage({ type: 'error', value: errMsg });
@@ -1983,7 +2031,7 @@ body.vscode-light {
--accent-glow:rgba(124,106,255,.1);--accent2-glow:rgba(224,64,251,.08);
--input-bg:rgba(255,255,255,.9);--code-bg:#f5f5f7;
}
html,body{height:100%;font-family:'SF Pro Display',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;font-size:13px;background:var(--bg);color:var(--text);display:flex;flex-direction:column;overflow:hidden}
html,body{height:100%;font-family:'SF Pro Display',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;font-size:13px;background:var(--bg);color:var(--text);display:flex;flex-direction:column;overflow:hidden;min-height:0}
/* AURORA BACKGROUND */
body::before{content:'';position:fixed;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(ellipse at 20% 50%,rgba(124,106,255,.06) 0%,transparent 50%),radial-gradient(ellipse at 80% 20%,rgba(224,64,251,.04) 0%,transparent 50%),radial-gradient(ellipse at 50% 80%,rgba(0,229,255,.03) 0%,transparent 50%);animation:aurora 20s ease-in-out infinite;z-index:0;pointer-events:none}
@@ -2011,7 +2059,7 @@ select:hover,select:focus{border-color:var(--accent);box-shadow:0 0 12px var(--a
.btn-icon:hover::before{opacity:1}
/* CHAT */
.chat{flex:1;overflow-y:auto;padding:16px 14px;display:flex;flex-direction:column;gap:16px;position:relative;z-index:1}
.chat{flex:1;overflow-y:auto;padding:16px 14px;display:flex;flex-direction:column;gap:16px;position:relative;z-index:1;min-height:0}
.chat::-webkit-scrollbar{width:2px}.chat::-webkit-scrollbar-track{background:transparent}.chat::-webkit-scrollbar-thumb{background:var(--accent);border-radius:2px;opacity:.5}
/* MESSAGES */
@@ -2097,7 +2145,7 @@ textarea::placeholder{color:var(--text-dim)}
0%, 100% { box-shadow: 0 0 15px var(--accent-glow); }
50% { box-shadow: 0 0 35px var(--accent2-glow); border-color: var(--accent2); }
}
.main-view{flex:1;display:flex;flex-direction:column;overflow:hidden;transition:all .5s cubic-bezier(.16,1,.3,1)}
.main-view{flex:1;display:flex;flex-direction:column;overflow:hidden;transition:all .5s cubic-bezier(.16,1,.3,1);min-height:0;max-height:100%}
body.init .main-view{justify-content:center;margin-top:-6vh}
body.init .chat{flex:0 0 auto;overflow:visible;padding-bottom:15px}
body.init .input-wrap{max-width:680px;width:100%;margin:0 auto;transform:none;transition:all .5s cubic-bezier(.16,1,.3,1)}