Files
connectai/tests/handoffDoc.test.ts
T
koriweb 47b3b9f93a v2.2.299~307: 아키텍처 수렴 + 채팅 정리 + 벤치마킹 강화 + Claude 구독 엔진
- v2.2.299 아키텍처 수렴: coreChat 통일(엔진 휴리스틱 3벌 제거), 기업 모드
  검색 오케스트레이터 승격, lib/execUtil(실행 래퍼 6곳·Python 탐지 3벌 단일화),
  lib/kstSchedule(워처 4개 nowInKst 통합), estimateTokens 통합, 설정 접근 규칙 명문화
- v2.2.300 채팅 화면 정리: LiveReasoningFilter(스트리밍 중 <think>/Harmony 추론
  토큰 단위 차단), 확신도·검토요청 footer 기본 숨김(계산·Reflection 은 유지)
- v2.2.301 문맥·의도 이해: [답변 전 이해 원칙] 상시 주입, 워크플로우 의도 브리핑,
  Report QA 루프(규칙 레지스트리+실측치+회귀 게이트, 블로그_v3 개념 이식)
- v2.2.302 /benchmark 비즈니스 렌즈(가격·수익·운영)+빌드 프롬프트 모드+QA 연계
- v2.2.303 handoff 모드(측정치 무손실 인수인계 문서)+/claude(Claude Code 터미널 위임)
- v2.2.304 이식성: 지식 경로 두뇌-상대 규약(pickWikiDir 상대 해석), 이사 체크리스트
- v2.2.305 Claude 구독 엔진: claude: 프로바이더(CLI 위임, 모델 드롭다운 자동 노출,
  coreChat 지원 — 워크플로우·QA도 구독 모델 가능)
- v2.2.306 Tone Guard: AI 상투어 금지 레지스트리(상담사 화법 실사례 8종+대조 예시)
- v2.2.307 /benchmark 레이아웃 골격(sectionRoles 결정론 분석, 롤링 배너 즉답),
  파트별 실패 격리, 합성 타임아웃 120→300초

검증: tsc 무오류 + jest 888 통과 + esbuild 정상

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 21:02:15 +09:00

86 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { buildHandoffDoc } from '../src/features/datacollect/prompts/handoffDoc';
import { buildClaudeCommand } from '../src/features/claude/claudeLauncher';
import { parseBenchmarkArgs, BENCHMARK_MODE_PARTS } from '../src/features/datacollect/handlers';
const SCAN = {
meta: { title: 'InteriorAI', description: 'Fire your interior designer', lang: 'en' },
design: {
colors: {
palette: [{ value: 'rgb(10,10,10)', count: 40 }, { value: 'rgb(255,87,51)', count: 12 }],
background: 'rgb(255,255,255)', primaryText: 'rgb(10,10,10)',
buttonBackground: 'rgb(255,87,51)', buttonText: 'rgb(255,255,255)',
},
typography: { primaryFont: 'Inter', h1: { size: '48px', weight: 700 }, body: { size: '16px' } },
layout: { bodyMaxWidth: '1200px', sectionSpacing: '96px', borderRadiusScale: ['8px', '16px'] },
},
interactions: { hoverRules: ['button: background 0.2s ease'] },
microcopy: { headline: 'Fire your interior designer', ctaSamples: ['Get started $29/mo'] },
structure: { h1: 'Fire your interior designer' },
sitemap: {
totalPages: 2, crawlDepth: 1, ascii: '/\n└── /pricing',
pages: [
{ url: '/', role: 'landing', h1: 'Fire your interior designer', primaryContentType: 'hero', imageCount: 6, ctaSamples: ['Get started'] },
{ url: '/pricing', role: 'pricing', title: 'Pricing', primaryContentType: 'table', imageCount: 0, formFields: [{ name: 'email', type: 'email' }] },
],
},
};
describe('buildHandoffDoc — 측정치 무손실 인수인계 문서', () => {
const doc = buildHandoffDoc(SCAN, 'https://interiorai.com', { crawlDepth: 1, maxPages: 8, userContent: '' });
test('측정된 원시 값이 그대로 들어간다 (rgb·px·카피 원문)', () => {
expect(doc).toContain('rgb(255,87,51)(×12)');
expect(doc).toContain('1200px');
expect(doc).toContain('Fire your interior designer');
expect(doc).toContain('Get started $29/mo');
});
test('클라우드 모델용 지시문과 임의 대체 금지 규칙을 포함한다', () => {
expect(doc).toContain('클라우드 모델용 지시문');
expect(doc).toContain('측정치를 그대로 사용하라');
expect(doc).toContain('추측하지 말고');
});
test('요구사항 미입력 시 채울 체크리스트를 제공한다', () => {
expect(doc).toContain('- [ ] 서비스 이름');
expect(doc).toContain('- [ ] 뺄 기능');
});
test('사용자 변형 지시가 있으면 요구사항 우선 원칙과 함께 삽입된다', () => {
const d2 = buildHandoffDoc(SCAN, 'https://interiorai.com', { crawlDepth: 1, maxPages: 8, userContent: '부동산 중개용으로 변형' });
expect(d2).toContain('부동산 중개용으로 변형');
expect(d2).toContain('요구사항이 우선한다');
});
test('페이지 인벤토리 표와 원시 JSON 부록을 포함한다', () => {
expect(doc).toContain('| /pricing | pricing |');
expect(doc).toContain('원시 스캔 데이터 부록');
expect(doc).toContain('"primaryFont": "Inter"');
});
test('빈 스캔에도 문서가 깨지지 않는다', () => {
const d = buildHandoffDoc({}, 'https://x.com', { crawlDepth: 0, maxPages: 1, userContent: '' });
expect(d).toContain('(스캔 데이터 없음)');
});
});
describe('handoff 모드 파싱·구성', () => {
test('handoff 는 bare/mode= 모두 인식되고 합성 파트가 없다', () => {
expect(parseBenchmarkArgs('https://a.com handoff').mode).toBe('handoff');
expect(parseBenchmarkArgs('https://a.com mode=handoff').mode).toBe('handoff');
expect(BENCHMARK_MODE_PARTS.handoff).toEqual([]);
});
});
describe('buildClaudeCommand — 셸 안전 정규화', () => {
test('지시문을 큰따옴표 한 줄 인자로 만든다', () => {
expect(buildClaudeCommand('파일 읽고 개발해줘')).toBe('claude "파일 읽고 개발해줘"');
});
test('따옴표·POSIX 확장 문자를 무해화한다', () => {
expect(buildClaudeCommand('say "hi" and $HOME `ls`')).toBe(`claude "say 'hi' and HOME ls"`);
});
test('빈 지시문이면 대화형 실행', () => {
expect(buildClaudeCommand(' ')).toBe('claude');
});
});