feat(onboarding): 두뇌 기본 위치 부트스트랩 — 성장 데이터 저장처 명시화 (v2.2.217)

두뇌 미설정 시 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 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 17:39:08 +09:00
parent 70ea421827
commit 92c92da090
4 changed files with 99 additions and 3 deletions
+6
View File
@@ -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);
+90
View File
@@ -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<string | null> {
try {
const cfg = vscode.workspace.getConfiguration('g1nation');
const profiles = cfg.get<Array<{ localBrainPath?: string }>>('brainProfiles', []) || [];
const legacy = (cfg.get<string>('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;
}
}