/** * Terminology Dictionary — 프로젝트 표준 용어집을 시스템 프롬프트에 주입. * * 사용자 제안: "표준 표기 강제 + 답변 내 표기 일관성 검증". 예: `runway` vs `런웨이`, * `P-Reinforce` vs `p-reinforce`, `Chronicle` vs `크로니클`. * * 설계 — 사용자 편집 markdown 파일: * - 위치: `/.astra/glossary.md` * - 형식: 자유 markdown. ASTRA 는 *형식을 강제하지 않고* 통째로 주입 * - 권장 컨벤션: H2/H3 섹션으로 표준 표기 / 영-한 컨벤션 / 금지 용어 등 그룹핑 * * 시스템 프롬프트 블록 `[TERMINOLOGY DICTIONARY]`: * - 글로서리 본문 + Term Check 지침 (#1 typo/용어 self-check 사용자 제안 통합) * - 답변 작성 시 표준 표기 우선 + 답변 직전 자기 점검 + 새 용어 도입 시 명시 * * 캐시: 파일 mtime 기반 — 매 turn 디스크 read 안 함. */ import * as path from 'path'; import * as vscode from 'vscode'; import { createMtimeFileCache } from '../lib/mtimeFileCache'; const DEFAULT_GLOSSARY_REL_PATH = '.astra/glossary.md'; /** Raw 본문 캐시 — mtime 기반, 파일 편집 시 자동 재read. */ const _rawCache = createMtimeFileCache('terminology-raw', (raw) => raw.trim()); export function getGlossaryFilePath(relPath: string = DEFAULT_GLOSSARY_REL_PATH): string | null { const folders = vscode.workspace.workspaceFolders; if (!folders || folders.length === 0) return null; return path.join(folders[0].uri.fsPath, relPath); } function readGlossary(relPath: string): string { const fp = getGlossaryFilePath(relPath); if (!fp) return ''; return _rawCache.read(fp) ?? ''; } export function clearGlossaryCache(): void { _rawCache.clear(); } export interface TerminologyBlockOptions { /** Glossary 파일 상대 경로. 기본 '.astra/glossary.md'. */ relPath: string; /** 본문 최대 길이 (chars). 너무 큰 글로서리는 시스템 프롬프트 비대 — cap. 기본 4000. */ maxBodyLength: number; /** 길이 초과 시 잘릴 안내 표시 여부. */ showTruncationNote: boolean; } export const DEFAULT_TERMINOLOGY_OPTIONS: TerminologyBlockOptions = { relPath: DEFAULT_GLOSSARY_REL_PATH, maxBodyLength: 4000, showTruncationNote: true, }; export function buildTerminologyBlock(options: Partial = {}): string { const opts: TerminologyBlockOptions = { ...DEFAULT_TERMINOLOGY_OPTIONS, ...options }; const raw = readGlossary(opts.relPath); if (!raw) return ''; // 파일 없음 → 블록 안 만듦 (no-op) let body = raw; let truncated = false; if (body.length > opts.maxBodyLength) { body = body.slice(0, opts.maxBodyLength); truncated = true; } const lines: string[] = []; lines.push('[TERMINOLOGY DICTIONARY]'); lines.push('프로젝트 표준 용어집. 답변 생성 시 다음 표기·컨벤션을 *최우선* 으로 사용.'); lines.push(''); lines.push('---'); lines.push(body); if (truncated && opts.showTruncationNote) { lines.push(''); lines.push(`_…(글로서리 ${raw.length - opts.maxBodyLength}자 잘림 — 핵심 용어를 앞쪽에 배치해 주세요)_`); } lines.push('---'); // Term Check 지침 — 사용자 제안 #1 (typo/용어 self-check) 통합. lines.push(''); lines.push('[Term Check — 답변 직전 자기 점검]'); lines.push('1. **표준 표기 우선**: 위 용어가 답변에 등장하면 *글로서리의 표기를 그대로* 사용. 변형·번역 임의 적용 금지.'); lines.push('2. **표기 흔들림 방지**: 같은 용어를 한 답변 안에서 *동일 표기* 로 일관 사용 (예: "Chronicle" 과 "크로니클" 섞지 말 것).'); lines.push('3. **새 용어 도입 시**: 글로서리에 없는 고유 명사·약어 처음 사용 시 *"새 용어: X"* 라고 한 번 명시.'); lines.push('4. **금지 표기 검증**: 답변 직전, 글로서리의 *금지·비추* 항목이 답변에 들어가지 않았는지 검토. 들어갔으면 *재작성*.'); lines.push('5. **모르겠으면 글로서리**: 표기 확신 없을 때 "글로서리에 없어 일반 표기 사용" 한 줄 명시 후 진행.'); lines.push('[/TERMINOLOGY DICTIONARY]'); return lines.join('\n'); } /** * 글로서리 파일 작성 도우미 — 처음 사용자가 만들 때 권장 컨벤션 템플릿. * 슬래시 명령 `/glossary init` 등에서 호출. */ export const GLOSSARY_TEMPLATE = `# 프로젝트 용어집 ASTRA 가 답변 시 표준 표기로 사용. 사용자가 자유롭게 편집 가능. 파일 저장 후 다음 채팅 turn 부터 자동 반영. ## 표준 표기 - **ASTRA** (X: astra, Astra 외) — 본 VS Code extension 이름 - **P-Reinforce v3.0** (X: p-reinforce, p reinforce) — 지식 압축 규칙 - **Chronicle ADR** (X: chronicle, ADR 단독) — 의사결정 기록 ## 영-한 표기 컨벤션 - Performance → 성능 - Bug → 버그 - Memory → 메모리 ## 금지·비추 표현 - ❌ "절대적", "반드시" (단정적 표현 — 정책 충돌 위험) - ❌ "에이전트가 알아서" (그라운딩 위반) - ❌ 한·영 깨짐 (예: "결ently", "p-rein동") ## 슬래시 명령 표기 원문 그대로 — 한국어 번역 금지: - /runway, /customers, /hire, /morning, /evening, /weekly, /cohort, /memory, /glossary `;