feat: v2.2.92 → v2.2.158 — god-file 분해 + Stocks feature + 대화 연속성
R56–R59: agent.ts 2731→1529줄 god-file 분해 (25 modules) · attrParsers + LLM 메서드 8개 (callNonStreaming, streamChatOnce 등) · executeActions 415줄 → 8 handler 그룹 (file/run/list/brain/calendar/sheets/tasks) · handlePrompt 1100줄 → 7 phase 모듈 (system prompt + budget + autoContinue 등) R50–R55: extension.ts 1145→349줄 (telegram/settings/provider commands 분리) Stocks feature 신규: /stocks slash command (v2.2.152~158) · .astra/stocks.json 저장소 + Yahoo Finance 현재가 갱신 · 8 키워드 필터 (ROE/성장성/유동성/수익성/영업효율/기술력/안정성/PBR) · Naver 시가총액 페이지 JSON API (m.stock.naver.com) 발굴 · LLM Top 5 매력도 분석 + Telegram 자동 보고서 · KST 09:00/15:00 watcher 자동 모니터링 대화 연속성 (v2.2.150~157): · [PRIOR TURN CONCLUSION] block 으로 직전 결론 anchor · thin follow-up 분류 → boilerplate 헤더 suppression · slash 명령 결과 chatHistory mirror (capture wrapper) · echo/parrot 금지 system prompt rule 기타: /stocks 슬래시 자동완성 dropdown UI, Naver JSON API 전환 (cheerio 제거) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import * as fs from 'fs';
|
||||
import type { ProjectProfile } from '../../features/projectChronicle';
|
||||
import { formatArchitectureContextForPrompt } from '../../features/projectArchitecture';
|
||||
|
||||
/**
|
||||
* Architecture (chronicle 프로젝트 자동 attach) 관련 webview payload + prompt
|
||||
* context 빌더. webview send / fs write / scan 같은 *상태성* 부분은 provider 와
|
||||
* `ArchitectureWatchManager` 가 계속 책임 — 이 모듈은 데이터 변환만.
|
||||
*
|
||||
* - buildArchitectureStatusPayload(profile, hasDoc, wasDetached)
|
||||
* → 'architectureStatus' 메시지의 active/inactive/hidden 분기
|
||||
* - buildProjectArchitectureContext(profile)
|
||||
* → agent.ts 가 prompt 에 prepend 하는 architecture context string
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sidebar chip 의 3 가지 상태:
|
||||
* 1) active — auto-attach 켜져 있고 doc 존재. 칩에 "마지막 갱신 N분 전" 표시.
|
||||
* 2) inactive (canAttach) — workspace + project 는 있으나 doc 미생성 or detached.
|
||||
* 칩에 [Attach] 버튼 노출. `detached` 플래그로 "Activate" vs "Re-attach" 구분.
|
||||
* 3) hidden — profile null. 호출자가 `{ active: false }` 만 보내고 끝.
|
||||
*
|
||||
* 빌더는 (1)(2) 만 만들고, hidden 은 호출자가 직접 보낸다 (profile 이 없는데
|
||||
* 빌더에 넘겨봤자 의미 없음).
|
||||
*/
|
||||
export function buildArchitectureStatusPayload(profile: ProjectProfile, hasDoc: boolean, wasDetached: boolean) {
|
||||
const fullyActive = hasDoc && !wasDetached;
|
||||
if (fullyActive) {
|
||||
return {
|
||||
type: 'architectureStatus' as const,
|
||||
value: {
|
||||
active: true,
|
||||
projectId: profile.projectId,
|
||||
projectName: profile.projectName,
|
||||
docPath: profile.architectureDocPath,
|
||||
lastUpdated: profile.architectureLastUpdated || '',
|
||||
autoUpdate: profile.architectureAutoUpdate !== false,
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: 'architectureStatus' as const,
|
||||
value: {
|
||||
active: false,
|
||||
canAttach: !!profile.projectRoot,
|
||||
projectId: profile.projectId,
|
||||
projectName: profile.projectName,
|
||||
// "never activated" 와 "detached" 구분 — chip 라벨 결정용.
|
||||
detached: wasDetached,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** Workspace 도 profile 도 없는 hidden 상태 — chip 자체 숨김. */
|
||||
export function buildArchitectureHiddenPayload() {
|
||||
return {
|
||||
type: 'architectureStatus' as const,
|
||||
value: { active: false as const },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh / Attach 가 사전 가드에서 실패 (활성 project 없음 / projectRoot 없음).
|
||||
* webview 는 spinner 를 해제하고 사용자에게 안내 띄움.
|
||||
*/
|
||||
export function buildArchitectureRefreshFailedPayload(reason: string) {
|
||||
return {
|
||||
type: 'architectureRefreshFailed' as const,
|
||||
value: { reason },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh 가 성공적으로 수행된 후 webview 에 보낼 결과. 3가지 숫자 (newly /
|
||||
* cached / deleted) 가 함께 가야 사용자가 "Refresh 가 실제로 뭘 했는가" 를
|
||||
* 신뢰할 수 있다 — 그냥 timestamp 만 바뀐 경우와 분 단위로 큰 작업이 일어난
|
||||
* 경우를 구분.
|
||||
*/
|
||||
export function buildArchitectureRefreshResultPayload(opts: {
|
||||
projectName: string;
|
||||
docPath: string;
|
||||
newlyAnalyzed: number;
|
||||
cached: number;
|
||||
deleted: number;
|
||||
durationMs: number;
|
||||
}) {
|
||||
return {
|
||||
type: 'architectureRefreshResult' as const,
|
||||
value: opts,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Agent 의 prompt 에 prepend 되는 architecture context block. auto-attach 가 off
|
||||
* 거나 doc 이 없거나 디스크에서 사라졌으면 빈 문자열 (agent.ts 가 알아서 skip).
|
||||
*/
|
||||
export function buildProjectArchitectureContext(profile: ProjectProfile | null): string {
|
||||
if (!profile || profile.architectureAutoAttach === false || !profile.architectureDocPath) return '';
|
||||
if (!fs.existsSync(profile.architectureDocPath)) return '';
|
||||
return formatArchitectureContextForPrompt({
|
||||
projectName: profile.projectName,
|
||||
docPath: profile.architectureDocPath,
|
||||
// project root 를 같이 넘겨 Source: 헤더가 workspace-relative 로 출력되게.
|
||||
projectRoot: profile.projectRoot,
|
||||
lastUpdated: profile.architectureLastUpdated,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user