diff --git a/.astra/project-context/architecture.md b/.astra/project-context/architecture.md
index 388bb9c..73571ce 100644
--- a/.astra/project-context/architecture.md
+++ b/.astra/project-context/architecture.md
@@ -3,15 +3,15 @@
## Snapshot
-- **Workspace**: `ConnectAI` `v2.2.90` _(absolute path varies by environment; resolved from the active VS Code workspace)_
+- **Workspace**: `ConnectAI` `v2.2.158` _(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**: 286 source files, ~57,087 lines across 5 top-level modules.
+- **Stats**: 395 source files, ~63,423 lines across 5 top-level modules.
## Last Refresh
-- **Time**: 2026-05-24T04:49:04.938Z
-- **Files newly analysed**: 3
-- **Files reused from cache**: 283
+- **Time**: 2026-05-25T00:59:03.313Z
+- **Files newly analysed**: 1
+- **Files reused from cache**: 394
## Directory Map
```mermaid
@@ -19,13 +19,15 @@ mindmap
root((ConnectAI))
src/
features/
- core/
- memory/
- retrieval/
- docs/
+ sidebar/
lib/
+ agent/
+ core/
+ extension/
media/
tests/
+ helpers/
+ integration/
mocks/
core_py/
docs/
@@ -37,9 +39,9 @@ mindmap
> Arrows: which top-level module imports from which.
```mermaid
flowchart LR
- src["src/
140 files"]
+ src["src/
247 files"]
media["media/
6 files"]
- tests["tests/
35 files"]
+ tests["tests/
37 files"]
core_py["core_py/
6 files"]
docs["docs/
99 files"]
tests --> src
@@ -53,82 +55,85 @@ flowchart LR
## Hub Files
> Imported by many other files — touching these has wide blast radius.
-- `src/utils.ts` — referenced by **50** files
-- `src/config.ts` — referenced by **16** files
-- `src/features/company/types.ts` — referenced by **13** files · Type definitions for the 1인 기업 (One-Person Company) mode. The mode turns the user into a virtual CEO that dispatches work to a roster of specialist agents. Each turn produces a session directory conta
-- `src/core/services.ts` — referenced by **10** files
-- `src/lib/paths.ts` — referenced by **10** files
-- `src/agent.ts` — referenced by **7** files
-- `src/sidebarProvider.ts` — referenced by **7** files
-- `src/skills/agentKnowledgeMap.ts` — referenced by **6** files
+- `src/utils.ts` — referenced by **87** files
+- `src/agent.ts` — referenced by **34** files
+- `src/config.ts` — referenced by **32** files
+- `src/core/services.ts` — referenced by **14** files
+- `src/features/company/index.ts` — referenced by **14** files · Public API for 1인 기업 모드. Consumers (sidebarProvider, chatHandlers, command handlers) import from this barrel so internal layout can move around without touching every call site.
+- `src/features/company/types.ts` — referenced by **14** files · Type definitions for the 1인 기업 (One-Person Company) mode. The mode turns the user into a virtual CEO that dispatches work to a roster of specialist agents. Each turn produces a session directory conta
+- `src/sidebarProvider.ts` — referenced by **11** files
+- `src/lib/contextManager.ts` — referenced by **10** files · Context Manager (컨텍스트 한계 관리) "context length = 132k" 는 "답변을 132k 토큰까지 생성해도 된다" 가 아닙니다. 시스템 프롬프트 + 대화 기록 + 입력 문서 + 생성될 답변 + 여유분 ≤ context length 이 모듈은 요청을 보내기 전에 입력 토큰을 추정하고, - 동적으로 출력 상한(maxTokens)을 계
## Modules
-### `src/` — 140 files, ~39,922 lines
+### `src/` — 247 files, ~45,859 lines
**Sub-directories**
-- `src/features/` (67) — Astra Office — public API. 다음 세션에서 추가될 OfficeSnapshot presenter / schema 도 같은 entry 로 노출 예정. 현재 노출: full webview panel H
+- `src/features/` (87) — Astra Office — public API. 다음 세션에서 추가될 OfficeSnapshot presenter / schema 도 같은 entry 로 노출 예정. 현재 노출: full webview panel H
+- `src/sidebar/` (35) — Brain profile lifecycle 의 pure helpers — sidebarProvider 의 add/edit/delete 흐름에서 modal UI 와 config 쓰기를 제외한 데이터 변환 만 격리. 현
+- `src/lib/` (28) — Astra Mode Architecture Context Builder. 의도: 사용자가 Astra 자체의 mode 디자인 (Guard vs Multi-Agent 가 별도 모드여야 하는지) 을 묻는 메타 질문에 답할
+- `src/agent/` (25) — 25 files (.ts)
- `src/core/` (15) — Astra Path Resolver (경로 해결기) Astra의 모든 데이터 파일(.astra 디렉토리)의 경로를 중앙에서 관리합니다. 확장 프로그램의 설치 경로(extensionUri) 기반으로 .astra 디렉토
+- `src/extension/` (8) — 8 files (.ts)
- `src/memory/` (8) — Episodic Memory (일화 기억) 과거 대화/회의/결정의 맥락 흐름을 저장합니다. 세션 종료 시 자동으로 에피소드를 요약하여 저장합니다. "왜 이렇게 결정했는지", "어떤 흐름으로 진행했는지" 기록. 저장
- `src/retrieval/` (8) — Brain Index — persistent, mtime-keyed tokenized cache of the Second Brain RAG 검색은 매 질의마다 브레인의 모든 .md 파일을 읽고 토크나이즈해서 TF-I
- `src/docs/` (6) — src Chronicle Records
-- `src/lib/` (6) — Context Manager (컨텍스트 한계 관리) "context length = 132k" 는 "답변을 132k 토큰까지 생성해도 된다" 가 아닙니다. 시스템 프롬프트 + 대화 기록 + 입력 문서 + 생성될 답변
-- `src/sidebar/` (5) — 5 files (.ts)
-- `src/integrations/` (4) — Per-chat conversation history for the Telegram bot. Why this exists: the previous bot was stateless — every inbound mess
+- `src/integrations/` (6) — Per-chat conversation history for the Telegram bot. Why this exists: the previous bot was stateless — every inbound mess
- `src/lmstudio/` (4) — 4 files (.ts)
- `src/skills/` (4) — 4 files (.ts)
-- `src/agents/` (2) — 2 files (.ts)
-- `src/scaffolder/` (2) — Scaffolder template catalog. Templates are pure data — (projectName) => { [relativePath]: contents }. New templates are
**Key files**
-- `src/utils.ts` (448 lines)
-- `src/config.ts` (406 lines)
+- `src/utils.ts` (471 lines)
+- `src/agent.ts` (1487 lines)
+- `src/config.ts` (418 lines)
- `src/features/company/types.ts` (446 lines) — Type definitions for the 1인 기업 (One-Person Company) mode. The mode turns the user into a virtual CEO that dispatches work to a roster of specialist agents. Each turn produces a session directory conta
+- `src/sidebarProvider.ts` (3194 lines)
- `src/core/services.ts` (176 lines)
-- `src/sidebarProvider.ts` (4340 lines)
-- `src/lib/paths.ts` (151 lines)
+- `src/lib/contextManager.ts` (278 lines) — Context Manager (컨텍스트 한계 관리) "context length = 132k" 는 "답변을 132k 토큰까지 생성해도 된다" 가 아닙니다. 시스템 프롬프트 + 대화 기록 + 입력 문서 + 생성될 답변 + 여유분 ≤ context length 이 모듈은 요청을 보내기 전에 입력 토큰을 추정하고, - 동적으로 출력 상한(maxTokens)을 계
- `src/features/company/companyConfig.ts` (896 lines) — State + config plumbing for 1인 기업 모드. Two surfaces: - CompanyState (runtime data: enabled flag, company name, which agents are active, per-agent model overrides). Persisted in VS Code's globalState so
+- `src/integrations/telegram/telegramClient.ts` (154 lines)
+- `src/lib/paths.ts` (151 lines)
+- `src/agent/actions/types.ts` (41 lines)
+- `src/skills/agentKnowledgeMap.ts` (374 lines)
+- `src/features/stocks/types.ts` (53 lines) — Stocks 모듈 공유 타입. investresults/targetstocks.json 스키마를 그대로 받아서, ConnectAI 의 /.astra/stocks.json 으로 옮긴 뒤 같은 필드명을 유지. 한글 필드명은 사용자의 도메인 데이터라 변경하지 않는다 — 마이그레이션 충돌 회피 + 사용자가 직접 JSON 편집할 때 frictio
+- `src/lib/contextBuilders/promptDetection.ts` (85 lines) — 사용자 prompt 의 의도 분류 류 detection helpers. 모두 stateless 정규식 매칭. 옛 코드는 agent.ts 의 private 메서드로 박혀 있었는데, system prompt 빌더 (buildJarvisProjectBriefContext 등) 가 이걸 의존하면서 god-file 안에서 서로 얽힘. 헬퍼만 먼저 떼면 의존 그래프가
+- `src/retrieval/lessonHelpers.ts` (325 lines) — Lesson / Experience Memory — pure helpers (no vscode dependency) "Lesson" = a markdown file in the active brain that captures a past mistake/risk and how to avoid repeating it. Identified by a lessons
- `src/memory/types.ts` (126 lines) — Memory Type Definitions (메모리 타입 정의) Astra의 5-Layer Cognitive Memory System의 모든 타입을 정의합니다. ① Short-Term ② Long-Term ③ Project ④ Procedural ⑤ Episodic
- `src/retrieval/scoring.ts` (541 lines) — Scoring Engine — TF-IDF + Bilingual Tokenizer 단순 includes() 키워드 매칭을 넘어서, TF-IDF 가중치 기반의 문서 스코어링을 제공합니다. 한국어/영어 양국어 토크나이저를 포함합니다.
-- `src/skills/agentKnowledgeMap.ts` (374 lines)
-- `src/agent.ts` (4105 lines)
+- `src/security.ts` (159 lines)
+- `src/features/secondBrainTrace.ts` (792 lines)
- `src/features/providers/types.ts` (63 lines) — Cloud LLM provider routing — model id prefix → provider id 매핑. Prefix 규칙: openrouter:anthropic/claude-3.5-sonnet → { provider: 'openrouter', model: 'anthropic/claude-3.5-sonnet' } anthropic:claude-3-5
-- `src/lib/engine.ts` (1103 lines)
-- `src/retrieval/brainIndex.ts` (325 lines) — Brain Index — persistent, mtime-keyed tokenized cache of the Second Brain RAG 검색은 매 질의마다 브레인의 모든 .md 파일을 읽고 토크나이즈해서 TF-IDF 점수를 계산했습니다 — 파일 수가 많아지면 그게 병목입니다. 이 모듈은 /.astra/brain-index.json 에
-- `src/retrieval/lessonHelpers.ts` (325 lines) — Lesson / Experience Memory — pure helpers (no vscode dependency) "Lesson" = a markdown file in the active brain that captures a past mistake/risk and how to avoid repeating it. Identified by a lessons
-- `src/features/company/dispatcher.ts` (1442 lines) — Sequential dispatcher for 1인 기업 모드. Drives one company "turn": user prompt → CEO planner (JSON {brief, tasks}) → for each task in plan: dispatch one specialist (sequentially) - build specialist prompt
-- `src/features/providers/providerConfig.ts` (78 lines) — Provider 별 API key + enable 토글 저장소. 설계: - API key 자체는 vscode.SecretStorage (secrets) 에 — settings.json / Settings Sync 침범 안 받음. - enabled 토글은 일반 settings (g1nation.providers..enabled) — 사용자가 패널에서
-- `src/features/approval/approvalQueue.ts` (129 lines)
-- `src/integrations/telegram/telegramClient.ts` (154 lines)
-- `src/features/astraOffice/view/runtime.ts` (1932 lines) — 자동 분리: src/sidebarProvider.ts 4002-5116 (IIFE 본문) 에서 추출. 동작 동등. ${assets.derivedBase} placeholder 는 panelHtml 에서 .replace() 로 실제 값 주입. 다음 세션에서 OfficeSnapshot 기반으로 단계적으로 잘라낼 예정.
-- `src/features/company/agents.ts` (211 lines) — 기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정. 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때 필요한 직군을 빠짐없이 커버하되 역할이 겹치지 않게 분리한다. 직군 구분 (혼동 방지): - 기획자(business) : 무엇을 만들지 정의
-- `src/features/company/pixelOfficeState.ts` (286 lines) — Pixel Office — Agent Work Pipeline 상태를 시각화하는 UI Layer 전용 모듈. ─────────────────── 설계 원칙 ─────────────────── 1. Agent 핵심 판단 로직을 절대 바꾸지 않는다. Pipeline 진행, contract 합의, 검수 cycle, 승인 게이트 — 모두 기존 dispatcher
-- `src/features/company/sessionStore.ts` (231 lines) — Disk persistence for company-mode session artefacts. Each company turn produces a timestamped directory: /.astra/company/sessions/2026-05-13T21-29/ ├─ brief.md ← CEO's task decompositio
-- `src/features/projectArchitecture/scanner.ts` (644 lines) — Deep static analyser for the Project Architecture Context generator. Walks the project tree (skipping the usual nodemodules / out / dist noise), pulls the role of each interesting file from its leadin
-- `src/lib/contextManager.ts` (278 lines) — Context Manager (컨텍스트 한계 관리) "context length = 132k" 는 "답변을 132k 토큰까지 생성해도 된다" 가 아닙니다. 시스템 프롬프트 + 대화 기록 + 입력 문서 + 생성될 답변 + 여유분 ≤ context length 이 모듈은 요청을 보내기 전에 입력 토큰을 추정하고, - 동적으로 출력 상한(maxTokens)을 계
+- `src/integrations/telegram/telegramBot.ts` (270 lines)
+- `src/lib/contextBuilders/localProjectIntent.ts` (233 lines)
+- `src/lib/engine.ts` (1114 lines)
+- `src/lmstudio/streamer.ts` (252 lines)
+- `src/core/responseRecovery.ts` (310 lines) — Response Recovery — Thought Quarantine + Final-only Retry + Auto-Continuation The user already asked their question; they're waiting for an answer, not for a chance to babysit the generation engine. S
-### `media/` — 6 files, ~7,484 lines
+### `media/` — 6 files, ~7,649 lines
**Key files**
-- `media/sidebar.css` (2068 lines) — Stylesheet
-- `media/sidebar.js` (3807 lines)
-- `media/sidebar.html` (538 lines) — Astra
-- `media/settings-panel.html` (398 lines) — Astra Settings
+- `media/sidebar.css` (2104 lines) — Stylesheet
+- `media/sidebar.js` (3921 lines)
+- `media/sidebar.html` (539 lines) — Astra
+- `media/settings-panel.html` (406 lines) — Astra Settings
- `media/settings-panel.css` (210 lines) — Stylesheet
-- `media/settings-panel.js` (463 lines)
+- `media/settings-panel.js` (469 lines)
-### `tests/` — 35 files, ~5,641 lines
+### `tests/` — 37 files, ~5,875 lines
*Depends on*: `src/`
**Sub-directories**
+- `tests/helpers/` (1) — MockLLMClient — IAIService 의 Mock 구현체. 의도: 회사 모드 dispatcher / ChunkedWriter / ceoPlanner 등 LLM 을 호출하는 코드 경로를 CI 환경에서도 테스
+- `tests/integration/` (1) — MockLLMClient 자체의 sanity test. 이게 통과하면 dispatcher / ceoPlanner / ChunkedWriter 등 IAIService 를 받는 코드가 실제 LLM 없이 단위 / inte
- `tests/mocks/` (1) — 1 files (.js)
**Key files**
-- `tests/agentEngine.test.ts` (405 lines) — AgentEngine Tests — Chunked Writer Architecture 예전 buildup(planner → researcher → reflector → writer → synthesizer)을 단일 ChunkedWriter 의 outline → section[N] → polish 로 교체한 뒤의 회귀 테스트. 다루는 범위: 1. ErrorC
+- `tests/helpers/mockLLMClient.ts` (112 lines) — MockLLMClient — IAIService 의 Mock 구현체. 의도: 회사 모드 dispatcher / ChunkedWriter / ceoPlanner 등 LLM 을 호출하는 코드 경로를 CI 환경에서도 테스트 가능하게. 실제 Ollama / LM Studio 없이도 응답을 미리 정의하거나 동적으로 생성 가능. 사용 예: const ai = new
+- `tests/agentEngine.test.ts` (413 lines) — AgentEngine Tests — Chunked Writer Architecture 예전 buildup(planner → researcher → reflector → writer → synthesizer)을 단일 ChunkedWriter 의 outline → section[N] → polish 로 교체한 뒤의 회귀 테스트. 다루는 범위: 1. ErrorC
- `tests/lmStudioLifecycle.test.ts` (326 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/localPathPreflight.test.ts` (520 lines)
- `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` (222 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.
-- `tests/localPathPreflight.test.ts` (492 lines)
- `tests/secondBrainTrace.test.ts` (407 lines)
- `tests/approvalQueue.test.ts` (164 lines) — Unit tests for ApprovalQueue. Strategy: drive enqueue → approve / reject / clear / pre-empt directly, confirm the onChange event fires at the right moments and callbacks fire exactly once.
- `tests/projectScaffolder.test.ts` (135 lines) — Unit tests for FileSystemProjectScaffolder. Drives against a real temp directory so end-to-end file IO + path-traversal defenses are exercised.
@@ -136,6 +141,7 @@ flowchart LR
- `tests/skillInjectionService.test.ts` (172 lines) — Unit tests for FileSystemSkillInjectionService. Strategy: drive the service against a real temp directory so path-traversal defenses and writeFileSync paths are exercised end-to-end. The service accep
- `tests/dataProcessor.test.ts` (87 lines) — /
- `tests/findBrainFilesCache.test.ts` (80 lines) — Unit tests for findBrainFiles TTL cache.
+- `tests/integration/mockLLMClient.test.ts` (86 lines) — MockLLMClient 자체의 sanity test. 이게 통과하면 dispatcher / ceoPlanner / ChunkedWriter 등 IAIService 를 받는 코드가 실제 LLM 없이 단위 / integration 테스트 가능. 향후 dispatcher 의 multi-stage flow 같은 큰 integration 테스트는 이 mock 을
- `tests/officeSchema.test.ts` (241 lines)
- `tests/paths.test.ts` (84 lines) — Unit tests for the centralized path resolver.
- `tests/systemSpecs.test.ts` (90 lines) — Unit tests for SystemSpecs + HeuristicModelMemoryEstimator. Strategy: - HeuristicModelMemoryEstimator is pure — directly drive it with model ids. - NodeSystemSpecsProvider depends on os. so we test: a
@@ -147,8 +153,6 @@ flowchart LR
- `tests/icsParser.test.ts` (134 lines)
- `tests/lessonHelpers.test.ts` (191 lines)
- `tests/projectChronicle.test.ts` (199 lines)
-- `tests/responseRecovery.test.ts` (151 lines)
-- `tests/scoring.test.ts` (134 lines)
### `core_py/` — 6 files, ~409 lines
@@ -226,7 +230,7 @@ flowchart LR
- `g1nation.calendar.refresh` — Astra: Google Calendar 새로고침 📅
- `g1nation.calendar.connectOAuth` — Astra: Google Calendar OAuth 연결 (쓰기) 🔐
- `g1nation.devilAgent.toggle` — Astra: Toggle Devil Agent 🎭
-- **Configuration** (86 settings):
+- **Configuration** (93 settings):
- `g1nation.multiAgentEnabled` *(boolean)* _(default: `false`)_ — Enable Multi-Agent Workflow (Planner -> Researcher -> Writer) for complex tasks.
- `g1nation.datacollectBridgeUrl` *(string)* _(default: `"http://127.0.0.1:3002"`)_ — Wiki/Datacollect MCP Bridge URL. /research, /benchmark, /youtube chat slash commands route here. The Bridge must be running (`npm run bridge` in the Datacollect project).
- `g1nation.datacollectSavePath` *(string)* _(default: `""`)_
@@ -287,7 +291,7 @@ flowchart LR
- `g1nation.workflow.autoCtxFractionThreshold` *(number)* _(default: `0.3`)_
- `g1nation.chunkedSwitchTokens` *(number)* _(default: `50000`)_
- `g1nation.chunkedMaxSections` *(number)* _(default: `3`)_
- - _…and 26 more_
+ - _…and 33 more_
## Dependencies
- **Runtime** (2): `@lmstudio/sdk`, `pdf-parse`
@@ -335,7 +339,7 @@ Astra는 대표님의 명시적인 승인 하에 로컬 시스템의 강력한
**Designed for High-Performance Decision Making.**
Copyright (C) **g1nation**. All rights reserved.
-_Last auto-scan: 2026-05-24T04:49:04.938Z · signature `932fe655`_
+_Last auto-scan: 2026-05-25T00:59:03.313Z · signature `fca24b52`_
## Purpose
diff --git a/.astra/project-context/scan-cache.json b/.astra/project-context/scan-cache.json
index 122667e..3956700 100644
--- a/.astra/project-context/scan-cache.json
+++ b/.astra/project-context/scan-cache.json
@@ -1,11 +1,318 @@
{
"version": 1,
- "generatedAt": "2026-05-24T04:49:04.948Z",
+ "generatedAt": "2026-05-25T00:59:03.343Z",
"files": {
+ "src/agent/actions/brainOps.ts": {
+ "mtimeMs": 1779634187000,
+ "size": 2642,
+ "lines": 54,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/utils",
+ "src/config"
+ ]
+ },
+ "src/agent/actions/calendar.ts": {
+ "mtimeMs": 1779634195000,
+ "size": 2221,
+ "lines": 43,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/agent/attrParsers",
+ "src/features/calendar"
+ ]
+ },
+ "src/agent/actions/fileCreateEdit.ts": {
+ "mtimeMs": 1779634159000,
+ "size": 3263,
+ "lines": 73,
+ "role": "",
+ "imports": [
+ "src/security",
+ "src/core/errors",
+ "src/agent/actions/types"
+ ]
+ },
+ "src/agent/actions/fileDeleteRead.ts": {
+ "mtimeMs": 1779634168000,
+ "size": 2053,
+ "lines": 44,
+ "role": "",
+ "imports": [
+ "src/security",
+ "src/core/errors",
+ "src/agent/actions/types"
+ ]
+ },
+ "src/agent/actions/listFiles.ts": {
+ "mtimeMs": 1779634179000,
+ "size": 1470,
+ "lines": 31,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/security",
+ "src/config"
+ ]
+ },
+ "src/agent/actions/runCommand.ts": {
+ "mtimeMs": 1779634168000,
+ "size": 925,
+ "lines": 20,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/security"
+ ]
+ },
+ "src/agent/actions/sheets.ts": {
+ "mtimeMs": 1779634216000,
+ "size": 4099,
+ "lines": 87,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/agent/attrParsers",
+ "src/features/sheets"
+ ]
+ },
+ "src/agent/actions/tasks.ts": {
+ "mtimeMs": 1779634214000,
+ "size": 3589,
+ "lines": 69,
+ "role": "",
+ "imports": [
+ "src/agent/actions/types",
+ "src/agent/attrParsers",
+ "src/features/tasks"
+ ]
+ },
+ "src/agent/actions/types.ts": {
+ "mtimeMs": 1779634104000,
+ "size": 2471,
+ "lines": 41,
+ "role": "",
+ "imports": [
+ "src/core/transaction",
+ "src/agent"
+ ]
+ },
+ "src/agent/attrParsers.ts": {
+ "mtimeMs": 1779633055000,
+ "size": 4608,
+ "lines": 116,
+ "role": "",
+ "imports": [
+ "src/features/tasks",
+ "src/src/agent"
+ ]
+ },
+ "src/agent/handlePrompt/applyAutoContinuation.ts": {
+ "mtimeMs": 1779634654000,
+ "size": 7835,
+ "lines": 159,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/agent",
+ "src/core/responseRecovery",
+ "src/lib/contextBuilders/outputSanitization",
+ "src/lib/contextManager",
+ "src/core/telemetry"
+ ]
+ },
+ "src/agent/handlePrompt/buildAgentModeSystemPrompt.ts": {
+ "mtimeMs": 1779635541000,
+ "size": 3964,
+ "lines": 75,
+ "role": "",
+ "imports": [
+ "src/lib/contextBuilders/systemPromptShaping",
+ "src/lib/contextManager",
+ "src/utils"
+ ]
+ },
+ "src/agent/handlePrompt/buildAstraModeSystemPrompt.ts": {
+ "mtimeMs": 1779635520000,
+ "size": 5253,
+ "lines": 82,
+ "role": "",
+ "imports": [
+ "src/lib/contextBuilders/localProjectIntent",
+ "src/lib/contextBuilders/promptDetection",
+ "src/retrieval/knowledgeMix"
+ ]
+ },
+ "src/agent/handlePrompt/buildModeBridgeContext.ts": {
+ "mtimeMs": 1779634537000,
+ "size": 2855,
+ "lines": 57,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/lib/contextBuilders/systemPromptShaping",
+ "src/lib/contextBuilders/lastTopicLine",
+ "src/utils"
+ ]
+ },
+ "src/agent/handlePrompt/buildTurnContextBlocks.ts": {
+ "mtimeMs": 1779634584000,
+ "size": 4857,
+ "lines": 117,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/config",
+ "src/utils",
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/secondBrainInventory",
+ "src/lib/contextBuilders/localProjectPath",
+ "src/lib/contextBuilders/recentProjectKnowledge",
+ "src/lib/contextBuilders/jarvisProjectBrief",
+ "src/lib/contextBuilders/astraModeArchitecture",
+ "src/features/secondBrainTrace"
+ ]
+ },
+ "src/agent/handlePrompt/computeBudgetedRequest.ts": {
+ "mtimeMs": 1779634641000,
+ "size": 8091,
+ "lines": 161,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/agent",
+ "src/lib/contextManager",
+ "src/lib/contextBuilders/droppedHistorySummary"
+ ]
+ },
+ "src/agent/handlePrompt/processFinalAnswer.ts": {
+ "mtimeMs": 1779634891000,
+ "size": 6459,
+ "lines": 147,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/config",
+ "src/core/responseRecovery",
+ "src/lib/contextBuilders/outputSanitization",
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/secondBrainInventory",
+ "src/lib/contextBuilders/localProjectIntent",
+ "src/lib/contextBuilders/projectKnowledge",
+ "src/lib/contextBuilders/localProjectPath",
+ "src/lib/contextBuilders/recentProjectKnowledge",
+ "src/features/secondBrainTrace",
+ "src/lib/contextManager"
+ ]
+ },
+ "src/agent/llm/callNonStreaming.ts": {
+ "mtimeMs": 1779633563000,
+ "size": 4233,
+ "lines": 101,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/utils",
+ "src/lib/contextBuilders/engineMessages",
+ "src/lmstudio/streamer",
+ "src/lib/contextBuilders/lmStudioSampling",
+ "src/features/providers"
+ ]
+ },
+ "src/agent/llm/createStreamingRequest.ts": {
+ "mtimeMs": 1779633585000,
+ "size": 8968,
+ "lines": 169,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/lib/contextBuilders/engineMessages",
+ "src/lib/contextBuilders/modelCandidates",
+ "src/lmstudio/streamer",
+ "src/lib/contextBuilders/lmStudioSampling",
+ "src/agent",
+ "src/features/providers"
+ ]
+ },
+ "src/agent/llm/devilRebuttal.ts": {
+ "mtimeMs": 1779633604000,
+ "size": 2938,
+ "lines": 74,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/agent",
+ "src/features/devilAgent"
+ ]
+ },
+ "src/agent/llm/streamChatOnce.ts": {
+ "mtimeMs": 1779633587000,
+ "size": 5834,
+ "lines": 136,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/lib/contextBuilders/lmStudioSampling",
+ "src/agent"
+ ]
+ },
+ "src/agent/misc.ts": {
+ "mtimeMs": 1779633631000,
+ "size": 2070,
+ "lines": 56,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/config",
+ "src/core/session",
+ "src/agent"
+ ]
+ },
+ "src/agent/multiAgent/callRoleAgent.ts": {
+ "mtimeMs": 1779633728000,
+ "size": 4666,
+ "lines": 104,
+ "role": "",
+ "imports": [
+ "src/config",
+ "src/utils",
+ "src/lib/contextManager",
+ "src/lib/contextBuilders/lmStudioSampling",
+ "src/agent"
+ ]
+ },
+ "src/agent/multiAgent/workflow.ts": {
+ "mtimeMs": 1779633889000,
+ "size": 5533,
+ "lines": 117,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/config",
+ "src/agents/AgentWorkflowManager",
+ "src/core/errorHandler",
+ "src/core/statusBar",
+ "src/core/responseRecovery",
+ "src/agent"
+ ]
+ },
+ "src/agent/sessions/compressSummary.ts": {
+ "mtimeMs": 1779633584000,
+ "size": 2719,
+ "lines": 61,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/config",
+ "src/agent"
+ ]
+ },
"src/agent.ts": {
- "mtimeMs": 1779584933000,
- "size": 233704,
- "lines": 4105,
+ "mtimeMs": 1779635568000,
+ "size": 79990,
+ "lines": 1487,
"role": "",
"imports": [
"src/utils",
@@ -14,6 +321,25 @@
"src/core/transaction",
"src/core/session",
"src/agents/AgentWorkflowManager",
+ "src/lib/contextBuilders/astraModeArchitecture",
+ "src/lib/contextBuilders/multiAgentRouting",
+ "src/lib/contextBuilders/thinkingPartnerContract",
+ "src/lib/contextBuilders/droppedHistorySummary",
+ "src/lib/contextBuilders/historyTransform",
+ "src/lib/contextBuilders/lastTopicLine",
+ "src/lib/contextBuilders/modelCandidates",
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/systemPromptShaping",
+ "src/lib/contextBuilders/outputSanitization",
+ "src/lib/contextBuilders/engineMessages",
+ "src/lib/contextBuilders/memoryContext",
+ "src/lib/contextBuilders/projectEvidence",
+ "src/lib/contextBuilders/jarvisProjectBrief",
+ "src/lib/contextBuilders/secondBrainInventory",
+ "src/lib/contextBuilders/localProjectIntent",
+ "src/lib/contextBuilders/projectKnowledge",
+ "src/lib/contextBuilders/localProjectPath",
+ "src/lib/contextBuilders/recentProjectKnowledge",
"src/core/errorHandler",
"src/core/events",
"src/core/errors",
@@ -26,31 +352,59 @@
"src/memory",
"src/retrieval",
"src/retrieval/lessonHelpers",
- "src/retrieval/embeddings",
- "src/retrieval/brainIndex",
- "src/skills/agentKnowledgeMap",
"src/retrieval/knowledgeMix",
"src/core/responseRecovery",
"src/lib/contextManager",
"src/lmstudio/streamer",
+ "src/lib/contextBuilders/lmStudioSampling",
+ "src/agent",
+ "src/agent/attrParsers",
+ "src/agent/llm/callNonStreaming",
+ "src/agent/llm/createStreamingRequest",
+ "src/agent/llm/streamChatOnce",
+ "src/agent/llm/devilRebuttal",
+ "src/agent/sessions/compressSummary",
+ "src/agent/multiAgent/callRoleAgent",
+ "src/agent/multiAgent/workflow",
+ "src/agent/misc",
+ "src/agent/actions/types",
+ "src/agent/actions/fileCreateEdit",
+ "src/agent/actions/fileDeleteRead",
+ "src/agent/actions/runCommand",
+ "src/agent/actions/listFiles",
+ "src/agent/actions/brainOps",
+ "src/agent/actions/calendar",
+ "src/agent/actions/sheets",
+ "src/agent/actions/tasks",
+ "src/agent/handlePrompt/buildModeBridgeContext",
+ "src/lib/contextBuilders/priorTurnConclusion",
+ "src/agent/handlePrompt/buildTurnContextBlocks",
+ "src/agent/handlePrompt/buildAgentModeSystemPrompt",
+ "src/agent/handlePrompt/buildAstraModeSystemPrompt",
+ "src/agent/handlePrompt/computeBudgetedRequest",
+ "src/agent/handlePrompt/processFinalAnswer",
+ "src/agent/handlePrompt/applyAutoContinuation",
"src/features/approval/approvalQueue",
- "src/features/providers"
+ "src/features/providers",
+ "src/features/selfReflector/selfReflectorExecution",
+ "src/features/selfReflector/selfReflectorHollow"
]
},
"src/agents/AgentWorkflowManager.ts": {
- "mtimeMs": 1779534441000,
- "size": 2315,
- "lines": 62,
+ "mtimeMs": 1779609976000,
+ "size": 2729,
+ "lines": 69,
"role": "",
"imports": [
"src/agents/factory",
- "src/lib/engine"
+ "src/lib/engine",
+ "src/config"
]
},
"src/agents/factory.ts": {
- "mtimeMs": 1779597040000,
- "size": 17711,
- "lines": 288,
+ "mtimeMs": 1779601097000,
+ "size": 19504,
+ "lines": 328,
"role": "",
"imports": [
"src/config",
@@ -71,9 +425,9 @@
]
},
"src/config.ts": {
- "mtimeMs": 1779598116000,
- "size": 21266,
- "lines": 406,
+ "mtimeMs": 1779609954000,
+ "size": 22021,
+ "lines": 418,
"role": "",
"imports": []
},
@@ -132,9 +486,9 @@
]
},
"src/core/lock.ts": {
- "mtimeMs": 1778169995000,
- "size": 2358,
- "lines": 66,
+ "mtimeMs": 1779609906000,
+ "size": 3869,
+ "lines": 93,
"role": "",
"imports": [
"src/utils"
@@ -150,9 +504,9 @@
]
},
"src/core/responseRecovery.ts": {
- "mtimeMs": 1779510440000,
- "size": 15870,
- "lines": 293,
+ "mtimeMs": 1779598805000,
+ "size": 16753,
+ "lines": 310,
"role": "Response Recovery — Thought Quarantine + Final-only Retry + Auto-Continuation The user already asked their question; they're waiting for an answer, not for a chance to babysit the generation engine. S",
"imports": [
"src/lib/contextManager"
@@ -247,10 +601,96 @@
"role": "Project Timeline",
"imports": []
},
+ "src/extension/calendarSetup.ts": {
+ "mtimeMs": 1779631650000,
+ "size": 10551,
+ "lines": 214,
+ "role": "",
+ "imports": [
+ "src/features/calendar"
+ ]
+ },
+ "src/extension/initialSetup.ts": {
+ "mtimeMs": 1779631670000,
+ "size": 2922,
+ "lines": 60,
+ "role": "",
+ "imports": [
+ "src/utils"
+ ]
+ },
+ "src/extension/lessonCommands.ts": {
+ "mtimeMs": 1779632141000,
+ "size": 2666,
+ "lines": 46,
+ "role": "",
+ "imports": [
+ "src/skills/agentKnowledgeMap",
+ "src/extension/lessons",
+ "src/agent"
+ ]
+ },
+ "src/extension/lessons.ts": {
+ "mtimeMs": 1779631363000,
+ "size": 7324,
+ "lines": 135,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/retrieval",
+ "src/retrieval/lessonHelpers"
+ ]
+ },
+ "src/extension/providerCommands.ts": {
+ "mtimeMs": 1779631883000,
+ "size": 7565,
+ "lines": 136,
+ "role": "",
+ "imports": [
+ "src/sidebarProvider",
+ "src/extension/calendarSetup",
+ "src/features/company",
+ "src/features/calendar",
+ "src/features/devilAgent"
+ ]
+ },
+ "src/extension/scaffoldCommand.ts": {
+ "mtimeMs": 1779632128000,
+ "size": 2300,
+ "lines": 50,
+ "role": "",
+ "imports": [
+ "src/scaffolder/projectScaffolder",
+ "src/scaffolder/templates"
+ ]
+ },
+ "src/extension/settingsSetup.ts": {
+ "mtimeMs": 1779632397000,
+ "size": 3063,
+ "lines": 64,
+ "role": "",
+ "imports": [
+ "src/features/settings/settingsPanelProvider",
+ "src/retrieval",
+ "src/extension/telegramCommands",
+ "src/integrations/telegram/telegramBot",
+ "src/integrations/telegram/telegramClient"
+ ]
+ },
+ "src/extension/telegramCommands.ts": {
+ "mtimeMs": 1779632383000,
+ "size": 4802,
+ "lines": 103,
+ "role": "",
+ "imports": [
+ "src/integrations/telegram/telegramBot",
+ "src/integrations/telegram/telegramClient"
+ ]
+ },
"src/extension.ts": {
- "mtimeMs": 1779543586000,
- "size": 66247,
- "lines": 1251,
+ "mtimeMs": 1779666646000,
+ "size": 16725,
+ "lines": 354,
"role": "",
"imports": [
"src/utils",
@@ -268,21 +708,20 @@
"src/features/approval/approvalQueue",
"src/features/approval/approvalPanelProvider",
"src/features/approval/approvalStatusBar",
- "src/scaffolder/projectScaffolder",
- "src/scaffolder/templates",
"src/integrations/telegram/telegramClient",
"src/integrations/telegram/telegramBot",
- "src/core/services",
- "src/features/company",
- "src/features/settings/settingsPanelProvider",
- "src/skills/agentKnowledgeMap",
"src/retrieval",
"src/retrieval/lessonHelpers",
- "src/skills/scopedBrainRetriever",
- "src/features/setup/datacollectSetup",
- "src/integrations/telegram/conversationHistory",
- "src/features/calendar",
- "src/features/devilAgent"
+ "src/extension/calendarSetup",
+ "src/extension/initialSetup",
+ "src/features/stocks",
+ "src/extension/providerCommands",
+ "src/extension/scaffoldCommand",
+ "src/extension/lessonCommands",
+ "src/extension/telegramCommands",
+ "src/extension/settingsSetup",
+ "src/integrations/telegram/telegramSetup",
+ "src/features/setup/datacollectSetup"
]
},
"src/features/approval/approvalPanelProvider.ts": {
@@ -378,9 +817,9 @@
]
},
"src/features/astraOffice/view/runtime.ts": {
- "mtimeMs": 1779492050000,
- "size": 91938,
- "lines": 1932,
+ "mtimeMs": 1779609597000,
+ "size": 93954,
+ "lines": 1963,
"role": "자동 분리: src/sidebarProvider.ts 4002-5116 (IIFE 본문) 에서 추출. 동작 동등. ${assets.derivedBase} placeholder 는 panelHtml 에서 .replace() 로 실제 값 주입. 다음 세션에서 OfficeSnapshot 기반으로 단계적으로 잘라낼 예정.",
"imports": []
},
@@ -430,9 +869,9 @@
"imports": []
},
"src/features/company/agents.ts": {
- "mtimeMs": 1778936611000,
- "size": 15031,
- "lines": 211,
+ "mtimeMs": 1779608334000,
+ "size": 37591,
+ "lines": 531,
"role": "기본 에이전트 로스터 — 1인 기업 모드의 출고 디폴트. 설계 의도: 소프트웨어/게임 개발 IT 회사의 1인 기업 운영을 가정. 한 사람이 기획 → 디자인 → 개발 → QA → 출시 → 운영/마케팅을 모두 책임질 때 필요한 직군을 빠짐없이 커버하되 역할이 겹치지 않게 분리한다. 직군 구분 (혼동 방지): - 기획자(business) : 무엇을 만들지 정의 ",
"imports": [
"src/features/company/types"
@@ -476,9 +915,9 @@
]
},
"src/features/company/dispatcher.ts": {
- "mtimeMs": 1779536000000,
- "size": 73381,
- "lines": 1442,
+ "mtimeMs": 1779631120000,
+ "size": 69508,
+ "lines": 1365,
"role": "Sequential dispatcher for 1인 기업 모드. Drives one company \"turn\": user prompt → CEO planner (JSON {brief, tasks}) → for each task in plan: dispatch one specialist (sequentially) - build specialist prompt",
"imports": [
"src/core/services",
@@ -493,14 +932,25 @@
"src/features/company/sessionStore",
"src/features/company/resumeStore",
"src/features/company/telegramReport",
- "src/features/company/types",
- "src/features/company/intentAlignment",
- "src/features/calendar",
- "src/features/tasks",
- "src/config",
"src/features/selfReflector/selfReflectorVerifier",
"src/features/selfReflector/selfReflectorExecution",
- "src/features/selfReflector/selfReflectorHollow"
+ "src/features/selfReflector/selfReflectorHollow",
+ "src/features/company/intentAlignment",
+ "src/config",
+ "src/features/company/types",
+ "src/features/calendar",
+ "src/features/tasks",
+ "src/features/company/dispatcherHelpers"
+ ]
+ },
+ "src/features/company/dispatcherHelpers.ts": {
+ "mtimeMs": 1779631073000,
+ "size": 5866,
+ "lines": 121,
+ "role": "",
+ "imports": [
+ "src/features/company/companyConfig",
+ "src/features/company/types"
]
},
"src/features/company/index.ts": {
@@ -600,9 +1050,9 @@
"imports": []
},
"src/features/company/resumeStore.ts": {
- "mtimeMs": 1778768128000,
- "size": 5672,
- "lines": 134,
+ "mtimeMs": 1779608998000,
+ "size": 6030,
+ "lines": 140,
"role": "Disk persistence for company-turn resume state. 각 turn의 sessionDir 안에 resume.json을 두고, dispatcher가 매 의미 있는 시점(plan 확정 / 각 stage 직후 / abort 시점)에 현재 상태를 덮어쓴다. 재개 시점에는 이 파일을 읽어 nextIndex 부터 dispatch 재개. ",
"imports": [
"src/utils",
@@ -641,22 +1091,63 @@
"imports": []
},
"src/features/datacollect/bridgeClient.ts": {
- "mtimeMs": 1779542176000,
- "size": 5949,
- "lines": 129,
+ "mtimeMs": 1779609459000,
+ "size": 7046,
+ "lines": 164,
"role": "",
"imports": []
},
+ "src/features/datacollect/prompts/meetPrompt.ts": {
+ "mtimeMs": 1779630862000,
+ "size": 2521,
+ "lines": 72,
+ "role": "회의 녹취 텍스트 → 사실 기반 구조화 회의록(Actionable Minutes) LLM 프롬프트. 사용자 정의 규칙: Fact/Discussion/Decision/Risk/Action 분류, 메타데이터 우선.",
+ "imports": []
+ },
+ "src/features/datacollect/prompts/synthesisPrompt.ts": {
+ "mtimeMs": 1779630675000,
+ "size": 13838,
+ "lines": 257,
+ "role": "/benchmark 보고서의 3 파트 분할 — 1: 4-렌즈 / 2: IA + 토큰 / 3: 재구축 명세.",
+ "imports": []
+ },
+ "src/features/datacollect/prompts/wikifyPrompt.ts": {
+ "mtimeMs": 1779630813000,
+ "size": 4509,
+ "lines": 88,
+ "role": "추출된 웹사이트 본문 → Datacollect Research(P-Reinforce v3.0)와 동일한 위키 문서 프롬프트. Bridge의 /api/research/synthesize 템플릿을 웹 본문 소스용으로 이식.",
+ "imports": []
+ },
+ "src/features/datacollect/prompts/youtubePrompts.ts": {
+ "mtimeMs": 1779630783000,
+ "size": 17777,
+ "lines": 331,
+ "role": "/youtube slash command 의 LLM 입력 빌더 + 자막 변환 헬퍼. - formatHms / fullScriptFromSegments / bucketSegments — segment list 가공 - YoutubeAnalysisMode — info/benchmark/both 라우팅 enum (slashRouter 가 사용) - buildIn",
+ "imports": []
+ },
+ "src/features/datacollect/scheduling/calendarHelpers.ts": {
+ "mtimeMs": 1779630862000,
+ "size": 4133,
+ "lines": 89,
+ "role": "/meet 슬래시 명령의 후처리 — 회의록에서 action items 를 뽑아 캘린더 task 일정을 계산하는 stateless helpers. slashRouter 의 inline 블록을 분리. - addBusinessDays(base, n) — 토·일 제외 영업일 n 일 후 날짜 - toYmd(d) — Date → 'YYYY-MM-DD' - extrac",
+ "imports": []
+ },
"src/features/datacollect/slashRouter.ts": {
- "mtimeMs": 1779548421000,
- "size": 97168,
- "lines": 1797,
+ "mtimeMs": 1779668795000,
+ "size": 61939,
+ "lines": 1132,
"role": "",
"imports": [
"src/utils",
"src/features/datacollect/bridgeClient",
"src/features/calendar",
- "src/features/setup/datacollectSetup"
+ "src/features/setup/datacollectSetup",
+ "src/features/datacollect/prompts/synthesisPrompt",
+ "src/features/datacollect/prompts/youtubePrompts",
+ "src/features/datacollect/prompts/wikifyPrompt",
+ "src/features/datacollect/prompts/meetPrompt",
+ "src/features/datacollect/scheduling/calendarHelpers",
+ "src/features/stocks"
]
},
"src/features/devilAgent/devilPrompt.ts": {
@@ -724,9 +1215,9 @@
]
},
"src/features/projectChronicle/guardPrompt.ts": {
- "mtimeMs": 1777870211000,
- "size": 6880,
- "lines": 75,
+ "mtimeMs": 1779665457000,
+ "size": 8969,
+ "lines": 106,
"role": "",
"imports": [
"src/features/projectChronicle/types"
@@ -879,9 +1370,9 @@
]
},
"src/features/settings/settingsPanelProvider.ts": {
- "mtimeMs": 1779597205000,
- "size": 32670,
- "lines": 701,
+ "mtimeMs": 1779610047000,
+ "size": 33094,
+ "lines": 707,
"role": "",
"imports": [
"src/integrations/telegram/telegramClient",
@@ -920,6 +1411,165 @@
"src/features/calendar/calendarApi"
]
},
+ "src/features/stocks/discoveryAnalyzer.ts": {
+ "mtimeMs": 1779670188000,
+ "size": 10289,
+ "lines": 237,
+ "role": "",
+ "imports": [
+ "src/core/services",
+ "src/utils",
+ "src/extension/telegramCommands",
+ "src/integrations/telegram/telegramClient",
+ "src/features/stocks/stockDiscovery"
+ ]
+ },
+ "src/features/stocks/index.ts": {
+ "mtimeMs": 1779668795000,
+ "size": 119,
+ "lines": 2,
+ "role": "",
+ "imports": [
+ "src/features/stocks/stocksWatcher",
+ "src/features/stocks/slashStocks"
+ ]
+ },
+ "src/features/stocks/llmJudge.ts": {
+ "mtimeMs": 1779667101000,
+ "size": 6884,
+ "lines": 127,
+ "role": "",
+ "imports": [
+ "src/core/services",
+ "src/utils",
+ "src/features/stocks/stocksStore",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/naverFundamentals.ts": {
+ "mtimeMs": 1779668334000,
+ "size": 7077,
+ "lines": 161,
+ "role": "",
+ "imports": [
+ "src/utils"
+ ]
+ },
+ "src/features/stocks/naverScreener.ts": {
+ "mtimeMs": 1779668297000,
+ "size": 6442,
+ "lines": 151,
+ "role": "",
+ "imports": [
+ "src/utils"
+ ]
+ },
+ "src/features/stocks/sheetsSync.ts": {
+ "mtimeMs": 1779666427000,
+ "size": 4193,
+ "lines": 99,
+ "role": "",
+ "imports": [
+ "src/features/sheets",
+ "src/utils",
+ "src/features/stocks/signalClassifier",
+ "src/features/stocks/stocksStore",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/signalClassifier.ts": {
+ "mtimeMs": 1779666385000,
+ "size": 2749,
+ "lines": 69,
+ "role": "",
+ "imports": [
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/slashStocks.ts": {
+ "mtimeMs": 1779670229000,
+ "size": 13254,
+ "lines": 279,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/features/stocks/stocksStore",
+ "src/features/stocks/yahooClient",
+ "src/features/stocks/signalClassifier",
+ "src/features/stocks/sheetsSync",
+ "src/features/stocks/llmJudge",
+ "src/features/stocks/telegramReport",
+ "src/features/stocks/stocksWatcher",
+ "src/features/stocks/stockDiscovery",
+ "src/features/stocks/discoveryAnalyzer",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/stockDiscovery.ts": {
+ "mtimeMs": 1779667941000,
+ "size": 7408,
+ "lines": 159,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/features/stocks/naverScreener",
+ "src/features/stocks/naverFundamentals",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/stocksStore.ts": {
+ "mtimeMs": 1779666348000,
+ "size": 4027,
+ "lines": 96,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/stocksWatcher.ts": {
+ "mtimeMs": 1779666551000,
+ "size": 6367,
+ "lines": 163,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/features/stocks/stocksStore",
+ "src/features/stocks/yahooClient",
+ "src/features/stocks/telegramReport",
+ "src/features/stocks/sheetsSync"
+ ]
+ },
+ "src/features/stocks/telegramReport.ts": {
+ "mtimeMs": 1779666511000,
+ "size": 5218,
+ "lines": 117,
+ "role": "",
+ "imports": [
+ "src/integrations/telegram/telegramClient",
+ "src/extension/telegramCommands",
+ "src/utils",
+ "src/features/stocks/stocksStore",
+ "src/features/stocks/signalClassifier",
+ "src/features/stocks/types"
+ ]
+ },
+ "src/features/stocks/types.ts": {
+ "mtimeMs": 1779666327000,
+ "size": 2135,
+ "lines": 53,
+ "role": "Stocks 모듈 공유 타입. investresults/targetstocks.json 스키마를 그대로 받아서, ConnectAI 의 /.astra/stocks.json 으로 옮긴 뒤 같은 필드명을 유지. 한글 필드명은 사용자의 도메인 데이터라 변경하지 않는다 — 마이그레이션 충돌 회피 + 사용자가 직접 JSON 편집할 때 frictio",
+ "imports": []
+ },
+ "src/features/stocks/yahooClient.ts": {
+ "mtimeMs": 1779666367000,
+ "size": 2555,
+ "lines": 60,
+ "role": "",
+ "imports": [
+ "src/utils"
+ ]
+ },
"src/features/tasks/index.ts": {
"mtimeMs": 1778936468000,
"size": 225,
@@ -945,6 +1595,15 @@
"src/utils"
]
},
+ "src/integrations/telegram/promptBuilders.ts": {
+ "mtimeMs": 1779632676000,
+ "size": 7520,
+ "lines": 143,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
"src/integrations/telegram/telegramBot.ts": {
"mtimeMs": 1778421270000,
"size": 11344,
@@ -966,6 +1625,24 @@
"src/utils"
]
},
+ "src/integrations/telegram/telegramSetup.ts": {
+ "mtimeMs": 1779632732000,
+ "size": 9960,
+ "lines": 176,
+ "role": "",
+ "imports": [
+ "src/integrations/telegram/telegramBot",
+ "src/integrations/telegram/telegramClient",
+ "src/core/services",
+ "src/utils",
+ "src/skills/agentKnowledgeMap",
+ "src/skills/scopedBrainRetriever",
+ "src/sidebarProvider",
+ "src/integrations/telegram/promptBuilders",
+ "src/features/company",
+ "src/integrations/telegram/conversationHistory"
+ ]
+ },
"src/integrations/telegram/types.ts": {
"mtimeMs": 1778252305000,
"size": 1255,
@@ -973,6 +1650,212 @@
"role": "Subset of the Telegram Bot API types we actually consume. Source: https://core.telegram.org/bots/api Only fields the bot reads or writes are typed — leaving the rest as unknown keeps the surface narro",
"imports": []
},
+ "src/lib/contextBuilders/astraModeArchitecture.ts": {
+ "mtimeMs": 1779601304000,
+ "size": 3926,
+ "lines": 56,
+ "role": "Astra Mode Architecture Context Builder. 의도: 사용자가 Astra 자체의 mode 디자인 (Guard vs Multi-Agent 가 별도 모드여야 하는지) 을 묻는 메타 질문에 답할 때, 모델이 일반론적 답이 아니라 현재 코드베이스 의 실제 구조 를 보고 답하게 하려고 시스템 프롬프트에 추가 컨텍스트 블록을 주입. 이 bu",
+ "imports": []
+ },
+ "src/lib/contextBuilders/droppedHistorySummary.ts": {
+ "mtimeMs": 1779618681000,
+ "size": 2299,
+ "lines": 52,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/engineMessages.ts": {
+ "mtimeMs": 1779622213000,
+ "size": 2188,
+ "lines": 56,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/historyTransform.ts": {
+ "mtimeMs": 1779622758000,
+ "size": 3671,
+ "lines": 77,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/jarvisProjectBrief.ts": {
+ "mtimeMs": 1779619198000,
+ "size": 2860,
+ "lines": 59,
+ "role": "",
+ "imports": [
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/projectEvidence",
+ "src/lib/contextBuilders/thinkingPartnerContract"
+ ]
+ },
+ "src/lib/contextBuilders/lastTopicLine.ts": {
+ "mtimeMs": 1779618707000,
+ "size": 1057,
+ "lines": 19,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/lmStudioSampling.ts": {
+ "mtimeMs": 1779630388000,
+ "size": 1268,
+ "lines": 29,
+ "role": "",
+ "imports": [
+ "src/config",
+ "src/lmstudio/streamer"
+ ]
+ },
+ "src/lib/contextBuilders/localProjectIntent.ts": {
+ "mtimeMs": 1779620557000,
+ "size": 13912,
+ "lines": 233,
+ "role": "",
+ "imports": [
+ "src/lib/contextBuilders/promptDetection"
+ ]
+ },
+ "src/lib/contextBuilders/localProjectPath.ts": {
+ "mtimeMs": 1779621240000,
+ "size": 16718,
+ "lines": 328,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/config",
+ "src/security",
+ "src/lib/contextBuilders/localProjectIntent"
+ ]
+ },
+ "src/lib/contextBuilders/memoryContext.ts": {
+ "mtimeMs": 1779623151000,
+ "size": 11034,
+ "lines": 233,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/config",
+ "src/memory",
+ "src/retrieval",
+ "src/retrieval/lessonHelpers",
+ "src/retrieval/embeddings",
+ "src/retrieval/brainIndex",
+ "src/skills/agentKnowledgeMap",
+ "src/retrieval/knowledgeMix"
+ ]
+ },
+ "src/lib/contextBuilders/modelCandidates.ts": {
+ "mtimeMs": 1779618716000,
+ "size": 833,
+ "lines": 20,
+ "role": "사용자 지정 modelName 으로 추론 호출 시도할 때, 첫 호출이 404 / not-loaded 류로 실패할 가능성에 대비한 fallback 후보 목록을 만든다. LM Studio 한정: gemma3:4b 같은 \":quant suffix\" 형태가 안 먹히면 base name (gemma3) 도 시도하게 한 줄 더 push. Ollama 는 항상 정확한 ",
+ "imports": []
+ },
+ "src/lib/contextBuilders/multiAgentRouting.ts": {
+ "mtimeMs": 1779622465000,
+ "size": 5161,
+ "lines": 96,
+ "role": "",
+ "imports": [
+ "src/config",
+ "src/lib/contextManager",
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/astraModeArchitecture",
+ "src/lib/contextBuilders/localProjectIntent"
+ ]
+ },
+ "src/lib/contextBuilders/outputSanitization.ts": {
+ "mtimeMs": 1779622739000,
+ "size": 5239,
+ "lines": 99,
+ "role": "모델 출력 후처리 (post-stream sanitization). 모두 stateless pure transform. 1) sanitizeAssistantContent — 모델이 답변에 흘려보낸 내부 마커 (rationale, reasoning channels, Harmony/GPT-OSS 채널 마커, [PROBLEM]/[GOAL]/[REASONING] ",
+ "imports": []
+ },
+ "src/lib/contextBuilders/priorTurnConclusion.ts": {
+ "mtimeMs": 1779635475000,
+ "size": 3686,
+ "lines": 75,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/projectEvidence.ts": {
+ "mtimeMs": 1779619101000,
+ "size": 2132,
+ "lines": 39,
+ "role": "Project-knowledge / local-path 컨텍스트 블록 안에서 증거 파일 목록을 뽑아내는 pure parser 모음. 두 종류 컨텍스트 포맷이 살짝 달라 함수를 둘로 둠: - extractEvidenceFilesFromProjectKnowledge: ## Evidence Files 블록 (project knowledge overview 문서 ",
+ "imports": []
+ },
+ "src/lib/contextBuilders/projectKnowledge.ts": {
+ "mtimeMs": 1779620833000,
+ "size": 9514,
+ "lines": 163,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/lib/contextBuilders/projectEvidence"
+ ]
+ },
+ "src/lib/contextBuilders/promptDetection.ts": {
+ "mtimeMs": 1779621960000,
+ "size": 5483,
+ "lines": 85,
+ "role": "사용자 prompt 의 의도 분류 류 detection helpers. 모두 stateless 정규식 매칭. 옛 코드는 agent.ts 의 private 메서드로 박혀 있었는데, system prompt 빌더 (buildJarvisProjectBriefContext 등) 가 이걸 의존하면서 god-file 안에서 서로 얽힘. 헬퍼만 먼저 떼면 의존 그래프가",
+ "imports": []
+ },
+ "src/lib/contextBuilders/recentProjectKnowledge.ts": {
+ "mtimeMs": 1779621624000,
+ "size": 8714,
+ "lines": 191,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/agent",
+ "src/lib/contextBuilders/projectEvidence"
+ ]
+ },
+ "src/lib/contextBuilders/secondBrainInventory.ts": {
+ "mtimeMs": 1779619757000,
+ "size": 6210,
+ "lines": 104,
+ "role": "",
+ "imports": [
+ "src/config",
+ "src/features/secondBrainTrace"
+ ]
+ },
+ "src/lib/contextBuilders/systemPromptShaping.ts": {
+ "mtimeMs": 1779621987000,
+ "size": 3122,
+ "lines": 78,
+ "role": "System prompt 의 조립 단계 에서 일어나는 두 가지 stateless 변환: 1) stripAstraFormattingForAgentMode — Agent Mode v3 에서 Astra 기본 시스템 프롬프트의 포맷/페르소나/스탠스 섹션을 제거. 에이전트 자체 프롬프트와 섹션 헤더가 충돌해 모델이 두 톤을 섞어 답하는 회귀를 막는다. 2) comp",
+ "imports": []
+ },
+ "src/lib/contextBuilders/thinFollowUp.ts": {
+ "mtimeMs": 1779635357000,
+ "size": 2097,
+ "lines": 39,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/lib/contextBuilders/thinkingPartnerContract.ts": {
+ "mtimeMs": 1779618664000,
+ "size": 1289,
+ "lines": 21,
+ "role": "Thinking partner response contract — system prompt 에 항상 prepend 되는 6항목 응답 규약. 100% stateless 한 정적 문자열이라 god-file agent.ts 에 박혀 있을 이유 없음. 단위 테스트 / 다른 모드에서 재사용 / contract 수정 시 변경 범위 최소화를 위해 별도 모듈로 격리. 6",
+ "imports": []
+ },
"src/lib/contextManager.ts": {
"mtimeMs": 1779513818000,
"size": 13258,
@@ -999,9 +1882,9 @@
]
},
"src/lib/engine.ts": {
- "mtimeMs": 1779597103000,
- "size": 51410,
- "lines": 1103,
+ "mtimeMs": 1779609235000,
+ "size": 52150,
+ "lines": 1114,
"role": "",
"imports": [
"src/core/lock",
@@ -1014,9 +1897,9 @@
]
},
"src/lib/formatter.ts": {
- "mtimeMs": 1777980992000,
- "size": 3851,
- "lines": 81,
+ "mtimeMs": 1779609099000,
+ "size": 4676,
+ "lines": 96,
"role": "",
"imports": [
"src/lib/engine"
@@ -1272,10 +2155,175 @@
"src/sidebarProvider"
]
},
+ "src/sidebar/builders/agentSkillResolver.ts": {
+ "mtimeMs": 1779628200000,
+ "size": 4250,
+ "lines": 90,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/skills/agentKnowledgeMap",
+ "src/skills/externalSkillLoader"
+ ]
+ },
+ "src/sidebar/builders/alignmentCardPayloads.ts": {
+ "mtimeMs": 1779628760000,
+ "size": 1517,
+ "lines": 41,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
+ "src/sidebar/builders/alignmentRouting.ts": {
+ "mtimeMs": 1779630169000,
+ "size": 1918,
+ "lines": 41,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
+ "src/sidebar/builders/architecturePayloads.ts": {
+ "mtimeMs": 1779629073000,
+ "size": 4306,
+ "lines": 107,
+ "role": "",
+ "imports": [
+ "src/features/projectChronicle",
+ "src/features/projectArchitecture"
+ ]
+ },
+ "src/sidebar/builders/autoChronicleClassifier.ts": {
+ "mtimeMs": 1779627010000,
+ "size": 4262,
+ "lines": 88,
+ "role": "",
+ "imports": []
+ },
+ "src/sidebar/builders/autoChroniclePayloads.ts": {
+ "mtimeMs": 1779627191000,
+ "size": 4706,
+ "lines": 116,
+ "role": "",
+ "imports": [
+ "src/features/projectChronicle",
+ "src/sidebar/builders/textHelpers",
+ "src/sidebar/builders/autoChronicleClassifier"
+ ]
+ },
+ "src/sidebar/builders/brainProfileHelpers.ts": {
+ "mtimeMs": 1779626545000,
+ "size": 1109,
+ "lines": 24,
+ "role": "Brain profile lifecycle 의 pure helpers — sidebarProvider 의 add/edit/delete 흐름에서 modal UI 와 config 쓰기를 제외한 데이터 변환 만 격리. 현재 한 함수만 있지만 향후 edit 의 \"변경된 필드만 머지\", delete 의 \"next active 선택 규칙\" 등 다른 pure trans",
+ "imports": []
+ },
+ "src/sidebar/builders/chroniclePayloads.ts": {
+ "mtimeMs": 1779625757000,
+ "size": 1793,
+ "lines": 49,
+ "role": "",
+ "imports": [
+ "src/features/projectChronicle"
+ ]
+ },
+ "src/sidebar/builders/companyPayloads.ts": {
+ "mtimeMs": 1779625178000,
+ "size": 8984,
+ "lines": 202,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
+ "src/sidebar/builders/companyTurnEmitter.ts": {
+ "mtimeMs": 1779629947000,
+ "size": 2485,
+ "lines": 54,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
+ "src/sidebar/builders/dispatcherDepsBuilder.ts": {
+ "mtimeMs": 1779629723000,
+ "size": 3461,
+ "lines": 68,
+ "role": "",
+ "imports": [
+ "src/features/company",
+ "src/sidebar/managers/approvalGates",
+ "src/core/services",
+ "src/config"
+ ]
+ },
+ "src/sidebar/builders/proactiveSuggestions.ts": {
+ "mtimeMs": 1779626190000,
+ "size": 1485,
+ "lines": 30,
+ "role": "Proactive suggestion tip 한 줄 텍스트 — 사이드바가 사용자의 특정 탐색 행동 (settings 열기, brain sync 보기, agent 선택 등) 을 감지하면 채팅에 callout 으로 잠깐 띄우는 도움말. Stateless lookup table — sidebarProvider 의 옛 handleProactiveSuggestion",
+ "imports": []
+ },
+ "src/sidebar/builders/projectProfileFactories.ts": {
+ "mtimeMs": 1779627696000,
+ "size": 4484,
+ "lines": 106,
+ "role": "",
+ "imports": [
+ "src/features/projectChronicle",
+ "src/sidebar/builders/textHelpers"
+ ]
+ },
+ "src/sidebar/builders/promptAttachments.ts": {
+ "mtimeMs": 1779627922000,
+ "size": 5975,
+ "lines": 117,
+ "role": "",
+ "imports": [
+ "src/utils"
+ ]
+ },
+ "src/sidebar/builders/sessionPayloads.ts": {
+ "mtimeMs": 1779628917000,
+ "size": 2334,
+ "lines": 63,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/sidebar/managers/chatSessionStore"
+ ]
+ },
+ "src/sidebar/builders/statusPayloads.ts": {
+ "mtimeMs": 1779624672000,
+ "size": 4354,
+ "lines": 107,
+ "role": "",
+ "imports": [
+ "src/config"
+ ]
+ },
+ "src/sidebar/builders/textHelpers.ts": {
+ "mtimeMs": 1779625537000,
+ "size": 1399,
+ "lines": 34,
+ "role": "sidebarProvider 가 chronicle 기록 / 세션 title / YAML frontmatter 등에서 공통으로 쓰는 작은 텍스트 변환 헬퍼. 모두 stateless. - slugify(value) — kebab-case slug (한/영/숫자 보존, 48자 cap) - summarizeForTitle(value) — chat title 표시용",
+ "imports": []
+ },
+ "src/sidebar/builders/wikiRaw.ts": {
+ "mtimeMs": 1779625926000,
+ "size": 4136,
+ "lines": 97,
+ "role": "",
+ "imports": [
+ "src/agent",
+ "src/sidebar/builders/textHelpers"
+ ]
+ },
"src/sidebar/chatHandlers.ts": {
- "mtimeMs": 1779536404000,
- "size": 23810,
- "lines": 417,
+ "mtimeMs": 1779669848000,
+ "size": 25980,
+ "lines": 451,
"role": "",
"imports": [
"src/sidebarProvider",
@@ -1308,10 +2356,123 @@
"src/features/company/resumeStore"
]
},
+ "src/sidebar/managers/agentSkillStore.ts": {
+ "mtimeMs": 1779626174000,
+ "size": 5563,
+ "lines": 128,
+ "role": "",
+ "imports": []
+ },
+ "src/sidebar/managers/approvalGates.ts": {
+ "mtimeMs": 1779601410000,
+ "size": 2755,
+ "lines": 63,
+ "role": "",
+ "imports": [
+ "src/features/company/dispatcher"
+ ]
+ },
+ "src/sidebar/managers/architectureWatch.ts": {
+ "mtimeMs": 1779617624000,
+ "size": 4230,
+ "lines": 90,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/features/projectArchitecture",
+ "src/features/projectChronicle"
+ ]
+ },
+ "src/sidebar/managers/chatSessionStore.ts": {
+ "mtimeMs": 1779623748000,
+ "size": 4755,
+ "lines": 110,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/agent"
+ ]
+ },
+ "src/sidebar/managers/chronicleProjectStore.ts": {
+ "mtimeMs": 1779627762000,
+ "size": 2378,
+ "lines": 50,
+ "role": "",
+ "imports": [
+ "src/features/projectChronicle",
+ "src/sidebar/builders/projectProfileFactories"
+ ]
+ },
+ "src/sidebar/managers/companyTurn.ts": {
+ "mtimeMs": 1779617783000,
+ "size": 4397,
+ "lines": 116,
+ "role": "",
+ "imports": [
+ "src/features/company"
+ ]
+ },
+ "src/sidebar/managers/modelDiscovery.ts": {
+ "mtimeMs": 1779624023000,
+ "size": 6127,
+ "lines": 146,
+ "role": "",
+ "imports": [
+ "src/utils",
+ "src/sidebarProvider"
+ ]
+ },
+ "src/sidebar/managers/pixelOfficeHelpers.ts": {
+ "mtimeMs": 1779624267000,
+ "size": 6199,
+ "lines": 156,
+ "role": "",
+ "imports": [
+ "src/features/company",
+ "src/features/astraOffice"
+ ]
+ },
+ "src/sidebar/managers/pixelOfficeLayoutStore.ts": {
+ "mtimeMs": 1779624235000,
+ "size": 1672,
+ "lines": 37,
+ "role": "",
+ "imports": [
+ "src/features/astraOffice"
+ ]
+ },
+ "src/sidebar/managers/pixelOfficeState.ts": {
+ "mtimeMs": 1779623462000,
+ "size": 3494,
+ "lines": 77,
+ "role": "",
+ "imports": [
+ "src/features/company",
+ "src/features/astraOffice"
+ ]
+ },
+ "src/sidebar/managers/sessionStateStore.ts": {
+ "mtimeMs": 1779628403000,
+ "size": 2851,
+ "lines": 63,
+ "role": "",
+ "imports": [
+ "src/agent"
+ ]
+ },
+ "src/sidebar/registry.ts": {
+ "mtimeMs": 1779600922000,
+ "size": 1898,
+ "lines": 51,
+ "role": "",
+ "imports": [
+ "src/sidebarProvider"
+ ]
+ },
"src/sidebarProvider.ts": {
- "mtimeMs": 1779536519000,
- "size": 201315,
- "lines": 4340,
+ "mtimeMs": 1779635440000,
+ "size": 150473,
+ "lines": 3194,
"role": "",
"imports": [
"src/utils",
@@ -1319,22 +2480,51 @@
"src/agent",
"src/bridge",
"src/features/projectChronicle",
+ "src/lib/contextBuilders/thinFollowUp",
"src/lmstudio/lifecycleManager",
"src/lmstudio/activityTracker",
"src/sidebar/chatHandlers",
"src/sidebar/brainHandlers",
"src/sidebar/chronicleHandlers",
"src/sidebar/agentHandlers",
+ "src/sidebar/registry",
+ "src/sidebar/managers/approvalGates",
+ "src/sidebar/managers/architectureWatch",
+ "src/sidebar/managers/companyTurn",
+ "src/sidebar/managers/pixelOfficeState",
+ "src/sidebar/managers/pixelOfficeHelpers",
+ "src/sidebar/managers/chatSessionStore",
+ "src/sidebar/managers/modelDiscovery",
+ "src/sidebar/managers/pixelOfficeLayoutStore",
+ "src/sidebar/builders/statusPayloads",
+ "src/sidebar/builders/companyPayloads",
+ "src/sidebar/builders/textHelpers",
+ "src/sidebar/managers/chronicleProjectStore",
+ "src/sidebar/builders/chroniclePayloads",
+ "src/sidebar/builders/wikiRaw",
+ "src/sidebar/managers/agentSkillStore",
+ "src/sidebar/builders/proactiveSuggestions",
+ "src/sidebar/builders/brainProfileHelpers",
+ "src/sidebar/builders/autoChronicleClassifier",
+ "src/sidebar/builders/autoChroniclePayloads",
+ "src/sidebar/builders/architecturePayloads",
+ "src/sidebar/builders/projectProfileFactories",
+ "src/sidebar/builders/promptAttachments",
+ "src/sidebar/builders/agentSkillResolver",
+ "src/sidebar/managers/sessionStateStore",
+ "src/sidebar/builders/sessionPayloads",
+ "src/sidebar/builders/alignmentCardPayloads",
+ "src/sidebar/builders/dispatcherDepsBuilder",
+ "src/sidebar/builders/companyTurnEmitter",
+ "src/sidebar/builders/alignmentRouting",
"src/skills/agentKnowledgeMap",
"src/retrieval/brainIndex",
"src/lib/contextManager",
- "src/skills/externalSkillLoader",
"src/features/projectArchitecture",
"src/features/projectArchitecture/intentDetector",
"src/features/company",
"src/core/services",
- "src/features/astraOffice",
- "src/features/company/dispatcher"
+ "src/features/astraOffice"
]
},
"src/skills/agentKnowledgeMap.ts": {
@@ -1395,9 +2585,9 @@
"imports": []
},
"src/utils.ts": {
- "mtimeMs": 1779513331000,
- "size": 23609,
- "lines": 448,
+ "mtimeMs": 1779665439000,
+ "size": 25886,
+ "lines": 471,
"role": "",
"imports": [
"src/config",
@@ -1412,44 +2602,44 @@
"imports": []
},
"media/settings-panel.html": {
- "mtimeMs": 1779598086000,
- "size": 22426,
- "lines": 398,
+ "mtimeMs": 1779609999000,
+ "size": 23423,
+ "lines": 406,
"role": "Astra Settings",
"imports": []
},
"media/settings-panel.js": {
- "mtimeMs": 1779597166000,
- "size": 21773,
- "lines": 463,
+ "mtimeMs": 1779610021000,
+ "size": 22127,
+ "lines": 469,
"role": "",
"imports": []
},
"media/sidebar.css": {
- "mtimeMs": 1778943817000,
- "size": 88173,
- "lines": 2068,
+ "mtimeMs": 1779667174000,
+ "size": 89705,
+ "lines": 2104,
"role": "Stylesheet",
"imports": []
},
"media/sidebar.html": {
- "mtimeMs": 1779518692000,
- "size": 34475,
- "lines": 538,
+ "mtimeMs": 1779667158000,
+ "size": 34561,
+ "lines": 539,
"role": "Astra",
"imports": []
},
"media/sidebar.js": {
- "mtimeMs": 1779517691000,
- "size": 222774,
- "lines": 3807,
+ "mtimeMs": 1779667223000,
+ "size": 229423,
+ "lines": 3921,
"role": "",
"imports": []
},
"tests/agentEngine.test.ts": {
- "mtimeMs": 1779597242000,
- "size": 18323,
- "lines": 405,
+ "mtimeMs": 1779609795000,
+ "size": 19050,
+ "lines": 413,
"role": "AgentEngine Tests — Chunked Writer Architecture 예전 buildup(planner → researcher → reflector → writer → synthesizer)을 단일 ChunkedWriter 의 outline → section[N] → polish 로 교체한 뒤의 회귀 테스트. 다루는 범위: 1. ErrorC",
"imports": [
"src/lib/engine",
@@ -1520,6 +2710,15 @@
"src/utils"
]
},
+ "tests/helpers/mockLLMClient.ts": {
+ "mtimeMs": 1779601519000,
+ "size": 3563,
+ "lines": 112,
+ "role": "MockLLMClient — IAIService 의 Mock 구현체. 의도: 회사 모드 dispatcher / ChunkedWriter / ceoPlanner 등 LLM 을 호출하는 코드 경로를 CI 환경에서도 테스트 가능하게. 실제 Ollama / LM Studio 없이도 응답을 미리 정의하거나 동적으로 생성 가능. 사용 예: const ai = new ",
+ "imports": [
+ "src/core/services"
+ ]
+ },
"tests/icsParser.test.ts": {
"mtimeMs": 1778934828000,
"size": 5011,
@@ -1529,6 +2728,15 @@
"src/features/calendar/icsParser"
]
},
+ "tests/integration/mockLLMClient.test.ts": {
+ "mtimeMs": 1779601548000,
+ "size": 2931,
+ "lines": 86,
+ "role": "MockLLMClient 자체의 sanity test. 이게 통과하면 dispatcher / ceoPlanner / ChunkedWriter 등 IAIService 를 받는 코드가 실제 LLM 없이 단위 / integration 테스트 가능. 향후 dispatcher 의 multi-stage flow 같은 큰 integration 테스트는 이 mock 을 ",
+ "imports": [
+ "tests/helpers/mockLLMClient"
+ ]
+ },
"tests/integration_retrieval.test.ts": {
"mtimeMs": 1779536730000,
"size": 4013,
@@ -1570,12 +2778,22 @@
]
},
"tests/localPathPreflight.test.ts": {
- "mtimeMs": 1779510896000,
- "size": 23892,
- "lines": 492,
+ "mtimeMs": 1779622608000,
+ "size": 25010,
+ "lines": 520,
"role": "",
"imports": [
- "src/agent"
+ "src/agent",
+ "src/lib/contextBuilders/historyTransform",
+ "src/lib/contextBuilders/promptDetection",
+ "src/lib/contextBuilders/projectEvidence",
+ "src/lib/contextBuilders/jarvisProjectBrief",
+ "src/lib/contextBuilders/localProjectIntent",
+ "src/lib/contextBuilders/projectKnowledge",
+ "src/lib/contextBuilders/localProjectPath",
+ "src/lib/contextBuilders/recentProjectKnowledge",
+ "src/lib/contextBuilders/astraModeArchitecture",
+ "src/lib/contextBuilders/multiAgentRouting"
]
},
"tests/mocks/vscode.js": {
@@ -2008,7 +3226,7 @@
"imports": []
},
"docs/records/ConnectAI/chronicle.config.json": {
- "mtimeMs": 1779598044000,
+ "mtimeMs": 1779670425000,
"size": 416,
"lines": 11,
"role": "JSON configuration",
diff --git a/.astra/tests/engine/.astra/cache/7fa9e2c0ed212d5dbde1172e996cde86955f34dda22a6e02b95c9adc0a456927.json b/.astra/tests/engine/.astra/cache/7fa9e2c0ed212d5dbde1172e996cde86955f34dda22a6e02b95c9adc0a456927.json
index 7a26fb1..f0c2739 100644
--- a/.astra/tests/engine/.astra/cache/7fa9e2c0ed212d5dbde1172e996cde86955f34dda22a6e02b95c9adc0a456927.json
+++ b/.astra/tests/engine/.astra/cache/7fa9e2c0ed212d5dbde1172e996cde86955f34dda22a6e02b95c9adc0a456927.json
@@ -1,5 +1,5 @@
{
"result": "직답 결과 — single-pass mock 응답입니다.",
- "createdAt": 1779598841531,
+ "createdAt": 1779670266607,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/engine/.astra/cache/8c208151bed9108b665cd93e98fc10d377a9fef641dd359504b8d53aecd0a4c3.json b/.astra/tests/engine/.astra/cache/8c208151bed9108b665cd93e98fc10d377a9fef641dd359504b8d53aecd0a4c3.json
index 1239024..349e8b4 100644
--- a/.astra/tests/engine/.astra/cache/8c208151bed9108b665cd93e98fc10d377a9fef641dd359504b8d53aecd0a4c3.json
+++ b/.astra/tests/engine/.astra/cache/8c208151bed9108b665cd93e98fc10d377a9fef641dd359504b8d53aecd0a4c3.json
@@ -1,5 +1,5 @@
{
- "result": "---\nid: wiki_on\ndate: 2026-05-24T05:00:41.532Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\n직답 결과 — single-pass mock 응답입니다.\n\n직답 결과 — single-pass mock 응답입니다.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `0/100` | ✅ Low |\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- **[DIRECT]** 답변 작성 중... (단일 호출 fast-path) (12ms)\n",
- "createdAt": 1779598841532,
+ "result": "---\nid: wiki_on\ndate: 2026-05-25T00:51:06.608Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\n직답 결과 — single-pass mock 응답입니다.\n\n직답 결과 — single-pass mock 응답입니다.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `0/100` | ✅ Low |\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- **[DIRECT]** 답변 작성 중... (단일 호출 fast-path) (13ms)\n",
+ "createdAt": 1779670266608,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/engine/.astra/missions/wiki_on.json b/.astra/tests/engine/.astra/missions/wiki_on.json
index 27bb20e..9b20a49 100644
--- a/.astra/tests/engine/.astra/missions/wiki_on.json
+++ b/.astra/tests/engine/.astra/missions/wiki_on.json
@@ -1,8 +1,8 @@
{
"missionId": "wiki_on",
"status": "completed",
- "startTime": "2026-05-24T05:00:41.519Z",
- "totalElapsedMs": 14,
+ "startTime": "2026-05-25T00:51:06.593Z",
+ "totalElapsedMs": 15,
"results": {
"direct": "직답 결과 — single-pass mock 응답입니다."
},
@@ -12,16 +12,16 @@
{
"from": "idle",
"to": "direct",
- "durationMs": 12,
+ "durationMs": 13,
"message": "답변 작성 중... (단일 호출 fast-path)",
- "ts": "2026-05-24T05:00:41.531Z"
+ "ts": "2026-05-25T00:51:06.606Z"
},
{
"from": "direct",
"to": "completed",
"durationMs": 2,
"message": "미션 완료",
- "ts": "2026-05-24T05:00:41.533Z"
+ "ts": "2026-05-25T00:51:06.608Z"
}
],
"resilienceMetrics": {
diff --git a/.astra/tests/stress/.astra/cache/21818066876cbf8515758bc351bb3d9d44f32b0e4cd024b2e055db3a0d34417e.json b/.astra/tests/stress/.astra/cache/21818066876cbf8515758bc351bb3d9d44f32b0e4cd024b2e055db3a0d34417e.json
index 394a304..28bd6df 100644
--- a/.astra/tests/stress/.astra/cache/21818066876cbf8515758bc351bb3d9d44f32b0e4cd024b2e055db3a0d34417e.json
+++ b/.astra/tests/stress/.astra/cache/21818066876cbf8515758bc351bb3d9d44f32b0e4cd024b2e055db3a0d34417e.json
@@ -1,5 +1,5 @@
{
"result": "Final report with inconsistencies. This should be long enough to pass validation.",
- "createdAt": 1779598848393,
+ "createdAt": 1779670273525,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/stress/.astra/cache/4fc755e372f1dd80d6bffc7b2ef973124fb64ba505f767c53a783833bbc3fa6a.json b/.astra/tests/stress/.astra/cache/4fc755e372f1dd80d6bffc7b2ef973124fb64ba505f767c53a783833bbc3fa6a.json
index 394a304..28bd6df 100644
--- a/.astra/tests/stress/.astra/cache/4fc755e372f1dd80d6bffc7b2ef973124fb64ba505f767c53a783833bbc3fa6a.json
+++ b/.astra/tests/stress/.astra/cache/4fc755e372f1dd80d6bffc7b2ef973124fb64ba505f767c53a783833bbc3fa6a.json
@@ -1,5 +1,5 @@
{
"result": "Final report with inconsistencies. This should be long enough to pass validation.",
- "createdAt": 1779598848393,
+ "createdAt": 1779670273525,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/stress/.astra/cache/6e559207c4542d959700ff14f360e6575e54853929e991e579e318f2f5a19030.json b/.astra/tests/stress/.astra/cache/6e559207c4542d959700ff14f360e6575e54853929e991e579e318f2f5a19030.json
index 2222f3c..4b77526 100644
--- a/.astra/tests/stress/.astra/cache/6e559207c4542d959700ff14f360e6575e54853929e991e579e318f2f5a19030.json
+++ b/.astra/tests/stress/.astra/cache/6e559207c4542d959700ff14f360e6575e54853929e991e579e318f2f5a19030.json
@@ -1,5 +1,5 @@
{
"result": "[{\"heading\":\"본문\",\"scope\":\"전체 답변\"}]",
- "createdAt": 1779598848392,
+ "createdAt": 1779670273513,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/stress/.astra/cache/f65136cebc95448a7e93a45745cb73b3a5a01af5d82391ec29a25bd72b8239a5.json b/.astra/tests/stress/.astra/cache/f65136cebc95448a7e93a45745cb73b3a5a01af5d82391ec29a25bd72b8239a5.json
index e27bb65..1b27619 100644
--- a/.astra/tests/stress/.astra/cache/f65136cebc95448a7e93a45745cb73b3a5a01af5d82391ec29a25bd72b8239a5.json
+++ b/.astra/tests/stress/.astra/cache/f65136cebc95448a7e93a45745cb73b3a5a01af5d82391ec29a25bd72b8239a5.json
@@ -1,5 +1,5 @@
{
"result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
- "createdAt": 1779598848393,
+ "createdAt": 1779670273519,
"modelVersion": "unknown"
}
\ No newline at end of file
diff --git a/.astra/tests/stress/.astra/missions/stress_conflict_1779598848381.json b/.astra/tests/stress/.astra/missions/stress_conflict_1779670273495.json
similarity index 73%
rename from .astra/tests/stress/.astra/missions/stress_conflict_1779598848381.json
rename to .astra/tests/stress/.astra/missions/stress_conflict_1779670273495.json
index 88efdad..1bfe1f4 100644
--- a/.astra/tests/stress/.astra/missions/stress_conflict_1779598848381.json
+++ b/.astra/tests/stress/.astra/missions/stress_conflict_1779670273495.json
@@ -1,8 +1,8 @@
{
- "missionId": "stress_conflict_1779598848381",
+ "missionId": "stress_conflict_1779670273495",
"status": "completed",
- "startTime": "2026-05-24T05:00:48.381Z",
- "totalElapsedMs": 13,
+ "startTime": "2026-05-25T00:51:13.495Z",
+ "totalElapsedMs": 30,
"results": {
"outline": "[{\"heading\":\"본문\",\"scope\":\"전체 답변\"}]",
"section_0": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.",
@@ -14,30 +14,30 @@
{
"from": "idle",
"to": "outline",
- "durationMs": 11,
+ "durationMs": 12,
"message": "답변 구조 잡는 중...",
- "ts": "2026-05-24T05:00:48.392Z"
+ "ts": "2026-05-25T00:51:13.507Z"
},
{
"from": "outline",
"to": "section",
- "durationMs": 1,
+ "durationMs": 6,
"message": "본문 작성 중...",
- "ts": "2026-05-24T05:00:48.393Z"
+ "ts": "2026-05-25T00:51:13.513Z"
},
{
"from": "section",
"to": "polish",
- "durationMs": 0,
+ "durationMs": 6,
"message": "최종 다듬기 중...",
- "ts": "2026-05-24T05:00:48.393Z"
+ "ts": "2026-05-25T00:51:13.519Z"
},
{
"from": "polish",
"to": "completed",
- "durationMs": 1,
+ "durationMs": 6,
"message": "미션 완료",
- "ts": "2026-05-24T05:00:48.394Z"
+ "ts": "2026-05-25T00:51:13.525Z"
}
],
"resilienceMetrics": {
diff --git a/.vscodeignore b/.vscodeignore
index 22e14ba..4572ea4 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -12,3 +12,30 @@ preview.html
_*.json
_yt_*
_*
+
+# ── 무게 다이어트 (v2.2.92+) ─────────────────────────────
+# Jest 테스트 코드 — 사용자 환경에 불필요
+tests/**
+
+# 스프라이트 원본 (편집용, 런타임엔 derived 만 사용)
+assets/**/*-source.png
+assets/**/sprites/**
+
+# pixelOffice layout 프리뷰 (개발 시 비교용)
+assets/pixelOffice/layout-preview*.png
+
+# 개발 / 빌드 아티팩트
+build_error.log
+diff.txt
+diff_utf8.txt
+task_plan.md
+ARCHITECTURE_ANALYSIS.md
+PATCHNOTES.md
+brain-viz.html
+system_schema.json
+jest.config.js
+
+# 2nd brain 캐시·py 도구·내부 문서 — 사용자에게 불필요
+.secondbrain/**
+core_py/**
+docs/**
diff --git a/docs/records/ConnectAI/chronicle.config.json b/docs/records/ConnectAI/chronicle.config.json
index adb8521..e5787c6 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-23T03:51:11.620Z",
- "updatedAt": "2026-05-24T04:50:03.783Z"
+ "updatedAt": "2026-05-25T00:53:45.126Z"
}
diff --git a/media/settings-panel.html b/media/settings-panel.html
index 8c04e8f..aa0dde9 100644
--- a/media/settings-panel.html
+++ b/media/settings-panel.html
@@ -390,6 +390,14 @@
Chunked 가 답변을 쪼갤 수 있는 최대 섹션 수. 실제 LLM 호출 = `2 + N` 회 (outline 1 + section N + polish 1). 기본 3 (총 5회). 빨리 받고 싶으면 2 (총 4회), 답변을 더 세분화하려면 5 (총 7회).
+
+
+
+
+
+
+
답변의 최종 다듬기 단계(polish) 톤·구조를 직접 정의합니다. 예: 격식체/반말/법률·마케팅 도메인 톤. 빈 값이면 기본 persona (한 줄 요약 + subheading + 5-check) 사용.
+
diff --git a/media/settings-panel.js b/media/settings-panel.js
index aedddca..7f8afe3 100644
--- a/media/settings-panel.js
+++ b/media/settings-panel.js
@@ -50,6 +50,7 @@
const advChatTemp = $('advChatTemp');
const advChunkedSwitch = $('advChunkedSwitch');
const advChunkedMax = $('advChunkedMax');
+ const advPolishPersona = $('advPolishPersona');
// ---- Google (Calendar + Sheets) ----
const gClientId = $('gClientId');
@@ -251,6 +252,10 @@
vscode.postMessage({ type: 'advanced.update', chunkedMaxSections: Number(advChunkedMax.value) })
);
+ document.querySelector('[data-save="advanced.polishPersonaOverride"]').addEventListener('click', () =>
+ vscode.postMessage({ type: 'advanced.update', polishPersonaOverride: String(advPolishPersona.value || '') })
+ );
+
// ---- Header ----
$('openVscodeSettings').addEventListener('click', () =>
vscode.postMessage({ type: 'openVscodeSettings' })
@@ -409,6 +414,7 @@
setIfNotFocused(advChatTemp, adv.chatTemperature);
setIfNotFocused(advChunkedSwitch, adv.chunkedSwitchTokens);
setIfNotFocused(advChunkedMax, adv.chunkedMaxSections);
+ setIfNotFocused(advPolishPersona, adv.polishPersonaOverride);
// ---- Google (Calendar + Sheets) ----
const g = state.google;
diff --git a/media/sidebar.css b/media/sidebar.css
index 7686c00..ea94a4c 100644
--- a/media/sidebar.css
+++ b/media/sidebar.css
@@ -2136,3 +2136,36 @@
}
.records-line .rl-latest { color: var(--border-bright); overflow: hidden; text-overflow: ellipsis; }
.records-line .hdr-dropdown { flex-shrink: 0; }
+
+ /* Slash 명령 자동완성 dropdown — input 바로 위에 floating. */
+ .slash-suggest {
+ position: absolute;
+ bottom: 100%;
+ left: 12px;
+ right: 12px;
+ margin-bottom: 6px;
+ background: var(--bg-secondary, #2a2a2a);
+ border: 1px solid var(--border, #444);
+ border-radius: 6px;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
+ max-height: 240px;
+ overflow-y: auto;
+ z-index: 100;
+ font-size: 13px;
+ }
+ .slash-suggest .ss-item {
+ padding: 6px 12px;
+ cursor: pointer;
+ display: flex;
+ gap: 10px;
+ align-items: baseline;
+ border-bottom: 1px solid var(--border-faint, #333);
+ }
+ .slash-suggest .ss-item:last-child { border-bottom: none; }
+ .slash-suggest .ss-item.active { background: var(--accent-faint, #094771); }
+ .slash-suggest .ss-item:hover { background: var(--bg-hover, #353535); }
+ .slash-suggest .ss-name { font-weight: 600; color: var(--accent, #4ec9b0); flex-shrink: 0; }
+ .slash-suggest .ss-desc { color: var(--text-dim, #999); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+ .slash-suggest .ss-empty { padding: 8px 12px; color: var(--text-dim, #999); font-style: italic; }
+ /* input-box 가 position:relative 여야 absolute 가 제대로 anchored. */
+ .input-box { position: relative; }
diff --git a/media/sidebar.html b/media/sidebar.html
index f1c7b42..104a280 100644
--- a/media/sidebar.html
+++ b/media/sidebar.html
@@ -510,6 +510,7 @@