diff --git a/package-lock.json b/package-lock.json index cc7aea6..83cb3be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "connect-ai-lab", - "version": "2.1.22", + "version": "2.1.23", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "connect-ai-lab", - "version": "2.1.22", + "version": "2.1.23", "license": "MIT", "dependencies": { "axios": "^1.15.0", diff --git a/package.json b/package.json index b802e38..f748dca 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "connect-ai-lab", "displayName": "Connect AI", "description": "100% 로컬 AI 코딩 에이전트 — 파일 생성, 코드 편집, 터미널 실행을 오프라인으로. Ollama + Gemma/Llama/DeepSeek 지원.", - "version": "2.1.22", + "version": "2.1.23", "publisher": "connectailab", "license": "MIT", "icon": "assets/icon.png", diff --git a/src/extension.ts b/src/extension.ts index 673d76a..665ee9a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -537,6 +537,9 @@ class SidebarChatProvider implements vscode.WebviewViewProvider { case 'syncBrain': await this._handleBrainMenu(); break; + case 'injectLocalBrain': + await this._handleInjectLocalBrain(msg.files); + break; case 'stopGeneration': if (this._abortController) { this._abortController.abort(); @@ -637,6 +640,59 @@ class SidebarChatProvider implements vscode.WebviewViewProvider { } } + private async _handleInjectLocalBrain(files: any[]) { + if (!this._view) return; + + const wsFolders = vscode.workspace.workspaceFolders; + if (!wsFolders) { + vscode.window.showErrorMessage("워크스페이스가 열려있지 않아 두뇌 연동이 불가능합니다."); + return; + } + + const rootPath = wsFolders[0].uri.fsPath; + const tbPath = path.join(rootPath, '.secondbrain'); + const today = new Date(); + const dateStr = today.getFullYear() + '-' + String(today.getMonth() + 1).padStart(2, '0') + '-' + String(today.getDate()).padStart(2, '0'); + const datePath = path.join(tbPath, '00_Raw', dateStr); + + if (!fs.existsSync(datePath)) { + fs.mkdirSync(datePath, { recursive: true }); + } + + let injectedTitles: string[] = []; + + this._view.webview.postMessage({ type: 'response', value: `🧠 **[P-Reinforce 연동 준비]**\n첨부하신 ${files.length}개의 파일을 로컬 두뇌(\`00_Raw/${dateStr}\`)에 입수하고 자동 푸시를 진행합니다.` }); + + for (const file of files) { + try { + const fileContent = Buffer.from(file.data, 'base64').toString('utf-8'); + const safeTitle = file.name.replace(/[^a-zA-Z0-9가-힣_.-]/gi, '_'); + const filePath = path.join(datePath, safeTitle); + fs.writeFileSync(filePath, fileContent, 'utf-8'); + injectedTitles.push(safeTitle); + } catch (err) { + console.error('Failed to write brain file:', err); + } + } + + const safeTitles = injectedTitles.join(', '); + + try { + const { execSync } = require('child_process'); + execSync(`git add ".secondbrain"`, { cwd: rootPath }); + execSync(`git commit -m "Auto-Inject Knowledge [Raw]: ${safeTitles}"`, { cwd: rootPath }); + execSync(`git push`, { cwd: rootPath }); + + setTimeout(() => { + this.sendPromptFromExtension(`[A.U 지식 주입 완료] 마스터가 '${safeTitles}' 스킬 칩을 내 로컬 두뇌의 \`00_Raw/${dateStr}\` 폴더에 다운로드하고 클라우드 동기화까지 100% 완료했습니다. "데이터가 완벽하게 입수되었습니다. P-Reinforce 구조화를 시작할까요?"라고 대답해라.`); + }, 3000); + } catch(err) { + setTimeout(() => { + this.sendPromptFromExtension(`[A.U 지식 주입 보류] 마스터가 '${safeTitles}' 스킬 칩을 로컬 \`00_Raw/${dateStr}\` 폴더에 저장했으나 깃허브 푸시는 보류되었습니다. "로컬 데이터가 입수되었습니다! P-Reinforce 구조화를 시작할까요?"라고 대답해라.`); + }, 3000); + } + } + // -------------------------------------------------------- // Fetch installed Ollama models // -------------------------------------------------------- @@ -1752,7 +1808,7 @@ body.init .input-wrap{max-width:680px;width:100%;margin:0 auto;transform:none;tr
+