From 92c92da090e202ce7645f747b44df22f56744f1e Mon Sep 17 00:00:00 2001 From: g1nation Date: Thu, 11 Jun 2026 17:39:08 +0900 Subject: [PATCH] =?UTF-8?q?feat(onboarding):=20=EB=91=90=EB=87=8C=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EC=9C=84=EC=B9=98=20=EB=B6=80=ED=8A=B8?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=9E=A9=20=E2=80=94=20=EC=84=B1=EC=9E=A5=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=80=EC=9E=A5=EC=B2=98=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=ED=99=94=20(v2.2.217)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 두뇌 미설정 시 config 가 숨김 점폴더(~/.g1nation-brain)로 조용히 폴백해 성장 데이터(레슨·기억·지식)가 비개발자는 찾을 수 없는 곳에 쌓이거나 기능이 멈추던 문제 해결. 설치 컴퓨터마다 저장 위치가 결정적이고 발견 가능해진다. - 활성화 시 brainProfiles/legacy 경로가 모두 비어 있으면: · 문서\AstraBrain 폴더 실제 생성 (lessons/·memory/ + 설명 README) · settings(global) brainProfiles 에 명시 기록 → 설정 UI 에서 보이고 변경 가능 · 사용자 1회 알림 (경로 + 백업 권장) - 데이터 보호: 옛 폴백(~/.g1nation-brain)에 데이터가 이미 있으면 이동 없이 그 경로를 그대로 등록 (유실 방지). - 기존 사용자(프로필/legacy 설정 존재)는 완전 no-op. Co-Authored-By: Claude Opus 4.8 --- package-lock.json | 4 +- package.json | 2 +- src/extension.ts | 6 +++ src/extension/brainBootstrap.ts | 90 +++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/extension/brainBootstrap.ts diff --git a/package-lock.json b/package-lock.json index fd31c37..ff560c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "astra", - "version": "2.2.216", + "version": "2.2.217", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "astra", - "version": "2.2.216", + "version": "2.2.217", "license": "MIT", "dependencies": { "@lmstudio/sdk": "^1.5.0", diff --git a/package.json b/package.json index 1ce7040..bec8ce2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "astra", "displayName": "Astra", "description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.", - "version": "2.2.216", + "version": "2.2.217", "publisher": "g1nation", "license": "MIT", "icon": "assets/icon.png", diff --git a/src/extension.ts b/src/extension.ts index 5562ab3..b6d3de9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -40,6 +40,7 @@ import { runConnectGoogleCalendarIcal, runConnectGoogleCalendarOAuth } from './e import { runInitialSetup } from './extension/initialSetup'; import { startStocksWatcher } from './features/stocks'; import { startDailyBriefingWatcher } from './features/briefing/dailyBriefing'; +import { ensureDefaultBrainConfigured } from './extension/brainBootstrap'; import { registerProviderCommands } from './extension/providerCommands'; import { registerScaffoldCommand } from './extension/scaffoldCommand'; import { registerLessonCommands } from './extension/lessonCommands'; @@ -65,6 +66,11 @@ export async function activate(context: vscode.ExtensionContext) { void vscode.window.showInformationMessage(`📡 Astra v${version} activated (PID=${process.pid})`); logInfo(`Astra activating... version=${version} pid=${process.pid}`); + // 두뇌 기본 위치 부트스트랩 — 미설정이면 문서\AstraBrain 생성·등록. + // 성장 데이터(레슨·기억·지식)가 숨김 폴백(~/.g1nation-brain)으로 조용히 가는 것을 방지. + // 이후 코드가 getConfig() 로 두뇌 경로를 읽으므로 설정 기록이 끝난 뒤 진행해야 한다. + await ensureDefaultBrainConfigured(); + // Initialize Astra Path Resolver (.astra → ConnectAI/.astra/) initAstraPathResolver(context); diff --git a/src/extension/brainBootstrap.ts b/src/extension/brainBootstrap.ts new file mode 100644 index 0000000..984c42a --- /dev/null +++ b/src/extension/brainBootstrap.ts @@ -0,0 +1,90 @@ +/** + * 두뇌(Second Brain) 기본 위치 부트스트랩 — 첫 실행 온보딩. + * + * 문제: 두뇌 미설정 시 config 가 `~/.g1nation-brain`(숨김 점폴더)로 조용히 폴백했다. + * - 폴더가 실제로 생성되지 않고, 설정 UI 에도 보이지 않으며, 숨김 폴더라 + * 비개발자 사용자는 자신의 성장 데이터(레슨·기억·지식)가 어디 쌓이는지 알 수 없다. + * - 컴퓨터마다 위치가 "보이지 않게" 달라져 백업·이전이 불가능했다. + * + * 해결: 활성화 시 두뇌가 명시 설정돼 있지 않으면 + * 1) `문서\AstraBrain` 폴더를 실제로 생성 (lessons/ · memory/ 포함) + * 2) README 로 "이 폴더가 ASTRA 의 두뇌"임을 설명 (백업 안내 포함) + * 3) settings(global) 의 brainProfiles 에 명시 기록 → 설정 UI 에서 보이고 변경 가능 + * 4) 사용자에게 1회 알림 + * + * 데이터 보호: 과거 폴백(`~/.g1nation-brain`)에 이미 데이터가 쌓여 있으면 + * 그 경로를 그대로 등록한다 (이동하지 않음 — 기존 성장 데이터 유실 방지). + * 이미 brainProfiles 또는 legacy localBrainPath 가 설정된 사용자는 no-op. + */ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { logError, logInfo } from '../utils'; + +const README_NAME = 'README-AstraBrain.md'; +const README_BODY = `# AstraBrain — ASTRA 의 두뇌 폴더 + +이 폴더는 VS Code 확장 **Astra** 가 학습·성장한 데이터를 저장하는 곳입니다. + +| 폴더/파일 | 내용 | +|---|---| +| \`lessons/\` | 작업 경험에서 만들어진 교훈 (경험 기억) | +| \`memory/long_term.json\` | 대화에서 추출된 장기 기억 | +| \`memory/episodes/\` | 일화 기억 | +| \`*.md\` 지식 문서 | 리서치·위키화로 축적된 지식 (검색/RAG 대상) | +| \`.astra/\` | 평가 골든셋·성장 리포트 등 | + +⚠️ **이 폴더는 ASTRA 의 자산입니다 — 백업을 권장합니다.** +위치 변경: VS Code Settings → \`g1nation.brainProfiles\` 의 \`localBrainPath\`. +`; + +/** + * 두뇌 미설정 시 기본 두뇌를 생성·등록한다. 활성화 초기에 1회 호출. + * 반환: 새로 부트스트랩했으면 그 경로, 아니면 null(이미 설정됨/실패). + */ +export async function ensureDefaultBrainConfigured(): Promise { + try { + const cfg = vscode.workspace.getConfiguration('g1nation'); + const profiles = cfg.get>('brainProfiles', []) || []; + const legacy = (cfg.get('localBrainPath', '') || '').trim(); + // 명시 설정이 하나라도 있으면 손대지 않는다 (기존 사용자 무영향). + if (profiles.some(p => (p?.localBrainPath || '').trim()) || legacy) return null; + + // 과거 숨김 폴백에 데이터가 이미 있으면 그 경로를 그대로 등록 (유실 방지). + const dotBrain = path.join(os.homedir(), '.g1nation-brain'); + let target: string; + let reused = false; + if (fs.existsSync(dotBrain) && fs.readdirSync(dotBrain).length > 0) { + target = dotBrain; + reused = true; + } else { + const docs = path.join(os.homedir(), 'Documents'); + target = path.join(fs.existsSync(docs) ? docs : os.homedir(), 'AstraBrain'); + } + + fs.mkdirSync(path.join(target, 'lessons'), { recursive: true }); + fs.mkdirSync(path.join(target, 'memory'), { recursive: true }); + const readmePath = path.join(target, README_NAME); + if (!fs.existsSync(readmePath)) fs.writeFileSync(readmePath, README_BODY, 'utf8'); + + await cfg.update('brainProfiles', [{ + id: 'default-brain', + name: 'AstraBrain', + localBrainPath: target, + description: reused ? '기존 데이터가 발견되어 자동 등록됨' : '첫 실행 시 자동 생성된 두뇌 폴더', + }], vscode.ConfigurationTarget.Global); + await cfg.update('activeBrainId', 'default-brain', vscode.ConfigurationTarget.Global); + + logInfo('Brain bootstrap 완료.', { target, reused }); + void vscode.window.showInformationMessage( + reused + ? `Astra 두뇌: 기존 데이터를 발견해 등록했습니다 — ${target}` + : `Astra 두뇌 폴더를 생성했습니다 — ${target} (레슨·기억·지식이 여기 저장됩니다. 백업 권장)`, + ); + return target; + } catch (e: any) { + logError('Brain bootstrap 실패 (기존 폴백 경로로 동작).', { error: e?.message ?? String(e) }); + return null; + } +}