diff --git a/.astra/project-context/architecture.md b/.astra/project-context/architecture.md index 09e30db..9d43c10 100644 --- a/.astra/project-context/architecture.md +++ b/.astra/project-context/architecture.md @@ -3,15 +3,15 @@ ## Snapshot -- **Workspace**: `ConnectAI` `v2.0.9` _(absolute path varies by environment; resolved from the active VS Code workspace)_ +- **Workspace**: `ConnectAI` `v2.1.0` _(absolute path varies by environment; resolved from the active VS Code workspace)_ - **Description**: The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making. - **Stack**: TypeScript, Node.js, VS Code Extension, LM Studio SDK, Test runner -- **Stats**: 201 source files, ~35,737 lines across 5 top-level modules. +- **Stats**: 202 source files, ~35,762 lines across 5 top-level modules. ## Last Refresh -- **Time**: 2026-05-13T16:44:14.023Z -- **Files newly analysed**: 8 -- **Files reused from cache**: 193 +- **Time**: 2026-05-13T16:54:00.117Z +- **Files newly analysed**: 5 +- **Files reused from cache**: 197 ## Directory Map ```mermaid @@ -41,7 +41,7 @@ flowchart LR media["media/
6 files"] tests["tests/
27 files"] core_py["core_py/
6 files"] - docs["docs/
62 files"] + docs["docs/
63 files"] tests --> src ``` @@ -117,14 +117,14 @@ flowchart LR - `media/settings-panel.html` (164 lines) — Astra Settings - `media/settings-panel.js` (270 lines) -### `tests/` — 27 files, ~4,932 lines +### `tests/` — 27 files, ~4,938 lines *Depends on*: `src/` **Sub-directories** - `tests/mocks/` (1) — 1 files (.js) **Key files** -- `tests/agentEngine.test.ts` (776 lines) — AgentEngine Integration Tests & Performance Benchmarks 검증 대상: 1. ErrorClassifier — 오류 유형(Transient/Permanent/Abort) 자동 분류 2. ErrorRecoveryMatrix — 각 규칙이 의도한 대응 전략으로 매핑되는지 검증 3. resilientExecute — 지수 백 +- `tests/agentEngine.test.ts` (782 lines) — AgentEngine Integration Tests & Performance Benchmarks 검증 대상: 1. ErrorClassifier — 오류 유형(Transient/Permanent/Abort) 자동 분류 2. ErrorRecoveryMatrix — 각 규칙이 의도한 대응 전략으로 매핑되는지 검증 3. resilientExecute — 지수 백 - `tests/lmStudioLifecycle.test.ts` (318 lines) — Unit tests for ModelLifecycleManager. Strategy: inject mock ILMStudioClient and a simple in-memory IActivityTracker. No real LM Studio or SDK is touched — the manager file does not import the SDK dire - `tests/telegramBot.test.ts` (363 lines) — Unit tests for TelegramBot + truncateForTelegram. Strategy: - TelegramBot is driven by an injected ITelegramClient stub. We script getUpdates to return queued batches and assert that: - the offset cur - `tests/lmStudioStreamer.test.ts` (220 lines) — Unit tests for LMStudioStreamer. Strategy: inject a fake ILMStudioClient that returns a fake model handle whose respond() yields a controllable async iterable. No real SDK or WebSocket touched. @@ -160,10 +160,10 @@ flowchart LR - `core_py/optimizer.py` (55 lines) - `core_py/queue_worker.py` (82 lines) -### `docs/` — 62 files, ~2,586 lines +### `docs/` — 63 files, ~2,605 lines **Sub-directories** -- `docs/records/` (50) — Astra Project Chronicle Records +- `docs/records/` (51) — Astra Project Chronicle Records - `docs/docs/` (5) — docs Chronicle Records **Key files** @@ -172,7 +172,7 @@ flowchart LR - `docs/EXPERIENCE_MEMORY_PLAN.md` (122 lines) — Experience Memory (Mistake / Lesson Loop) — Implementation Plan - `docs/records/ConnectAI/development/2026-05-02_connectai_project_knowledge_overview.md` (121 lines) — Astra Project Knowledge Overview - `docs/records/ConnectAI/development/2026-05-03_connectai_project_knowledge_overview.md` (121 lines) — Astra Project Knowledge Overview -- `docs/records/ConnectAI/timeline.md` (122 lines) — Project Timeline +- `docs/records/ConnectAI/timeline.md` (125 lines) — Project Timeline - `docs/Advanced_Features_Implementation_Guide.md` (40 lines) — Advanced Features Implementation Guide - `docs/PROJECT_CHRONICLE_GUARD_ROADMAP.md` (43 lines) — Project Chronicle Guard: Search Engine Roadmap - `docs/UX_UI_Consistency_Guidelines.md` (44 lines) — UX/UI Consistency Guidelines @@ -307,7 +307,7 @@ Astra는 대표님의 명시적인 승인 하에 로컬 시스템의 강력한 **Designed for High-Performance Decision Making.** Copyright (C) **g1nation**. All rights reserved. -_Last auto-scan: 2026-05-13T16:44:14.023Z · signature `c63276ae`_ +_Last auto-scan: 2026-05-13T16:54:00.117Z · signature `2c245387`_ ## Purpose diff --git a/.astra/project-context/scan-cache.json b/.astra/project-context/scan-cache.json index 7b90764..6aaf2f4 100644 --- a/.astra/project-context/scan-cache.json +++ b/.astra/project-context/scan-cache.json @@ -1,6 +1,6 @@ { "version": 1, - "generatedAt": "2026-05-13T16:44:14.033Z", + "generatedAt": "2026-05-13T16:54:00.128Z", "files": { "src/agent.ts": { "mtimeMs": 1778683690000, @@ -923,8 +923,8 @@ ] }, "src/sidebarProvider.ts": { - "mtimeMs": 1778686896000, - "size": 127185, + "mtimeMs": 1778690954000, + "size": 127595, "lines": 2934, "role": "", "imports": [ @@ -1056,9 +1056,9 @@ "imports": [] }, "tests/agentEngine.test.ts": { - "mtimeMs": 1778690526000, - "size": 33414, - "lines": 776, + "mtimeMs": 1778690770000, + "size": 33921, + "lines": 782, "role": "AgentEngine Integration Tests & Performance Benchmarks 검증 대상: 1. ErrorClassifier — 오류 유형(Transient/Permanent/Abort) 자동 분류 2. ErrorRecoveryMatrix — 각 규칙이 의도한 대응 전략으로 매핑되는지 검증 3. resilientExecute — 지수 백", "imports": [ "src/lib/engine" @@ -1508,7 +1508,7 @@ "imports": [] }, "docs/records/ConnectAI/chronicle.config.json": { - "mtimeMs": 1778690568000, + "mtimeMs": 1778690673000, "size": 416, "lines": 11, "role": "JSON configuration", @@ -1717,6 +1717,13 @@ "role": "Development Log: 너는 분석 요청하거나 내가 작업 요청을 할때 connectai architecture.md 문서를 참고하고 작업을 하나?", "imports": [] }, + "docs/records/ConnectAI/discussions/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업-할-거야.md": { + "mtimeMs": 1778690673000, + "size": 652, + "lines": 16, + "role": "Discussion: /Volumes/Data/project/Antigravity/ConnectAI 이 프로젝트 작업 할 거야.", + "imports": [] + }, "docs/records/ConnectAI/discussions/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업할거야.md": { "mtimeMs": 1778680095000, "size": 651, @@ -1767,9 +1774,9 @@ "imports": [] }, "docs/records/ConnectAI/timeline.md": { - "mtimeMs": 1778689955000, - "size": 8165, - "lines": 122, + "mtimeMs": 1778690673000, + "size": 8318, + "lines": 125, "role": "Project Timeline", "imports": [] }, diff --git a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json index f66cd13..c8adbda 100644 --- a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json +++ b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json @@ -1,5 +1,5 @@ { "result": "Final report with inconsistencies. This should be long enough to pass validation.", - "createdAt": 1778690820030, + "createdAt": 1778691140353, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json index 557cd72..4d1351a 100644 --- a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json +++ b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json @@ -1,5 +1,5 @@ { "result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.", - "createdAt": 1778690820030, + "createdAt": 1778691140352, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json index 836ebf2..d20067f 100644 --- a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json +++ b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json @@ -1,5 +1,5 @@ { "result": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", - "createdAt": 1778690820029, + "createdAt": 1778691140352, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json index e9316f9..18e0757 100644 --- a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json +++ b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json @@ -1,5 +1,5 @@ { - "result": "---\nid: stress_conflict_1778690820018\ndate: 2026-05-13T16:47:00.031Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (11ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (0ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (1ms)\n", - "createdAt": 1778690820031, + "result": "---\nid: stress_conflict_1778691140340\ndate: 2026-05-13T16:52:20.353Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (12ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (0ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (0ms)\n", + "createdAt": 1778691140353, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/missions/stress_conflict_1778690820018.json b/.astra/tests/stress/.astra/missions/stress_conflict_1778691140340.json similarity index 82% rename from .astra/tests/stress/.astra/missions/stress_conflict_1778690820018.json rename to .astra/tests/stress/.astra/missions/stress_conflict_1778691140340.json index 2099118..63cf002 100644 --- a/.astra/tests/stress/.astra/missions/stress_conflict_1778690820018.json +++ b/.astra/tests/stress/.astra/missions/stress_conflict_1778691140340.json @@ -1,7 +1,7 @@ { - "missionId": "stress_conflict_1778690820018", + "missionId": "stress_conflict_1778691140340", "status": "completed", - "startTime": "2026-05-13T16:47:00.018Z", + "startTime": "2026-05-13T16:52:20.340Z", "totalElapsedMs": 13, "results": { "planner": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", @@ -16,30 +16,30 @@ { "from": "idle", "to": "planner", - "durationMs": 11, + "durationMs": 12, "message": "전략 수립 중...", - "ts": "2026-05-13T16:47:00.029Z" + "ts": "2026-05-13T16:52:20.352Z" }, { "from": "planner", "to": "researcher", "durationMs": 0, "message": "핵심 정보 수집 및 분석 중...", - "ts": "2026-05-13T16:47:00.029Z" + "ts": "2026-05-13T16:52:20.352Z" }, { "from": "researcher", "to": "writer", - "durationMs": 1, + "durationMs": 0, "message": "최종 리포트 작성 및 편집 중...", - "ts": "2026-05-13T16:47:00.030Z" + "ts": "2026-05-13T16:52:20.352Z" }, { "from": "writer", "to": "completed", "durationMs": 1, "message": "미션 완료", - "ts": "2026-05-13T16:47:00.031Z" + "ts": "2026-05-13T16:52:20.353Z" } ], "resilienceMetrics": { diff --git a/docs/records/ConnectAI/chronicle.config.json b/docs/records/ConnectAI/chronicle.config.json index 2111806..2cb00c4 100644 --- a/docs/records/ConnectAI/chronicle.config.json +++ b/docs/records/ConnectAI/chronicle.config.json @@ -7,5 +7,5 @@ "corePurpose": "", "detailLevel": "standard", "createdAt": "2026-05-13T13:09:33.788Z", - "updatedAt": "2026-05-13T16:44:33.835Z" + "updatedAt": "2026-05-13T16:54:16.995Z" } diff --git a/docs/records/ConnectAI/development/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업할거야_implementation.md b/docs/records/ConnectAI/development/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업할거야_implementation.md new file mode 100644 index 0000000..556f82d --- /dev/null +++ b/docs/records/ConnectAI/development/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업할거야_implementation.md @@ -0,0 +1,22 @@ +# Development Log: /Volumes/Data/project/Antigravity/ConnectAI 이 프로젝트 작업할거야 + +## Purpose +Record the implementation or verification outcome from the current conversation. + +## Implementation Summary +네, `/Volumes/Data/project/Antigravity/ConnectAI` 프로젝트를 진행하시려는군요. 어떤 부분부터 시작하면 좋을지 구체적인 목표나 첫 번째 작업에 대해 말씀해 주시겠습니까? 예를 들어, 아키텍처 검토, 특정 기능 구현, 혹은 초기 계획 수립 등 원하는 방향을 알려주시면 바로 실행하겠습니다. + +## Architecture +Captured automatically from the assistant response and active project context. + +## Changed Files +- No explicit changed file list was captured automatically. + +## Dependency Notes +No new dependency note was captured automatically. + +## Bugs +No bugs recorded. + +## Lessons +- Automatic project records should be generated in the background when the turn contains durable project knowledge. diff --git a/docs/records/ConnectAI/timeline.md b/docs/records/ConnectAI/timeline.md index 59f067e..4e6479e 100644 --- a/docs/records/ConnectAI/timeline.md +++ b/docs/records/ConnectAI/timeline.md @@ -123,3 +123,6 @@ ## 2026-05-13 - Auto discussion record created: discussions/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업-할-거야.md + +## 2026-05-13 +- Auto development record created: development/2026-05-13_volumes-data-project-antigravity-connectai-이-프로젝트-작업할거야_implementation.md diff --git a/src/extension.ts b/src/extension.ts index f4a7db5..e486184 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -608,6 +608,20 @@ export async function activate(context: vscode.ExtensionContext) { if (!provider) return; await provider._openArchitectureDoc(); }), + // Re-resolve the active subproject when the user switches between files + // in different subfolders. Debounced so rapid editor flicks don't churn + // the chip / watcher. The actual resync is idempotent — if the active + // subproject didn't change, nothing visible happens. + (() => { + let timer: NodeJS.Timeout | undefined; + return vscode.window.onDidChangeActiveTextEditor(() => { + if (!provider) return; + if (timer) clearTimeout(timer); + timer = setTimeout(() => { + provider!._sendArchitectureStatus().catch(() => { /* swallow — chip is best-effort */ }); + }, 400); + }); + })(), // ── 1인 기업 (Company) Mode commands ────────────────────────────────── // Thin shells over sidebar-provider methods so the runtime owns all // state mutation (chip status, watcher lifecycle, agent persistence). diff --git a/src/features/projectArchitecture/index.ts b/src/features/projectArchitecture/index.ts index cc17644..12eb58f 100644 --- a/src/features/projectArchitecture/index.ts +++ b/src/features/projectArchitecture/index.ts @@ -130,6 +130,56 @@ export function architectureDocPathFor(projectRoot: string): string { return path.join(projectRoot, ARCH_DIR_REL, ARCH_FILE); } +/** + * Resolve the *effective* subproject root when the user has opened a parent + * folder that contains several independent subprojects (each carrying its own + * `.astra/project-context/` or `package.json`). + * + * Walks up from `hintFsPath` toward `workspaceRoot` and returns the first + * ancestor that already looks like a subproject. Falls back to `workspaceRoot` + * when no nested marker is found, when the hint lives outside the workspace, + * or when the hint sits inside `node_modules` / build folders. + * + * Markers (in order): + * 1. `.astra/project-context/` — an already-initialised Astra subproject. + * 2. `package.json` — a Node project root (covers fresh subprojects that + * haven't activated architecture mode yet). + */ +export function resolveActiveSubprojectRoot(workspaceRoot: string, hintFsPath?: string): string { + if (!workspaceRoot || !hintFsPath) return workspaceRoot; + let wsNorm: string; + let hintNorm: string; + try { + wsNorm = path.resolve(workspaceRoot); + hintNorm = path.resolve(hintFsPath); + } catch { + return workspaceRoot; + } + const rel = path.relative(wsNorm, hintNorm); + if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) { + return workspaceRoot; + } + // Skip hints that live inside dependency / build folders — those are not + // user-authored subprojects, and `node_modules//package.json` would + // otherwise be mistaken for a subproject root. + const skipSegments = new Set(['node_modules', '.git', 'out', 'dist', '.astra']); + const relSegments = rel.split(/[\\/]+/); + if (relSegments.some((s) => skipSegments.has(s))) return workspaceRoot; + + let cur = path.dirname(hintNorm); + while (true) { + if (cur === wsNorm) return workspaceRoot; + const r = path.relative(wsNorm, cur); + if (!r || r.startsWith('..') || path.isAbsolute(r)) return workspaceRoot; + const astraMarker = path.join(cur, ARCH_DIR_REL); + const pkgMarker = path.join(cur, 'package.json'); + if (fs.existsSync(astraMarker) || fs.existsSync(pkgMarker)) return cur; + const parent = path.dirname(cur); + if (parent === cur) return workspaceRoot; + cur = parent; + } +} + /** * Backwards-compatible thin wrapper. The watcher / refresh path only needs the * shape-signature to decide whether to re-emit the doc, so we expose `scanProject` diff --git a/src/sidebarProvider.ts b/src/sidebarProvider.ts index efa30fe..7a9e21d 100644 --- a/src/sidebarProvider.ts +++ b/src/sidebarProvider.ts @@ -31,6 +31,7 @@ import { buildOrRefreshArchitectureDoc, architectureDocPathFor, formatArchitectureContextForPrompt, + resolveActiveSubprojectRoot, scanProject, } from './features/projectArchitecture'; import { detectProjectIntent, KnownProject } from './features/projectArchitecture/intentDetector'; @@ -1217,8 +1218,14 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn * is free. */ async _ensureActiveProjectForWorkspace(): Promise { - const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (!workspaceRoot) return null; + const wsRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + if (!wsRoot) return null; + // When the parent folder contains several subprojects, use the active + // editor's location to pick the *effective* subproject root instead of + // always reporting the parent. + const hint = vscode.window.activeTextEditor?.document.uri.fsPath + ?? vscode.window.visibleTextEditors[0]?.document.uri.fsPath; + const workspaceRoot = resolveActiveSubprojectRoot(wsRoot, hint); const projects = this._getChronicleProjects(); const active = this._getActiveChronicleProject(); const norm = (p: string | undefined) => (p || '').replace(/[\\/]+$/, '').toLowerCase(); @@ -2484,6 +2491,15 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn logError('architecture: intent detection failed.', { error: e?.message ?? String(e) }); } } + // Re-resolve the active subproject from the currently-focused editor. + // Without this, switching between subprojects (e.g. ConnectAI → + // Datacollector) inside one VS Code window keeps loading the previous + // subproject's architecture into the prompt. + try { + await this._ensureActiveProjectForWorkspace(); + } catch (e: any) { + logError('architecture: workspace resync failed.', { error: e?.message ?? String(e) }); + } const projectArchitectureContext = this._buildProjectArchitectureContext(); // [File Processing v2] 파일 타입별 분류 처리