0a97324f1b
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>
108 lines
4.2 KiB
TypeScript
108 lines
4.2 KiB
TypeScript
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,
|
|
});
|
|
}
|