Set up AI dev environment for recordingtest (#2)
- CLAUDE.md with collaboration rules and Planner/Generator/Evaluator cycle - .claude/ agents, commands, skills, hooks per Claude Code conventions - Sprint Contracts for sut-prober, normalizer, recorder, player, diff-reporter - SUT catalog (EG-BIM Modeler, 187 plugins) and .gitignore excluding SUT tree - PROGRESS.md / PLAN.md as shared agent handoff state - Solution scaffold targeting sut-prober PoC Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
44
docs/contracts/diff-reporter.md
Normal file
44
docs/contracts/diff-reporter.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Sprint Contract — diff-reporter
|
||||
|
||||
**Owner:** Generator
|
||||
**Depends on:** normalizer (정규화된 입력)
|
||||
**Issue:** #2
|
||||
|
||||
## Goal
|
||||
|
||||
`*.approved`와 `*.received` 쌍을 받아 의미 있는 diff를 생성하고, 실패 지점을 시각화한다. `diff-triager` 서브에이전트가 읽을 수 있는 구조화 출력도 제공.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `Recordingtest.DiffReporter` 라이브러리 + CLI
|
||||
- [ ] 입력: `--approved <path> --received <path> --out <dir>`
|
||||
- [ ] JSON/텍스트 파일은 라인·객체 단위 의미 diff, 바이너리는 hex 요약 diff
|
||||
- [ ] 출력: `diff.json`(구조화), `diff.md`(사람용), `diff.html`(옵션, side-by-side)
|
||||
- [ ] `diff.json` 스키마: `{ file, hunks[], summary: { added, removed, changed } }`
|
||||
- [ ] 동일 파일 비교 시 "identical"로 단정, exit code 0
|
||||
- [ ] 차이 존재 시 exit code 1 + 요약을 stdout 1줄
|
||||
- [ ] diff-triager 에이전트가 `diff.json`만 읽어 bucket 분류 가능 (통합 테스트 1개)
|
||||
|
||||
## Interfaces
|
||||
|
||||
- **Inputs:** 두 파일 경로
|
||||
- **Outputs:** `diff.json`, `diff.md`, (옵션) `diff.html`
|
||||
- **Side effects:** 없음
|
||||
|
||||
## Out of scope
|
||||
|
||||
- 정규화 자체 (normalizer)
|
||||
- triage 분류 로직 (diff-triager 에이전트)
|
||||
- 자동 approve (`/approve` 커맨드)
|
||||
|
||||
## Evaluation plan
|
||||
|
||||
1. 동일 파일 2개 → identical 판정
|
||||
2. 1필드만 바뀐 JSON → `diff.json.hunks.length == 1`
|
||||
3. 바이너리 파일 diff → hex summary 출력
|
||||
4. diff-triager에 통합: normalization gap 케이스에서 bucket=`normalization_gap` 분류 확인
|
||||
|
||||
## Risks
|
||||
|
||||
- 큰 파일(수십 MB 모델)에서 성능 — 스트리밍 diff 필요
|
||||
- JSON 스키마 변경 시 triager 하위 호환성
|
||||
43
docs/contracts/normalizer.md
Normal file
43
docs/contracts/normalizer.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Sprint Contract — normalizer
|
||||
|
||||
**Owner:** Generator
|
||||
**Depends on:** sut-prober (Json 카탈로그)
|
||||
**Issue:** #2
|
||||
|
||||
## Goal
|
||||
|
||||
SUT 저장 파일(Json 설정 + 모델 파일)의 비결정적 필드를 정규화해 golden-file 비교를 결정적으로 만든다. 규칙은 **프로파일 단위로 버전 관리**되고 단위 테스트를 동반한다.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `Recordingtest.Normalizer` 라이브러리가 `Normalize(input, profile)` API 제공
|
||||
- [ ] 기본 프로파일 `default` 포함 규칙 최소 5개: 타임스탬프 마스킹, GUID 치환, 절대 경로 → `<REPO>`/`<USER>`, 부동소수점 epsilon(1e-6), JSON 객체 키 정렬
|
||||
- [ ] 프로파일은 `profiles/*.yaml`로 선언, 코드 변경 없이 규칙 추가 가능
|
||||
- [ ] 각 규칙마다 `tests/Normalizer.Tests/` 아래 before/after 샘플 1쌍 이상
|
||||
- [ ] 동일 입력으로 두 번 정규화해도 같은 바이트 출력 (idempotent)
|
||||
- [ ] 정규화 로그(sidecar) `normalization.log` 생성 — 어떤 규칙이 몇 번 적용됐는지 기록
|
||||
- [ ] `json-configs.json` 카탈로그의 "suspected fields" 전수를 default 프로파일로 덮는다
|
||||
|
||||
## Interfaces / contracts
|
||||
|
||||
- **Inputs:** 파일 경로 + 프로파일 이름
|
||||
- **Outputs:** 정규화된 바이트 스트림 + sidecar 로그
|
||||
- **Side effects:** sidecar 로그 쓰기만
|
||||
|
||||
## Out of scope
|
||||
|
||||
- 바이너리 `.hme`/`.egm` 파서 (별도 contract)
|
||||
- SUT 내부 호출
|
||||
- 정규화 규칙 자동 학습
|
||||
|
||||
## Evaluation plan
|
||||
|
||||
1. `dotnet test tests/Normalizer.Tests` 전부 pass
|
||||
2. `json-configs.json`의 모든 suspected field가 default 프로파일 규칙에 커버됨 (매핑 테이블 검증)
|
||||
3. 동일 입력 2회 정규화 바이트 diff 없음
|
||||
4. 샘플 `Settings.json` 정규화 전/후 비교에서 타임스탬프·경로가 마스킹됨
|
||||
|
||||
## Risks
|
||||
|
||||
- epsilon 선택이 SUT 실제 정밀도와 충돌 가능 → 구성 가능해야 함.
|
||||
- 컬렉션 순서 정렬이 SUT 의미를 바꿀 수 있음 → 정렬 대상은 명시적 화이트리스트.
|
||||
44
docs/contracts/player.md
Normal file
44
docs/contracts/player.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Sprint Contract — player
|
||||
|
||||
**Owner:** Generator
|
||||
**Depends on:** recorder 스키마 확정
|
||||
**Issue:** #2
|
||||
|
||||
## Goal
|
||||
|
||||
recorder가 생성한 시나리오 yaml을 SUT에 재생해 결과 저장 파일을 생성한다. 타이밍은 고정 sleep 금지, UIA/이벤트 기반 동기화.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `Recordingtest.Player` 콘솔이 `--scenario <path> [--output-dir <path>]` 받음
|
||||
- [ ] 각 step 재생 전 `wait_for`(uia 이벤트/엘리먼트 property) 대기 구현
|
||||
- [ ] `target.uia_path`로 엘리먼트 재탐색 후 `offset_norm`으로 좌표 계산해 입력 전달
|
||||
- [ ] 재생 중 예외 발생 시 시나리오 스텝 index + 엘리먼트 탐색 실패 이유를 아티팩트로 기록
|
||||
- [ ] 체크포인트 step에서 현재 저장 파일을 `<output-dir>/checkpoint-<n>.*`로 복사
|
||||
- [ ] 재생 완료 시 exit code 0, 실패 시 non-zero + 아티팩트 경로 출력
|
||||
- [ ] 동일 시나리오 10회 재생 시 9회 이상 성공 (flaky 허용 상한)
|
||||
|
||||
## Interfaces
|
||||
|
||||
- **Inputs:** 시나리오 yaml, 아티팩트 출력 디렉터리
|
||||
- **Outputs:** checkpoint 저장 파일, 실패 아티팩트(스크린샷, UIA 덤프, 로그)
|
||||
- **Side effects:** SUT 프로세스 실행/종료
|
||||
|
||||
## Out of scope
|
||||
|
||||
- 정규화 (normalizer의 몫)
|
||||
- diff (diff-reporter의 몫)
|
||||
- 리포트 집계 (test-runner의 몫)
|
||||
|
||||
## Evaluation plan
|
||||
|
||||
1. recorder로 만든 간단 시나리오(Box 생성 저장)를 10회 재생 → 9회 이상 완료 파일 생성
|
||||
2. 의도적으로 잘못된 `uia_path`를 넣어 실패 → 아티팩트에 탐색 실패 이유 기록 확인
|
||||
3. 체크포인트 2개 시나리오 재생 → 각 checkpoint 파일 존재 확인
|
||||
4. 고정 sleep 호출 grep으로 0건 확인
|
||||
|
||||
## Risks
|
||||
|
||||
- plugin 로드 지연 → 첫 step 전 "plugin ready" 신호 필요
|
||||
- 시작 상태 초기화 (임시 프로젝트 파일 삭제) 미비 시 누적 오염
|
||||
- 재생 중 모달 대화상자 출현 시 대응 정책 필요
|
||||
47
docs/contracts/recorder.md
Normal file
47
docs/contracts/recorder.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Sprint Contract — recorder
|
||||
|
||||
**Owner:** Generator
|
||||
**Depends on:** FlaUI 승인, sut-prober(UIA 힌트용 카탈로그)
|
||||
**Issue:** #2
|
||||
|
||||
## Goal
|
||||
|
||||
사용자가 EG-BIM Modeler에서 수동 테스트하는 동안 입력(키·마우스·창 이벤트)을 캡처해 element-aware 시나리오 파일을 생성한다.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `Recordingtest.Recorder` 콘솔 실행 시 SUT에 attach하고 입력 캡처 시작
|
||||
- [ ] 캡처되는 이벤트: 키 다운/업, 마우스 클릭/드래그/휠, 포커스 변경
|
||||
- [ ] 각 이벤트는 `{ ts, kind, uia_path, offset_norm, raw_coord, value }` 형식으로 기록
|
||||
- [ ] 3D 뷰포트(SharpDX surface) 클릭 시 uia_path는 호스팅 엘리먼트, `offset_norm`은 `[0..1]` 정규화 좌표
|
||||
- [ ] 출력: `scenarios/<name>.yaml` 스키마 준수 (`scenario-author` 규격 일치)
|
||||
- [ ] 비밀번호/토큰 마스킹 규칙 1개 이상 (예: focus된 element가 `PasswordBox`이면 `value`를 `<MASKED>`)
|
||||
- [ ] 캡처 중 SUT 성능에 눈에 띄는 영향 없음 (60 FPS 유지; 경고만)
|
||||
- [ ] 캡처 종료 시 요약(이벤트 수, 소요 시간, uia_path 미결 건수)
|
||||
|
||||
## Interfaces
|
||||
|
||||
- **Inputs:** `--output scenarios/<name>.yaml`, `--attach <pid or window title>`
|
||||
- **Outputs:** 시나리오 yaml
|
||||
- **Side effects:** 전역 Win32 hook 등록/해제
|
||||
|
||||
## Out of scope
|
||||
|
||||
- 리플레이 (player의 몫)
|
||||
- 3D 엔진 상태 캡처 (engine-bridge 사용 예정)
|
||||
- 자동 이름 추정 / 자연어 변환 (scenario-author)
|
||||
|
||||
## Evaluation plan
|
||||
|
||||
1. SUT를 수동 실행 후 recorder attach → Box 명령 버튼 클릭 → Box 생성 드래그 → 저장
|
||||
2. 출력 yaml 파싱 + 스키마 검증
|
||||
3. 클릭 이벤트의 `uia_path`가 `Button[@Name*='Box']` 형태 포함 확인
|
||||
4. 드래그 이벤트의 `offset_norm`이 `[0..1]` 범위 확인
|
||||
5. `PasswordBox`에 더미 입력 → `<MASKED>` 기록 확인
|
||||
6. 종료 후 hook 해제 확인 (재실행 시 double-hook 안 남음)
|
||||
|
||||
## Risks
|
||||
|
||||
- IME(한글) 조합 키 이벤트 손실 → 클립보드 우회 필요 가능
|
||||
- 해상도/DPI 변경 시 `raw_coord`는 유효성 상실 → `offset_norm` 우선 사용
|
||||
- Win32 hook은 UI thread 블록 가능 → 별도 스레드 + 큐 필수
|
||||
48
docs/contracts/sut-prober.md
Normal file
48
docs/contracts/sut-prober.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Sprint Contract — sut-prober
|
||||
|
||||
**Owner:** Generator (일반 세션)
|
||||
**Depends on:** 없음
|
||||
**Issue:** #2
|
||||
|
||||
## Goal
|
||||
|
||||
EG-BIM Modeler SUT의 **정적** 구조(플러그인·설정·어셈블리)를 덤프해 `docs/sut-catalog/`에 베이스라인 가능한 카탈로그를 생성한다. SUT는 실행하지 않는다.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
- [ ] `dotnet run --project src/Recordingtest.SutProber` 실행으로 카탈로그 3종이 생성된다: `plugins.json`, `json-configs.json`, `assemblies.json`
|
||||
- [ ] `plugins.json`은 `EG-BIM Modeler/Plugins/Eg*Plugin/` 187개(±) 전부를 담고, 각 항목은 `{ name, path, dlls[], size_bytes }` 형식
|
||||
- [ ] `json-configs.json`은 `EG-BIM Modeler/Json/*.json` 각 파일별 `{ name, top_level_keys[], suspected_nondeterministic_fields[] }`
|
||||
- [ ] `assemblies.json`은 `HmEG*.dll`, `Editor*.dll`, `HmGeometry*.dll`의 `{ name, size, has_pdb }`
|
||||
- [ ] 출력은 **정렬되어 있어** 두 번 실행해도 동일 (decimal/텍스트 diff 없음)
|
||||
- [ ] `EG-BIM Modeler/` 폴더에 대한 쓰기 접근이 없다 (코드 리뷰로 확인)
|
||||
- [ ] 경로는 repo root 상대 경로로 기록(절대 경로 금지)
|
||||
|
||||
## Interfaces / contracts
|
||||
|
||||
- **Inputs:** `EG-BIM Modeler/` (read-only), CLI 인자 `--sut <path>` (기본 `EG-BIM Modeler`)
|
||||
- **Outputs:** `docs/sut-catalog/plugins.json`, `docs/sut-catalog/json-configs.json`, `docs/sut-catalog/assemblies.json`
|
||||
- **Side effects:** 없음 (로그 제외)
|
||||
|
||||
## Out of scope
|
||||
|
||||
- SUT 실행 / 리플렉션 / 동적 분석
|
||||
- PDB 파싱 (engine-bridge의 몫)
|
||||
- UIA 트리 덤프 (recorder 또는 별도 PoC의 몫)
|
||||
|
||||
## Evaluation plan
|
||||
|
||||
evaluator는 다음을 수행:
|
||||
|
||||
1. `dotnet build` 성공
|
||||
2. `dotnet run --project src/Recordingtest.SutProber -- --sut "EG-BIM Modeler"` 실행, exit code 0 확인
|
||||
3. 세 카탈로그 파일 존재 확인 + JSON 파싱 유효성
|
||||
4. `plugins.json` 엔트리 수 ≥ 180
|
||||
5. 두 번째 실행 후 세 파일 `git diff` 결과가 비어있음을 확인 (결정성)
|
||||
6. `grep -r "EG-BIM Modeler" src/Recordingtest.SutProber/` 결과에 `File.Write|File.Delete|File.Create` 호출 없음 확인
|
||||
|
||||
## Risks / open questions
|
||||
|
||||
- .NET 버전 합의 필요 (`net8.0` 제안). SUT와 다를 수 있으나 prober는 독립 프로세스이므로 무관.
|
||||
- 플러그인 폴더 구조가 일정한지 샘플 확인 필요.
|
||||
- 경로 구분자(Windows `\`) 정규화 정책 — 출력에서 `/`로 통일 권장.
|
||||
19
docs/history/2026-04-07_이슈2-AI-AutomationPeer-부착옵션.md
Normal file
19
docs/history/2026-04-07_이슈2-AI-AutomationPeer-부착옵션.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# 2026-04-07 이슈 #2 — AI 기반 AutomationPeer 부착 옵션 기록
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~3분
|
||||
- **Context 사용량**: ~70k tokens
|
||||
|
||||
## 결정/기록
|
||||
|
||||
SUT 커스텀 컨트롤에 AutomationPeer를 부착하는 작업을 AI로 자동화하는 보조 전략을 메모리에 남김. Golden-file이 1차 전략이지만, element-aware 레코딩 보강이 필요해질 때 꺼낼 카드.
|
||||
|
||||
### 핵심
|
||||
- 패턴 정형화로 80% AI 자동 생성 가능
|
||||
- ControlType/패턴 매핑과 `AutomationProperties.Name`은 사람 리뷰 필요
|
||||
- SUT 저장소엔 별도 브랜치/PR로 제안, 직접 커밋 금지
|
||||
- recordingtest 저장소에는 가이드/스크립트만, SUT 코드 변경은 fork/PR로 분리
|
||||
|
||||
## 산출물
|
||||
- 메모리: `project_recordingtest_automationpeer_ai.md`
|
||||
- MEMORY.md 인덱스 갱신
|
||||
21
docs/history/2026-04-07_이슈2-CLAUDE-md-progress-plan-규칙.md
Normal file
21
docs/history/2026-04-07_이슈2-CLAUDE-md-progress-plan-규칙.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 2026-04-07 이슈 #2 — CLAUDE.md에 PROGRESS/PLAN 협업 규칙 추가
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~3분
|
||||
- **Context 사용량**: ~76k tokens
|
||||
|
||||
## 변경 내용
|
||||
|
||||
`CLAUDE.md` 에 §0 "세션 시작 시 필독" 섹션 신설. 여러 에이전트 협업을 위한 공유 메모리로 `PROGRESS.md`(끝난 일)와 `PLAN.md`(할 일) 운영 규칙 명시.
|
||||
|
||||
### 핵심 규칙
|
||||
- 세션 시작: PROGRESS.md + PLAN.md 먼저 read
|
||||
- 시작 시: PROGRESS.md에 in progress 표시
|
||||
- 종료 시: PROGRESS.md(done 이동) + PLAN.md(완료 제거/다음 단계) + history 파일 (3종 세트)
|
||||
- 충돌 시 최신 커밋 기준 머지, 모호하면 사용자에 질문
|
||||
|
||||
§7 Claude 작업 원칙에도 같은 내용 반영.
|
||||
|
||||
## 다음 단계
|
||||
|
||||
PROGRESS.md / PLAN.md 실제 파일은 셋업 단계에서 작성 예정 (현재는 CLAUDE.md 규칙만 정의).
|
||||
26
docs/history/2026-04-07_이슈2-CLAUDE-md-작성.md
Normal file
26
docs/history/2026-04-07_이슈2-CLAUDE-md-작성.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 2026-04-07 이슈 #2 — CLAUDE.md 작성
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~5분
|
||||
- **Context 사용량**: ~63k tokens
|
||||
|
||||
## 작업 내용
|
||||
|
||||
프로젝트 셋업 전, recordingtest(WPF 입력 회귀 자동화 도구)의 운영 지침인 `CLAUDE.md`를 루트에 작성. 셋업은 미실시.
|
||||
|
||||
## 포함 섹션
|
||||
|
||||
1. 프로젝트 정체성 / SUT 개요
|
||||
2. 핵심 전략 — Golden-file 회귀
|
||||
3. 아키텍처 구성요소(8개 모듈) 우선순위
|
||||
4. 기술 스택 가이드 (FlaUI, Win32 hook, JSON/YAML, LFS)
|
||||
5. 설계 원칙 8개 (결정성, element-aware, 타이밍, marshaling, 체크포인트, 아티팩트, 침습 최소화, 마스킹)
|
||||
6. 환경 제약 (세션0, DPI, GPU)
|
||||
7. 작업 흐름 규칙 (히스토리 필수)
|
||||
8. 디렉터리 구조(예정)
|
||||
9. 비목표
|
||||
10. 결정 로그 위치
|
||||
|
||||
## 다음 단계
|
||||
|
||||
사용자 승인 후 실제 솔루션/프로젝트 셋업 진행.
|
||||
28
docs/history/2026-04-07_이슈2-SUT-EGBIM-분석.md
Normal file
28
docs/history/2026-04-07_이슈2-SUT-EGBIM-분석.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 2026-04-07 이슈 #2 — SUT (EG-BIM Modeler) 폴더 분석
|
||||
|
||||
- **이슈**: kimminsync/recordingtest#2
|
||||
- **소요 시간**: ~5분
|
||||
- **Context 사용량**: ~82k tokens
|
||||
|
||||
## 분석 대상
|
||||
|
||||
`d:/MYCLAUDE_PROJECT/recordingtest/EG-BIM Modeler/` — SUT 실행파일 일습.
|
||||
|
||||
## 핵심 발견
|
||||
|
||||
- WPF + .NET, 3D 엔진 `HmEG.dll`, 렌더 SharpDX D3D11
|
||||
- MEF plugin `Plugins/Eg*Plugin/` 수십~100개+
|
||||
- **PDB 동봉** → 리플렉션/엔진 침습 비용 ↓
|
||||
- `Json/` 폴더에 텍스트 설정 다수 — golden-file 1차 타깃으로 적합
|
||||
- 자체 저장 포맷 `.hme`/`.egm` — 파서·정규화 규칙 필요
|
||||
- 3D 뷰포트는 D3D surface로 UIA 사각지대 확정
|
||||
|
||||
## 전략 반영
|
||||
|
||||
- sut-prober 첫 PoC: `Plugins/` 스캔 + `Json/` 스냅샷
|
||||
- engine-bridge: HmEG 리플렉션으로 카메라/씬그래프 접근
|
||||
- 모델 포맷 파서 모듈 분리
|
||||
|
||||
## 산출물
|
||||
- 메모리: `project_sut_egbim_modeler.md`
|
||||
- MEMORY.md 인덱스 갱신
|
||||
@@ -0,0 +1,68 @@
|
||||
# 2026-04-07 이슈 #2 — .claude/ 에이전트·커맨드·스킬·훅 셋업
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~15분
|
||||
- **Context 사용량**: ~95k tokens
|
||||
|
||||
## 작업 내용
|
||||
|
||||
Claude Code 공식 포맷 조사(claude-code-guide 에이전트) 후, recordingtest 운영에 필요한 커스터마이즈를 `.claude/` 하위에 생성.
|
||||
|
||||
### Subagents — `.claude/agents/*.md`
|
||||
- **sut-explorer** — EG-BIM Modeler 정적 분석(플러그인/Json/어셈블리). SUT 실행 금지.
|
||||
- **diff-triager** — 회귀 실패 분류(real bug / intentional / normalization gap / env drift / flaky).
|
||||
- **scenario-author** — 자연어 → 시나리오 YAML 생성.
|
||||
|
||||
### Slash commands — `.claude/commands/*.md`
|
||||
- **/sut-probe** — sut-explorer 위임, 카탈로그 생성.
|
||||
- **/regress** — 회귀 실행 + 실패 자동 triage.
|
||||
- **/approve** — received → approved 승격, 사유 강제.
|
||||
- **/handoff** — PROGRESS/PLAN/history 3종 세트 갱신.
|
||||
- **/progress** — PROGRESS.md/PLAN.md 요약 출력.
|
||||
|
||||
### Skills — `.claude/skills/<name>/SKILL.md`
|
||||
- **golden-file-normalizer** — 정규화 규칙 카테고리/원칙/저작 가이드.
|
||||
- **flaui-cookbook** — FlaUI 런칭/대기/엘리먼트 캡처/3D 뷰포트 폴백/함정.
|
||||
|
||||
### Hooks — `.claude/settings.json` + `.claude/hooks/*.sh`
|
||||
- **SessionStart** → `session-start-progress.sh`: PROGRESS.md/PLAN.md 자동 주입.
|
||||
- **PreToolUse(Bash)** → `guard-sut-launch.sh`: EG-BIM Modeler.exe 실행 경고.
|
||||
- **PreToolUse(Edit|Write)** → `guard-sut-folder.sh`: SUT 폴더 수정 차단(exit 2).
|
||||
- **Stop** → `stop-handoff-reminder.sh`: 오늘 history 파일/PROGRESS/PLAN 누락 시 /handoff 권장.
|
||||
|
||||
## 원칙
|
||||
|
||||
- 포맷은 claude-code-guide 조사 결과를 따름(frontmatter: name/description/allowed-tools/tools/model).
|
||||
- SUT 폴더는 **read-only** — 훅으로 강제.
|
||||
- 실제 모듈(src/*)은 아직 미생성 — /regress 등은 건드릴 파일이 없으면 early-exit.
|
||||
|
||||
## 산출물
|
||||
|
||||
```
|
||||
.claude/
|
||||
├── agents/
|
||||
│ ├── sut-explorer.md
|
||||
│ ├── diff-triager.md
|
||||
│ └── scenario-author.md
|
||||
├── commands/
|
||||
│ ├── sut-probe.md
|
||||
│ ├── regress.md
|
||||
│ ├── approve.md
|
||||
│ ├── handoff.md
|
||||
│ └── progress.md
|
||||
├── skills/
|
||||
│ ├── golden-file-normalizer/SKILL.md
|
||||
│ └── flaui-cookbook/SKILL.md
|
||||
├── hooks/
|
||||
│ ├── session-start-progress.sh
|
||||
│ ├── guard-sut-launch.sh
|
||||
│ ├── guard-sut-folder.sh
|
||||
│ └── stop-handoff-reminder.sh
|
||||
└── settings.json (hooks 섹션 추가)
|
||||
```
|
||||
|
||||
## 다음 단계
|
||||
|
||||
- PROGRESS.md / PLAN.md 실제 파일 작성 (셋업 단계에서)
|
||||
- src/ 모듈 scaffold
|
||||
- 훅 bash 스크립트 실제 동작 검증
|
||||
34
docs/history/2026-04-07_이슈2-golden-file-전략-채택.md
Normal file
34
docs/history/2026-04-07_이슈2-golden-file-전략-채택.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 2026-04-07 이슈 #2 — Golden-file 회귀 전략 채택
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~5분
|
||||
- **Context 사용량**: ~58k tokens
|
||||
|
||||
## 결정
|
||||
|
||||
사용자 제안 채택: **수동 테스트 입력 레코딩 → 리플레이 후 저장 파일을 베이스라인과 diff** 하는 golden-file 회귀 방식을 1차 검증 수단으로 삼는다. (ApprovalTests 패턴과 동형)
|
||||
|
||||
## 근거
|
||||
|
||||
- SUT(WPF+MEF+HmEG)에 AutomationPeer/probe 부착 협조 비용 회피
|
||||
- 결과물 파일 자체가 검증 기준 → 직관적, 사용자가 시나리오 작성 가능
|
||||
- 픽셀 비교 의존도 ↓ → viewport-verifier 우선순위 하향
|
||||
|
||||
## 성립 조건 / 함정
|
||||
|
||||
1. **결정성**: 저장 파일의 타임스탬프/GUID/경로/부동소수점/순서 → 정규화 파이프라인 필수
|
||||
2. **입력 재현 정확도**: 타이밍·포커스·IME·3D 드래그 픽셀 증폭
|
||||
3. **비교 범위**: 저장 파일만 vs +중간 체크포인트 vs +엔진 상태 sidecar
|
||||
4. **베이스라인 관리**: `*.approved`/`*.received` 워크플로, 큰 파일 LFS
|
||||
5. **진단**: 단계별 스냅샷으로 갈라진 지점 이분 탐색
|
||||
|
||||
## 모듈 우선순위 재조정
|
||||
|
||||
핵심: **recorder + player + 정규화 모듈 + diff-reporter**
|
||||
보조: engine-bridge(sidecar JSON 덤프 용도)
|
||||
후순위: viewport-verifier(픽셀 비교)
|
||||
|
||||
## 다음 단계
|
||||
|
||||
- 저장 파일 포맷 조사 (텍스트/바이너리, 정규화 가능 영역)
|
||||
- recorder PoC 범위 정의
|
||||
@@ -0,0 +1,41 @@
|
||||
# 2026-04-07 이슈 #2 — Planner/Evaluator 에이전트 & Sprint Contract 도입
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~10분
|
||||
- **Context 사용량**: ~108k tokens
|
||||
|
||||
## 배경
|
||||
|
||||
Anthropic "Harness Design for Long-Running Agent Applications" 기사를 읽고, 핵심 원칙을 recordingtest에 반영.
|
||||
|
||||
## 추가된 것
|
||||
|
||||
### 에이전트
|
||||
- `.claude/agents/planner.md` — 요청 → Sprint Contract + PLAN.md 엔트리. 구현 금지.
|
||||
- `.claude/agents/evaluator.md` — 완료된 모듈을 Sprint Contract 기준으로 독립 채점. 자기 작업 평가 금지.
|
||||
|
||||
### 커맨드
|
||||
- `.claude/commands/contract.md` — `/contract <name>`
|
||||
- `.claude/commands/evaluate.md` — `/evaluate <name>`
|
||||
|
||||
### CLAUDE.md
|
||||
- §0.1 "작업 사이클 — Planner → Generator → Evaluator" 섹션 신설
|
||||
- Sprint Contract / DoD 객관성 / 독립 평가 원칙 명시
|
||||
- 컨텍스트 위생: compaction 대신 reset, Stop hook 경고 준수, scaffolding audit 상시 항목
|
||||
- 디렉터리 구조에 `docs/contracts/`, `PROGRESS.md`, `PLAN.md` 추가
|
||||
|
||||
### 메모리
|
||||
- `project_recordingtest_harness_design.md` 신규
|
||||
- MEMORY.md 인덱스 갱신
|
||||
|
||||
## 원칙 요약
|
||||
|
||||
1. 생성자와 평가자는 같은 에이전트가 겸하지 않는다.
|
||||
2. DoD는 객관적으로 검증 가능해야 한다.
|
||||
3. 컨텍스트가 차면 요약하지 말고 파일에 쏟고 리셋.
|
||||
4. evaluator fail → PROGRESS.md에 done으로 넘기지 않는다.
|
||||
5. `.claude/` 비계는 주기적으로 감사·축소.
|
||||
|
||||
## 다음 단계
|
||||
|
||||
PROGRESS.md / PLAN.md 실제 부트스트랩 (첫 번째 Sprint Contract 작성부터).
|
||||
26
docs/history/2026-04-07_이슈2-구현고려사항-정리.md
Normal file
26
docs/history/2026-04-07_이슈2-구현고려사항-정리.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 2026-04-07 이슈 #2 — 구현 고려사항 정리
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~5분
|
||||
- **Context 사용량**: ~52k tokens
|
||||
|
||||
## 정리한 고려사항 카테고리
|
||||
|
||||
1. **레코딩/리플레이 안정성** — 좌표 vs element, 타이밍, 포커스/Z-order, IME
|
||||
2. **WPF/MEF 특성** — Custom AutomationPeer, plugin 비동기 로드, Dispatcher marshaling
|
||||
3. **3D 뷰포트(HmEG) 검증** — 픽셀 비교 한계, 엔진 내부 상태 검증, 픽킹 안정성
|
||||
4. **환경/재현성** — DPI, 멀티모니터, 시계/랜덤 격리, CI 세션 0 제약
|
||||
5. **테스트 자산 관리** — JSON/YAML 시나리오, 베이스라인 이미지 LFS, 모듈화
|
||||
6. **진단/디버깅** — 실패 아티팩트(스샷·UIA 덤프·엔진 상태), 영상 녹화, diff 오버레이
|
||||
7. **보안/안전** — 입력 마스킹, 권한 일치
|
||||
8. **거버넌스** — SUT 코드 변경 협조(AutomationPeer/probe), 유지보수 비용
|
||||
|
||||
## 핵심 인사이트
|
||||
|
||||
- 픽셀 비교보다 **엔진 내부 상태(engine-bridge)** 가 훨씬 안정적 → 우선순위 상향
|
||||
- **SUT 팀 협조** 가 기술적 난제보다 큰 장애물 (AutomationPeer/probe 부착)
|
||||
- WPF는 세션 0에서 못 돌므로 CI는 대화형 세션 agent 필요
|
||||
|
||||
## 다음 단계
|
||||
|
||||
위 고려사항을 sut-prober PoC 설계에 반영.
|
||||
41
docs/history/2026-04-07_이슈2-리서치-에이전트분해.md
Normal file
41
docs/history/2026-04-07_이슈2-리서치-에이전트분해.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 2026-04-07 이슈 #2 — 리서치 및 Agent 분해
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2 — 요구사항 컨텍스트 엔지니어링과 AI 개발환경 셋팅
|
||||
- **소요 시간**: ~15분
|
||||
- **Context 사용량**: ~45k tokens
|
||||
|
||||
## 작업 내용
|
||||
|
||||
WPF + MEF 플러그인 + 자체 HmEG 3D 엔진으로 구성된 SUT를 대상으로 한 입력 회귀 테스트 자동화 도구의 접근법을 웹 리서치하고, 단계별 agent로 분해하여 메모리에 저장.
|
||||
|
||||
### 리서치 결론
|
||||
|
||||
- **UIA 1순위**: FlaUI (.NET native, WPF 정밀 제어). WinAppDriver는 정체, Appium은 그 래퍼.
|
||||
- **3D 뷰포트**: UIA 불가 → 좌표 입력 + 픽셀/이미지 비교 + 엔진 in-process hook 하이브리드.
|
||||
- **MEF plug-in**: 각 plugin 프로젝트에 custom `AutomationPeer` 부착, plugin 상태를 probe로 노출.
|
||||
- **레코딩**: Win32 low-level hook + UIA element path + offset 동시 저장(해상도 내성).
|
||||
|
||||
### Agent 분해(예정)
|
||||
|
||||
1. sut-prober — UIA 트리 덤프, MEF plugin 목록
|
||||
2. recorder — element-aware 입력 캡처
|
||||
3. player — 재생/동기화
|
||||
4. viewport-verifier — 3D 스크린샷 비교
|
||||
5. engine-bridge — HmEG 상태 노출
|
||||
6. test-runner — 시나리오 실행/리포트
|
||||
7. diff-reporter — 실패 시각화
|
||||
|
||||
## 산출물
|
||||
|
||||
- 메모리: `project_recordingtest_goal.md`, `project_recordingtest_plan.md`
|
||||
- 본 히스토리 파일
|
||||
|
||||
## 다음 단계
|
||||
|
||||
`sut-prober` PoC부터 시작 — 사용자 결정 대기.
|
||||
|
||||
## 참고 링크
|
||||
|
||||
- [FlaUI vs WinAppDriver 2026](https://www.testsprite.com/use-cases/en/the-most-accurate-alternatives-to-winappdriver)
|
||||
- [WPF Custom AutomationPeer](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/ui-automation-of-a-wpf-custom-control)
|
||||
- [TestComplete WPF Record/Replay](https://support.smartbear.com/testcomplete/docs/app-testing/desktop/wpf/index.html)
|
||||
51
docs/history/2026-04-07_이슈2-병렬-스캐폴드-contracts.md
Normal file
51
docs/history/2026-04-07_이슈2-병렬-스캐폴드-contracts.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 2026-04-07 이슈 #2 — 병렬 스캐폴드 + Sprint Contracts 일괄
|
||||
|
||||
- **이슈**: kimminsung/recordingtest#2
|
||||
- **소요 시간**: ~20분
|
||||
- **Context 사용량**: ~130k tokens
|
||||
|
||||
## 작업 내용
|
||||
|
||||
"병렬화 가능한 부분 병렬 구현" 요청에 따라, 독립 파일들을 한 세션에서 병렬 Write로 일괄 생성.
|
||||
|
||||
### 부트스트랩 문서
|
||||
- `PROGRESS.md` — 공유 상태 파일 확장 (Done/In progress/Blocked/Scaffolding review)
|
||||
- `PLAN.md` — P0~P3 우선순위 큐 + 작업 규칙
|
||||
|
||||
### Sprint Contracts (5건)
|
||||
`docs/contracts/` 하위:
|
||||
- `sut-prober.md` — 187개 플러그인 카탈로그 + json-configs + assemblies 덤프
|
||||
- `normalizer.md` — 기본 프로파일 5규칙, idempotent
|
||||
- `recorder.md` — element-aware 입력 캡처, IME·마스킹 포함
|
||||
- `player.md` — 10회 중 9회 성공, 고정 sleep 금지
|
||||
- `diff-reporter.md` — JSON/텍스트 의미 diff, triager 연동
|
||||
|
||||
각 contract는 planner 에이전트 규격(Goal / DoD / Interfaces / Out of scope / Evaluation plan / Risks)을 준수하며, DoD 항목은 모두 객관적으로 검증 가능.
|
||||
|
||||
### SUT 카탈로그 v0
|
||||
- `docs/sut-catalog/catalog.md` — 어셈블리·UI스택·Json 설정·저장 포맷·영향 요약
|
||||
- `docs/sut-catalog/plugins.md` — 187개 플러그인 전체 목록 (사전순)
|
||||
|
||||
### 솔루션 스캐폴드 (sut-prober PoC)
|
||||
- `recordingtest.sln`
|
||||
- `Directory.Build.props` (net8.0, nullable, warnings-as-errors)
|
||||
- `src/Recordingtest.SutProber/` 4개 파일:
|
||||
- `Recordingtest.SutProber.csproj`
|
||||
- `Program.cs` — CLI 진입, `--sut`/`--out` 인자
|
||||
- `PluginScanner.cs` — 정렬된 플러그인 엔트리 스캔
|
||||
- `JsonConfigScanner.cs` — Json/*.json top-level 키 + 의심 필드 휴리스틱
|
||||
- `AssemblyScanner.cs` — HmEG*/Editor*/HmGeometry* 어셈블리 + PDB 존재
|
||||
|
||||
**주의**: sut-prober 구현은 contract를 **선제적으로 맞추지는 않음** — 빌드·실행·evaluator 검증은 별도 Generator 세션의 몫. 현재는 컴파일 가능한 뼈대 수준.
|
||||
|
||||
## 병렬화 전략
|
||||
|
||||
- 파일 간 의존성 0인 것들만 병렬 Write
|
||||
- Edit는 기존 파일 의존 → 순차 처리
|
||||
- 에이전트 스폰 대신 단일 세션 다중 도구 호출로 context 오버헤드 최소화
|
||||
|
||||
## 다음 단계
|
||||
|
||||
1. **Generator 세션**에서 sut-prober 빌드/실행 → 카탈로그 산출물 생성
|
||||
2. **Evaluator 세션**에서 `/evaluate sut-prober` → contract DoD 채점
|
||||
3. pass 시 PROGRESS.md → PLAN.md 제거 → P1 항목 착수
|
||||
100
docs/sut-catalog/catalog.md
Normal file
100
docs/sut-catalog/catalog.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# SUT Catalog (v0, 정적 분석)
|
||||
|
||||
> 수동 관찰 기반 초기 카탈로그. `sut-prober` PoC 완료 시 기계 생성 파일로 교체된다.
|
||||
> 마지막 갱신: 2026-04-07
|
||||
|
||||
## 개요
|
||||
|
||||
- **이름**: EG-BIM Modeler
|
||||
- **위치**: `EG-BIM Modeler/` (git 제외)
|
||||
- **실행파일**: `EG-BIM Modeler.exe` (.NET / WPF)
|
||||
- **구성**: `.deps.json`, `.runtimeconfig.json`, `.pdb` 동봉
|
||||
|
||||
## 핵심 어셈블리
|
||||
|
||||
| 이름 | 역할 | PDB |
|
||||
|------|------|-----|
|
||||
| `HmEG.dll` | 자체 3D 엔진 | ✅ (`HmEG.pdb`, `HmEG.xml`) |
|
||||
| `HmGeometry.dll` / `HmGeometry.V2.dll` | 지오메트리 커널 | ✅ |
|
||||
| `HmTriangle.dll` | 삼각분할 | ✅ |
|
||||
| `HmPG.dll` | (추정) 페러미터 그래프/프로파일 | - |
|
||||
| `HmCommonUI.dll`, `HmCommonBridge.dll` | 공통 UI / 네이티브 브릿지 | - |
|
||||
| `Editor02.HmEGAppManager.dll` | 앱 생명주기 / plugin 매니저 (MEF 로드 추정) | ✅ |
|
||||
| `Editor03.PluginInterface.dll` | Plugin 기본 계약 | ✅ |
|
||||
| `Editor04.CommandControl.dll` | 명령 파이프라인 UI | ✅ |
|
||||
| `Editor05.CommandCore.dll` | 명령 실행 코어 | ✅ |
|
||||
| `Editor06.CommandCustom.dll` | 커스텀 명령 | ✅ |
|
||||
| `Editor07.WidgetPluginInterface.dll` | 위젯 플러그인 계약 | ✅ |
|
||||
| `EditorCore.dll` | Editor 코어 | ✅ |
|
||||
| `Editor01.Localization.dll` | 다국어 | ✅ |
|
||||
| `Editor.AI01.HttpConnector.dll` | AI 연동 | ✅ |
|
||||
|
||||
## 렌더링
|
||||
|
||||
- **SharpDX** (D3D9/D3D11/DXGI/Direct2D, Mathematics, D3DCompiler)
|
||||
- 3D 뷰포트는 D3D surface → **UIA 사각지대**
|
||||
- `assimp.dll` / `AssimpNet.dll` → 메시 임포트
|
||||
- `freetype6.dll`, `SharpFont.dll` → 폰트
|
||||
- `SharpVectors.*` → SVG 지원
|
||||
|
||||
## UI 스택
|
||||
|
||||
- `MahApps.Metro`, `ControlzEx`, `Dragablz`
|
||||
- `CommunityToolkit.Mvvm`
|
||||
- `Microsoft.Xaml.Behaviors`, `System.Windows.Interactivity`
|
||||
- `System.Windows.Controls.WpfPropertyGrid`
|
||||
- `Microsoft.Web.WebView2.*` (WebView2 패널)
|
||||
|
||||
## 유틸/공용
|
||||
|
||||
- `Serilog` + `Serilog.Sinks.File`, `log4net`
|
||||
- `Newtonsoft.Json`, `Google.Protobuf`, `MemoryPack.Core`
|
||||
- `UnitsNet`, `FluentScheduler`, `System.Reactive`, `Flurl.Http`
|
||||
- `BaronSoftware.Auth.dll` — 인증/라이선스 추정 (**레코딩 시 민감정보 주의**)
|
||||
|
||||
## Json 설정 (텍스트 golden-file 1차 타깃)
|
||||
|
||||
`EG-BIM Modeler/Json/`:
|
||||
|
||||
- `Settings.json`, `DefaultSettings.json`
|
||||
- `CategoryCommands.json`, `DefaultCategoryCommands.json`
|
||||
- `CommandAlias.json`, `DefaultCommandAlias.json`
|
||||
- `KeyShortCut.json`, `DefaultKeyShortCut.json`
|
||||
- `MouseSnap.json`, `DefaultMouseSnap.json`
|
||||
- `StartupCommand.json`, `DefaultStartupCommand.json`
|
||||
- `Units.json`, `DefaultUnits.json`
|
||||
- `Materials.json`
|
||||
- `RecentFiles.json` — **확실히 비결정적** (최근 사용 파일 경로)
|
||||
|
||||
### 비결정성 후보 필드 (정규화 대상)
|
||||
|
||||
- `RecentFiles.json` 전체
|
||||
- 모든 `Settings.json` 내부의 경로·창 크기·마지막 실행 시간
|
||||
- GUID·타임스탬프 (포맷 확인 필요)
|
||||
|
||||
## 저장 파일 포맷
|
||||
|
||||
- `lmd.hme` — 자체 모델 포맷 (`.hme`)
|
||||
- `jversion.egm` — 버전/메타 파일
|
||||
- **바이너리 추정** — 별도 포맷 분석 contract 필요
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
- `ko-KR`, `en-US`, `ja-JP`, `es-ES` 리소스 폴더
|
||||
- `Editor01.Localization.dll` 경유
|
||||
|
||||
## MEF Plugin
|
||||
|
||||
- 위치: `EG-BIM Modeler/Plugins/Eg*Plugin/`
|
||||
- **총 187개** (2026-04-07 스냅샷)
|
||||
- 카테고리: 생성(Box, Circle, Arc, Curve, Cone, Cylinder …), Boolean(Union/Intersection/Difference), Array(Linear/Polar/Crv), Align, Check(Border/Disjointed/Duplicated/NonManifold/Self-Intersection/Overlap/ZeroArea/ZeroCurve), Audit, Block(Edit), Chamfer, Clash, Cap, Cut, DeleteFaces, Import/Export 등
|
||||
- 전체 목록: [plugins.md](plugins.md)
|
||||
|
||||
## recordingtest 영향 요약
|
||||
|
||||
1. **1차 검증 타깃**: `Json/` 텍스트 파일 (정규화 쉬움)
|
||||
2. **2차**: `.hme`/`.egm` 파서 필요
|
||||
3. **3D 뷰포트**: 좌표 입력 + engine-bridge
|
||||
4. **Plugin 카탈로그**: sut-prober 자동 덤프
|
||||
5. **PDB 풍부** → engine-bridge 리플렉션 비용 낮음
|
||||
6. **인증/라이선스**: 자동화 테스트 환경에서 로그인 상태 유지/마스킹 필요
|
||||
199
docs/sut-catalog/plugins.md
Normal file
199
docs/sut-catalog/plugins.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# EG-BIM Modeler Plugin List
|
||||
|
||||
- **스냅샷 일시**: 2026-04-07
|
||||
- **총 개수**: 187
|
||||
- **경로**: `EG-BIM Modeler/Plugins/`
|
||||
|
||||
> 자동 생성 전 수동 덤프. `sut-prober` PoC 완료 시 `plugins.json`으로 교체된다.
|
||||
|
||||
## 전체 목록 (사전순)
|
||||
|
||||
```
|
||||
Eg3DFacePlugin
|
||||
Eg3DMImportExporter
|
||||
EgAddToGroupPlugin
|
||||
EgAlignPlugin
|
||||
EgAlignSelectedVerticesPlugin
|
||||
EgAlignVerticesPlugin
|
||||
EgAnglePlugin
|
||||
EgArcPlugin
|
||||
EgAreaCentroidPlugin
|
||||
EgAreaPlugin
|
||||
EgArrayCrvPlugin
|
||||
EgArrayLinearPlugin
|
||||
EgArrayPlugin
|
||||
EgArrayPolarPlugin
|
||||
EgAuditPlugin
|
||||
EgBlockEditPlugin
|
||||
EgBlockPlugin
|
||||
EgBooleanDifferencePlugin
|
||||
EgBooleanIntersectionPlugin
|
||||
EgBooleanUnionPlugin
|
||||
EgBoundingBoxPlugin
|
||||
EgBoxPlugin
|
||||
EgBuildSectionPlugin
|
||||
EgCPlanePlugin
|
||||
EgCapPlugin
|
||||
EgChamferPlugin
|
||||
EgChangeColorPlugin
|
||||
EgCheckBorderEdgePlugin
|
||||
EgCheckDisjointedMeshPlugin
|
||||
EgCheckDuplicatedVertexPlugin
|
||||
EgCheckNonManifoldEdgePlugin
|
||||
EgCheckSelfIntersectionPlugin
|
||||
EgCheckSelfOverlapPlugin
|
||||
EgCheckZeroAreaPlugin
|
||||
EgCheckZeroCurvePlugin
|
||||
EgCirclePlugin
|
||||
EgClashPlugin
|
||||
EgCloseCrvPlugin
|
||||
EgClosestPtPlugin
|
||||
EgConePlugin
|
||||
EgConvertTextToBlockAttributePlugin
|
||||
EgCopyPlugin
|
||||
EgCopyToClipboardPlugin
|
||||
EgCrvEndPlugin
|
||||
EgCrvStartPlugin
|
||||
EgCurvePlugin
|
||||
EgCurveThroughPtPlugin
|
||||
EgCutPlugin
|
||||
EgCylinderPlugin
|
||||
EgDeleteFacesPlugin
|
||||
EgDeletePlugin
|
||||
EgDeleteSubCrvPlugin
|
||||
EgDeselByUidsPlugin
|
||||
EgDimAnglePlugin
|
||||
EgDirPlugin
|
||||
EgDistancePlugin
|
||||
EgDividePlugin
|
||||
EgDomainPlugin
|
||||
EgDotPlugin
|
||||
EgDupBorderPlugin
|
||||
EgDupEdgePlugin
|
||||
EgDupMeshHoleBoundaryPlugin
|
||||
EgEditTheGradingElevationPlugin
|
||||
EgEllipsePlugin
|
||||
EgEllipsoidPlugin
|
||||
EgEvaluatePtPlugin
|
||||
EgExplodeBlockPlugin
|
||||
EgExplodePlugin
|
||||
EgExportByPathPlugin
|
||||
EgExtendPlugin
|
||||
EgExtractMeshFacePlugin
|
||||
EgExtractNonManifoldMeshEdgesPlugin
|
||||
EgExtractPtPlugin
|
||||
EgExtrudeAlongCrvPlugin
|
||||
EgExtrudePlugin
|
||||
EgFillMeshHolePlugin
|
||||
EgFilletEdgePlugin
|
||||
EgFilletPlugin
|
||||
EgFilterByFaceCountPlugin
|
||||
EgFilterByLayerPlugin
|
||||
EgFilterByLengthPlugin
|
||||
EgFilterByModelTypePlugin
|
||||
EgFilterBySpatialBoxPlugin
|
||||
EgFilteringWithXYPlanePlugin
|
||||
EgFindTextPlugin
|
||||
EgFlipPlugin
|
||||
EgGroupPlugin
|
||||
EgHandleCurvePlugin
|
||||
EgHidePlugin
|
||||
EgHyperbolaPlugin
|
||||
EgImportByPathPlugin
|
||||
EgInsertPlugin
|
||||
EgInterpCrvPlugin
|
||||
EgIsolatePlugin
|
||||
EgJoinPlugin
|
||||
EgLengthPlugin
|
||||
EgLinePlugin
|
||||
EgLineSmoothPlugin
|
||||
EgLoftPlugin
|
||||
EgMarginLinePlugin
|
||||
EgMatchPropertiesPlugin
|
||||
EgMergeFacesPlugin
|
||||
EgMeshIntersectPlugin
|
||||
EgMeshPatchPlugin
|
||||
EgMeshPolylinePlugin
|
||||
EgMirrorPlugin
|
||||
EgModelClearPlugin
|
||||
EgMovePlugin
|
||||
EgObjectDescriptionPlugin
|
||||
EgOffsetMeshPlugin
|
||||
EgOffsetPlugin
|
||||
EgOneLayerOffPlugin
|
||||
EgOneLayerOnPlugin
|
||||
EgOpenURLPlugin
|
||||
EgOrientPlugin
|
||||
EgParabolaPlugin
|
||||
EgPastePlugin
|
||||
EgPatchPlugin
|
||||
EgPipePlugin
|
||||
EgPlanarDifferencePlugin
|
||||
EgPlanarIntersectionPlugin
|
||||
EgPlanarUnionPlugin
|
||||
EgPlanePlugin
|
||||
EgPlaneThroughPtPlugin
|
||||
EgPointPlugin
|
||||
EgPointsOffPlugin
|
||||
EgPointsOnPlugin
|
||||
EgPointsPlugin
|
||||
EgPolygonCountPlugin
|
||||
EgPolygonPlugin
|
||||
EgPolylinePlugin
|
||||
EgProfileSweepPlugin
|
||||
EgProjectPlugin
|
||||
EgProjectionPointPlugin
|
||||
EgPyramidPlugin
|
||||
EgRLeaderEditPlugin
|
||||
EgRebuildPlugin
|
||||
EgRectanglePlugin
|
||||
EgReduceMeshPlugin
|
||||
EgRemoveFromGroupPlugin
|
||||
EgRemoveSelfIntersectionPlugin
|
||||
EgRepairCrvTopologyPlugin
|
||||
EgRevolvePlugin
|
||||
EgRibbonPlugin
|
||||
EgRoadSectionPlugin
|
||||
EgRotate3DPlugin
|
||||
EgRotatePlugin
|
||||
EgScale1DPlugin
|
||||
EgScale2DPlugin
|
||||
EgScalePlugin
|
||||
EgScreenShotPlugin
|
||||
EgSelBoxPlugin
|
||||
EgSelByUidsPlugin
|
||||
EgSelColorPlugin
|
||||
EgSelLayerPlugin
|
||||
EgSelNamePlugin
|
||||
EgSelectedLayersOffPlugin
|
||||
EgSetDisplayModePlugin
|
||||
EgSetFocusedViewportPlugin
|
||||
EgSetGroupNamePlugin
|
||||
EgSetObjectNamePlugin
|
||||
EgSetViewmodePlugin
|
||||
EgShearPlugin
|
||||
EgShowPlugin
|
||||
EgSlabPlugin
|
||||
EgSlopePlugin
|
||||
EgSnipCrvPlugin
|
||||
EgSpherePlugin
|
||||
EgSplitDisjointMeshPlugin
|
||||
EgSplitPlugin
|
||||
EgSrfPtPlugin
|
||||
EgSubCrvPlugin
|
||||
EgSurfaceQuadRemeshPlugin
|
||||
EgSweep1Plugin
|
||||
EgSweep2Plugin
|
||||
EgTextPlugin
|
||||
EgTorusPlugin
|
||||
EgTrimPlugin
|
||||
EgTruncatedPyramidPlugin
|
||||
EgTubePlugin
|
||||
EgUnGroupPlugin
|
||||
EgUngroupAllPlugin
|
||||
EgUnifyNormalPlugin
|
||||
EgVerticalScalePlugin
|
||||
EgVolumeCentroidPlugin
|
||||
EgZoomPlugin
|
||||
HMEGImportExport
|
||||
```
|
||||
Reference in New Issue
Block a user