e2c5471046
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.6 KiB
7.6 KiB
id, title, category, status, verification_status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, created_at, updated_at, review_reason, merge_history, tags, raw_sources, applied_in, github_commit
| id | title | category | status | verification_status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | created_at | updated_at | review_reason | merge_history | tags | raw_sources | applied_in | github_commit | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| vscode-extension-structure-lifecycle | VSCode 확장 구조와 생명주기 | Architecture | draft | applied |
|
A | 0.93 | 2026-06-13 | 2026-06-13 |
|
|
|
VSCode 확장 구조와 생명주기
🎯 한 줄 통찰 (One-line insight)
VS Code 확장은 activate(context) 에서 깨어나 명령·뷰·이벤트를 등록하고 deactivate() 에서 정리되며, 모든 자원을 context.subscriptions 에 Disposable 로 등록해 두면 확장 종료 시 메모리/타이머/리스너가 누수 없이 일괄 정리된다 [S1].
🧠 핵심 개념 (Core concepts)
activate(context): 확장 진입점.package.json의 activationEvents 조건이 충족되면 호출된다.context: ExtensionContext가 전역 상태·구독·시크릿 저장소를 제공 [S1].deactivate(): 종료 훅. 명시적으로 풀어야 하는 자원(외부 프로세스, 봇, 모델 언로드)을 여기서 정리 [S1].- Disposable 패턴:
{ dispose(): void }를 가진 객체.context.subscriptions.push(disposable)하면 VS Code 가 종료 시dispose()를 호출 [S1]. - Command:
vscode.commands.registerCommand(id, handler)로 등록,package.json의contributes.commands에 선언. 반환값이 Disposable [S1]. - Webview: HTML 기반 커스텀 UI. 확장↔웹뷰는
postMessage로 통신. AstraAI 는 사이드바 대신 에디터 컬럼 에 패널로 띄운다 [S1]. - Configuration:
vscode.workspace.getConfiguration('g1nation')으로 설정 읽기,onDidChangeConfiguration으로 변경 반응 [S1]. - SecretStorage: 토큰 등 민감정보는
context.secrets에 저장(평문 설정 금지) [S1].
🧩 추출된 패턴 (Extracted patterns)
- 모든 자원을 subscriptions 로: 명령·리스너·상태바·타이머·커스텀 dispose 콜백까지 전부
context.subscriptions.push(...)— 정리를 잊지 않는 구조적 보장 [S1]. - 설정 변경 반응:
onDidChangeConfiguration((e) => { if (!e.affectsConfiguration('g1nation.ollamaUrl')) return; ... })— 관심 키만 필터링해 재설정 [S1]. - lazy webview 전송: 매우 이른 활성화 시점엔 웹뷰가 아직 없을 수 있어
provider?._sendModels(...)옵셔널 체이닝 + best-effort [S1]. - getter 콜백으로 늦은 바인딩: 아직 안 만들어진 객체는
getProvider: () => provider처럼 getter 로 주입 — 순환 의존/초기화 순서 문제 회피 [S1]. - 워처 = disposable 반환 함수:
startStocksWatcher(context)가 타이머를 만들고 disposable 을 반환해 subscriptions 에 등록 → 종료 시 timer cleanup [S1].
📖 세부 내용 (Details)
activate 의 책임 순서 (AstraAI 실제 순서)
- 가시화(버전 popup/console) → 환경 진단.
- 부트스트랩(brain 디렉터리, 임베딩 감지, 기능 인벤토리) — 일부는
void비차단. - 인프라 초기화(health monitor, path resolver, config 검증).
- 핵심 객체 생성·주입(LMStudioClient, lifecycle, AgentExecutor, SidebarChatProvider, BridgeServer).
- 명령·리스너 등록.
- 워처 시작(stocks, daily briefing, growth cycle, sleep digest).
- 웹뷰 자동 오픈.
deactivate 의 책임
HealthCheckMonitor.dispose(), 인메모리 인덱스 해제(clearBrainTokenIndex() — Map 이 프로세스 수명 동안 안 비는 것 방지), 텔레그램 봇 stop, 모델 lifecycle dispose+unload. 명시적 정리가 필요한 것만 여기서 처리하고, subscriptions 로 등록된 것은 VS Code 가 알아서 정리한다 [S1].
설정·시크릿
const cfg = vscode.workspace.getConfiguration('g1nation');
const timeout = cfg.get<number>('lmStudio.idleTimeoutMs', 300000); // 기본값 동반
const token = await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY); // 민감정보는 secrets
Webview 통신
확장→웹뷰는 webview.postMessage({ type: 'streamChunk', value }), 웹뷰→확장은 메시지 핸들러(sidebar/chatHandlers). 스트리밍은 streamStart/streamChunk/streamEnd 의 메시지 프로토콜로 표현 [참조: Agent 오케스트레이터 분해].
⚖️ 모순 및 업데이트 (Contradictions & updates)
- 사이드바 뷰 제거(v2.81): 과거엔 activity bar 사이드바에 webview view 를 등록했으나, 현재는 에디터 컬럼 3에 패널로 띄운다. 대신 activity bar 에는 명령 링크만 있는 빈 TreeView 를 둔다 — 탭이 닫혀도 다시 열 수 있게 [S1].
- activationEvents: 너무 광범위하면(예:
*) 시작이 느려진다. 필요한 이벤트로 좁히는 것이 좋다(AstraAI 는 명령/뷰 기반).
🛠️ 적용 사례 (Applied in summary)
AstraAI/src/extension.ts— activate/deactivate 의 전 과정, subscriptions 등록, 설정 반응, secrets 사용, 워처 등록이 모두 한 파일에 [S1].AstraAI/src/features/_shared/eventSourcedStore.ts—vscode.workspace.workspaceFolders로 워크스페이스 경로 해석(확장에서 파일 경로 다루는 표준 방식) [S3].
💻 코드 패턴 (Code patterns)
// 1) 명령 등록 → 반환된 Disposable 을 subscriptions 로 (src/extension.ts)
context.subscriptions.push(
vscode.commands.registerCommand('g1nation.clearChat', () => provider.clearChat()),
);
// 2) 설정 변경 반응 — 관심 키만 (src/extension.ts)
context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration((e) => {
if (!e.affectsConfiguration('g1nation.ollamaUrl')) return;
const newUrl = vscode.workspace.getConfiguration('g1nation').get<string>('ollamaUrl', '');
lmStudioClient.setBaseUrl(newUrl);
}),
);
// 3) 커스텀 dispose 콜백도 disposable 로 등록
context.subscriptions.push({ dispose: () => activityTracker.dispose() });
// 4) getter 콜백으로 늦은 바인딩 (순환/초기화 순서 회피)
const telegramBot = createTelegramBot(context, { telegramClient, getProvider: () => provider });
// 5) deactivate — 명시 정리가 필요한 것만
export async function deactivate() {
HealthCheckMonitor.dispose();
clearBrainTokenIndex();
if (_telegramBot) { try { await _telegramBot.stop(); } catch {} }
}
✅ 검증 상태 및 신뢰도
- 상태: draft
- 검증 단계: applied
- 출처 신뢰도: A
- 신뢰 점수: 0.93
- 중복 검사 결과: 신규 생성 (New discovery)
🔗 지식 그래프 (Knowledge Graph)
- 상위/루트: AstraAI 아키텍처 개요
- 관련 개념: 의존성 주입과 서비스 인터페이스, 모듈 시스템과 프로젝트 구성, 동시성 제어 Lock Queue Transaction
- 참조 맥락: 로컬 LLM 이 VS Code 확장의 명령/뷰/설정/수명관리 코드를 작성·수정할 때 참조.
📚 출처 (Sources)
- [S1] AstraAI/src/extension.ts — activate/deactivate, subscriptions, 명령/설정/시크릿/웹뷰/워처
- [S2] AstraAI/package.json — engines.vscode, main, contributes(명령/뷰)
- [S3] AstraAI/src/features/_shared/eventSourcedStore.ts — workspaceFolders 경로 해석
📝 변경 이력 (Change history)
- 2026-06-13: AstraAI 코드 분석 기반 초안 생성.