From 47a4a961e29a338587db4040f24e67e0ebc7da0d Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Mon, 1 Jun 2026 13:44:46 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A9=80=ED=8B=B0=ED=99=89=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=20UI=20=EC=9E=90=EB=8F=99=20=EB=85=B8=EC=B6=9C=20(Out?= =?UTF-8?q?putsForInput=20=E2=86=92=20=EA=B7=B8=EB=9E=98=ED=94=84=20reacha?= =?UTF-8?q?bility)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ProviderRegistry.OutputsForInput을 그래프 transitive closure로 전환. UI 코드 변경 0으로 멀티홉 변환(json→xlsx, svg→jpg 등)이 사이드바·카스케이드 메뉴에 자동 노출된다. 동일 포맷 self-edge는 제외. - DirectOutputsForInput(1홉)도 별도 보존 - 카스케이드 메뉴는 PopularOutputs 교집합이라 폭발 없이 풍부해짐 - 테스트 1개 추가 (멀티홉 노출 검증) — 총 38개 통과 - SSOT P6 in_progress --- docs/ssot/PLAN.md | 2 +- docs/ssot/_data/status.json | 2 +- docs/ssot/index.html | 2 +- .../Providers/ProviderRegistry.cs | 12 ++++++++++++ .../ConversionGraphTests.cs | 16 ++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/ssot/PLAN.md b/docs/ssot/PLAN.md index 10b247c..666227d 100644 --- a/docs/ssot/PLAN.md +++ b/docs/ssot/PLAN.md @@ -193,7 +193,7 @@ Everything2Everything의 북극성은 "세상의 모든 변환을 원자(atomic) **Exit Criteria:** API 키 입력 시 PDF 요약·이미지 캡션·번역이 동작하고, 키가 없으면 AI 페어만 사라지고 모든 기존 변환은 100% 동작. -### P6 · 매트릭스 자동 극대화 + 헤드리스 CLI `effort:L` `risk:medium` `status:planned` · depends: P5 +### P6 · 매트릭스 자동 극대화 + 헤드리스 CLI `effort:L` `risk:medium` `status:in_progress` · depends: P5 **목표:** 앞 단계에서 쌓인 모든 엣지를 그래프가 자동 합성해 진짜 N×M·다방향을 완성하고(video→mp3→txt AI전사 등), 헤드리스 CLI로 자동화·스크립팅을 개방한다. **산출물:** diff --git a/docs/ssot/_data/status.json b/docs/ssot/_data/status.json index 09b3b0f..7aa979c 100644 --- a/docs/ssot/_data/status.json +++ b/docs/ssot/_data/status.json @@ -5,7 +5,7 @@ "P3": "in_progress", "P4": "in_progress", "P5": "in_progress", - "P6": "planned", + "P6": "in_progress", "P7": "in_progress", "P8": "planned" } diff --git a/docs/ssot/index.html b/docs/ssot/index.html index 824d6d3..bfd9371 100644 --- a/docs/ssot/index.html +++ b/docs/ssot/index.html @@ -445,7 +445,7 @@ footer{border-top:1px solid var(--line2);margin-top:60px;padding:30px 0;color:va
P6
매트릭스 자동 극대화 + 헤드리스 CLI
앞 단계에서 쌓인 모든 엣지를 그래프가 자동 합성해 진짜 N×M·다방향을 완성하고(video→mp3→txt AI전사 등), 헤드리스 CLI로 자동화·스크립팅을 개방한다.
-
예정LRISK mediumdepends · P5
+
진행중LRISK mediumdepends · P5

산출물

  • OutputsForInput을 transitive closure로 확장 — '이 파일로 만들 수 있는 모든 포맷' UI 노출 + 손실 경로 경고 배지
  • 멀티홉 도그푸딩 검증: hwp→pdf→png, video→mp3→txt(AI) 같은 신규 합성 경로 동작 확인
  • 헤드리스 CLI 분리: --json/--output-dir/--quality/--prompt/--codec/--recursive 플래그 + stdout JSON 결과 + exit code
  • 워치폴더 모드(FileSystemWatcher + 디바운스 + 파일잠금 재시도, 출력 디렉터리 분리로 무한루프 방지)
  • QuickProgressWindow 취소 토큰 전파 + 케이퍼빌리티 사전 점검
diff --git a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs index 09dcd68..c2054d1 100644 --- a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs +++ b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs @@ -55,6 +55,18 @@ public sealed class ProviderRegistry } public IReadOnlyList OutputsForInput(string inputExtension) + { + // 그래프 reachability(transitive closure)로 멀티홉 변환까지 노출한다 (예: json→xlsx, svg→jpg). + // 동일 포맷(self-edge: txt→txt AI, png→png 압축)은 '다른 형식으로 변환' 목록에서 제외. + var input = ConversionPair.Normalize(inputExtension); + return _graph.ReachableOutputs(input, maxHops: 3, allowLossy: true) + .Where(o => !string.Equals(o, input, StringComparison.OrdinalIgnoreCase)) + .OrderBy(e => e, StringComparer.OrdinalIgnoreCase) + .ToList(); + } + + /// 1홉 직접 출력만 (그래프 reachability 이전의 좁은 목록이 필요한 곳용). + public IReadOnlyList DirectOutputsForInput(string inputExtension) { var input = ConversionPair.Normalize(inputExtension); return _outputsByInput.TryGetValue(input, out var list) diff --git a/src/Everything2Everything.Tests/ConversionGraphTests.cs b/src/Everything2Everything.Tests/ConversionGraphTests.cs index 7843a78..1a186a0 100644 --- a/src/Everything2Everything.Tests/ConversionGraphTests.cs +++ b/src/Everything2Everything.Tests/ConversionGraphTests.cs @@ -207,4 +207,20 @@ public class RegistryGraphIntegrationTests var path = graph.FindBestPath(".png", ".pdf", maxHops: 3); Assert.NotNull(path); } + + [Fact] + public void OutputsForInput_ExposesMultiHopReachable() + { + var reg = Everything2EverythingBootstrap.CreateDefault().Providers; + + var jsonOut = reg.OutputsForInput(".json"); + Assert.Contains(".csv", jsonOut); // 직접 + Assert.Contains(".xlsx", jsonOut); // 멀티홉 json→csv→xlsx + Assert.DoesNotContain(".json", jsonOut); // 동일 포맷 self 제외 + + var svgOut = reg.OutputsForInput(".svg"); + Assert.Contains(".png", svgOut); // 직접 + Assert.Contains(".jpg", svgOut); // 멀티홉 svg→png→jpg + Assert.Contains(".pdf", svgOut); // 직접 + } }