From c071a444bc08ef71daaf3b7e6d1b2d6cd1209aea Mon Sep 17 00:00:00 2001 From: "Jung Hyun, Nam" Date: Sun, 25 Oct 2026 00:16:09 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20=EC=9B=90=EA=B2=A9=20=EC=8A=A4?= =?UTF-8?q?=ED=82=AC=20=EB=A7=88=EC=BC=93=ED=94=8C=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=EC=99=80=20=EC=A0=84=EC=9A=A9=20=EC=8A=A4=ED=82=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EC=B0=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + docs/SKILL_MARKETPLACE.ko.md | 47 ++ docs/SKILL_MARKETPLACE.md | 47 ++ external/TableClothCatalog | 2 +- .../Dialogs/OptionsWindow.axaml | 4 +- .../Dialogs/OptionsWindow.axaml.cs | 10 + .../Dialogs/SkillMarketplaceWindow.axaml | 140 ++++++ .../Dialogs/SkillMarketplaceWindow.axaml.cs | 46 ++ src/TableCloth.App/ManagedAi/ManagedAiText.cs | 53 ++- .../OptionsWindowViewModel.Skills.cs | 30 +- .../ViewModels/OptionsWindowViewModel.cs | 8 +- .../SkillMarketplaceWindowViewModel.cs | 377 ++++++++++++++++ src/TableCloth.ManagedAi.Core/Contracts.cs | 5 +- src/TableCloth.ManagedAi.Core/SkillCatalog.cs | 45 ++ .../ServiceCollectionExtensions.cs | 13 + .../Skills/GithubSkillInstaller.cs | 215 +++++++++ .../Skills/OpenAiCodexSkillManager.cs | 44 +- .../Skills/SkillCatalogClient.cs | 207 +++++++++ .../SkillMarketplaceTests.cs | 421 ++++++++++++++++++ src/TableCloth.ManagedAi.Test/SkillTests.cs | 95 +++- .../TableCloth.ManagedAi.Test.csproj | 1 + src/TableCloth.Test/SkillMarketplaceTests.cs | 333 ++++++++++++++ 22 files changed, 2121 insertions(+), 23 deletions(-) create mode 100644 docs/SKILL_MARKETPLACE.ko.md create mode 100644 docs/SKILL_MARKETPLACE.md create mode 100644 src/TableCloth.App/Dialogs/SkillMarketplaceWindow.axaml create mode 100644 src/TableCloth.App/Dialogs/SkillMarketplaceWindow.axaml.cs create mode 100644 src/TableCloth.App/ViewModels/SkillMarketplaceWindowViewModel.cs create mode 100644 src/TableCloth.ManagedAi.Core/SkillCatalog.cs create mode 100644 src/TableCloth.ManagedAi.OpenAi/Skills/GithubSkillInstaller.cs create mode 100644 src/TableCloth.ManagedAi.OpenAi/Skills/SkillCatalogClient.cs create mode 100644 src/TableCloth.ManagedAi.Test/SkillMarketplaceTests.cs create mode 100644 src/TableCloth.Test/SkillMarketplaceTests.cs diff --git a/README.md b/README.md index 17888614..fbe67fe7 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ WinGet 등록소 반영에는 GitHub Release 게시 이후 시간이 더 걸릴 - [업데이트 채널 문제 해결](docs/TROUBLESHOOTING_UPDATE_CHANNEL.md) - [Avalonia와 Native AOT 전환 기록](docs/AVALONIA_AOT_MIGRATION.md) - [식탁보 AI Preview 구현 및 검증](docs/poc/managed-ai-runtime.md) +- [스킬 마켓플레이스와 원격 카탈로그](docs/SKILL_MARKETPLACE.ko.md), [English](docs/SKILL_MARKETPLACE.md) - [Windows Sandbox 내부 Codex CLI와 Computer Use 탐색 기록](docs/poc/codex-sandbox-computer-use.ko.md), [English](docs/poc/codex-sandbox-computer-use.md) - [Windows Sandbox RDP 호스팅 실험과 검증 기록](docs/poc/rdp-sandbox.ko.md), [English](docs/poc/rdp-sandbox.md) diff --git a/docs/SKILL_MARKETPLACE.ko.md b/docs/SKILL_MARKETPLACE.ko.md new file mode 100644 index 00000000..fa2ca8e1 --- /dev/null +++ b/docs/SKILL_MARKETPLACE.ko.md @@ -0,0 +1,47 @@ +# 스킬 마켓플레이스와 원격 카탈로그 + +2026년 10월 25일 기준으로 이번 구현은 식탁보 `develop` 계열을 대상으로 합니다. 마켓플레이스는 TableClothCatalog의 별도 XML 스킬 카탈로그를 읽고 식탁보 AI 전용 Codex 프로필에 설치한 스킬을 관리합니다. 현재 공개한 Preview 릴리스에는 이번 변경을 포함하지 않습니다. + +마켓플레이스에서 후보 검색, 출처와 라이선스 열람, 설치 검토 상태 확인, 로컬 스킬 관리를 함께 제공합니다. 최초 카탈로그에 후보 열두 개를 등록하고 설치 검토 상태를 대기로 유지합니다. + +이 문서에서는 창의 사용 경로부터 카탈로그 계약, 설치 허용 조건, 로컬 저장 범위, 검증 범위 순서로 살펴보겠습니다. [English](SKILL_MARKETPLACE.md) + +## AI 설정에서 여는 마켓플레이스 + +마켓플레이스의 진입 경로를 정리하겠습니다. **옵션 > AI 스킬 > 스킬 마켓플레이스 열기**를 선택하면 별도 창을 엽니다. 창에서 카탈로그와 설치된 스킬을 각각 조회할 수 있습니다. 검색으로 목록을 좁히고 카탈로그의 분야 필터로 후보를 선택할 수 있습니다. 후보를 선택하면 출처, 저자, 라이선스, 검토 상태, 적용 조건을 표시합니다. + +이어서 카탈로그 조회와 로컬 작업의 관계를 짚어보겠습니다. 두 작업은 진행 상태를 각각 관리합니다. 카탈로그 요청에 실패해도 설치된 스킬을 관리할 수 있습니다. [창](../src/TableCloth.App/Dialogs/SkillMarketplaceWindow.axaml)과 [뷰 모델](../src/TableCloth.App/ViewModels/SkillMarketplaceWindowViewModel.cs)이 이 동작을 구현합니다. + +## 버전을 지정하는 별도 XML 카탈로그 + +카탈로그는 `https://catalog.yourtablecloth.app/SkillCatalog.xml`에서 제공합니다. 원본은 [TableClothCatalog의 docs 디렉터리](https://github.com/yourtablecloth/TableClothCatalog/tree/main/docs)에 두며 `SkillCatalog.xsd`와 기여 안내를 함께 관리합니다. 기존 Pages 워크플로가 `main`에 반영한 파일을 게시합니다. + +`SkillCatalog Version="1"` 아래에 고정 ID를 가진 `Skill` 항목을 기록합니다. 각 항목은 GitHub 저장소, 경로, 고정한 원본 커밋을 지정합니다. 설명, 저자, SPDX 식별자, 라이선스 근거, 런타임과 네트워크 요구 사항, 설치 방식, 검토 상태, 적용 조건도 기록합니다. 후보 등록만으로 설치를 허용하지 않습니다. [공용 모델](../src/TableCloth.ManagedAi.Core/SkillCatalog.cs)에 애플리케이션이 읽는 필드를 정의했습니다. + +## 원격 설치를 허용하는 검토 조건 + +원격 설치의 허용 조건을 확인하겠습니다. 목록에 공개한 upstream 스킬 가운데 라이선스 검토를 완료하고 설치를 승인한 항목만 설치할 수 있습니다. 원본 커밋도 고정합니다. 라이선스 근거는 같은 저장소와 커밋의 파일을 가리킵니다. 검토 대기나 거절 상태, 목록 제외 상태, MCP 어댑터 후보에서는 다운로드를 시작하지 않습니다. 설치 시 클라이언트가 스킬 ID로 현재 카탈로그를 다시 조회합니다. + +클라이언트는 Git 체크아웃 없이 GitHub REST API로 선택한 파일을 조회합니다. 경로와 저장소 항목을 검사하고 요청 및 다운로드 크기를 제한합니다. 링크와 서브모듈을 거절하며 임시 디렉터리에 파일을 받은 뒤 기존 스킬 가져오기 기능으로 전달합니다. 고정한 라이선스 파일도 `LICENSE.upstream`으로 보존합니다. XML 파서는 외부 엔터티와 DTD를 허용하지 않습니다. [OpenAI 백엔드](../src/TableCloth.ManagedAi.OpenAi/Skills)가 이 검사를 수행합니다. + +다만 최초 후보의 검토 상태는 모두 대기로 유지합니다. 후보에 따라 API 키, OAuth 자격 증명, MCP 어댑터 또는 Node.js CLI가 필요합니다. 카탈로그의 적용 조건에 이러한 의존성을 기록합니다. 마켓플레이스는 해당 서비스를 설정하거나 전용 런타임의 실행 권한을 확장하지 않습니다. + +## 전용 프로필 안의 로컬 스킬 관리 + +설치된 스킬 화면에서 폴더 가져오기, 활성화와 비활성화, 확인 후 제거, 새로 고침, 스킬 폴더 열기를 제공합니다. 사용 설정은 이후 AI 작업에 적용합니다. 스킬을 제거하면 해당 전용 폴더도 삭제합니다. + +잘못된 `SKILL.md`도 오류 상태로 목록에 표시합니다. 해당 항목을 비활성화하거나 폴더를 열어 확인하고 개별 제거할 수 있습니다. 다른 스킬의 관리도 계속할 수 있습니다. 오류 항목의 활성화는 차단합니다. AI 실행은 잘못된 관리 대상 manifest를 복구하거나 제거할 때까지 오류로 중단합니다. + +스킬은 `%LOCALAPPDATA%\TableCloth\ManagedAi\profiles\openai-codex\codex-home\skills`에 보관합니다. 기존 가져오기 기능과 작업 잠금이 변경 작업을 제어합니다. 마켓플레이스는 이 프로필을 관리합니다. 사용자 전역 Codex 프로필과 스킬은 관리 범위에 포함하지 않습니다. [스킬 관리자](../src/TableCloth.ManagedAi.OpenAi/Skills/OpenAiCodexSkillManager.cs)와 [관리 경로](../src/TableCloth.ManagedAi.Core/ManagedAiPaths.cs)에서 저장 범위를 확인할 수 있습니다. + +## 자동 검증과 게시 경로의 구분 + +자동 검증의 범위를 검토하겠습니다. 테스트는 카탈로그 파싱, 검토 조건, 다운로드 검증, 뷰 모델 명령을 다룹니다. Avalonia 헤드리스 테스트는 실제 창을 생성합니다. 테스트에는 합성 스킬과 HTTP 응답을 사용합니다. 후보 서비스의 사용자 자격 증명 연동이나 MCP 어댑터의 동작은 이 테스트로 확인하지 않습니다. [백엔드 테스트](../src/TableCloth.ManagedAi.Test/SkillMarketplaceTests.cs)와 [UI 테스트](../src/TableCloth.Test/SkillMarketplaceTests.cs)에 검증 항목을 기록했습니다. + +카탈로그와 애플리케이션은 서로 다른 경로로 배포합니다. TableClothCatalog가 XML을 게시하면 원격 후보를 조회할 수 있습니다. 사용자는 이후 식탁보 빌드에서 마켓플레이스 창을 사용할 수 있습니다. 카탈로그 게시를 기다리는 동안에도 애플리케이션에서 설치된 스킬을 관리할 수 있습니다. + +## 후보 검토와 설치 승인 + +여기까지 정리하면 카탈로그는 후보와 적용 조건을 기록하고 설치 승인 상태를 함께 제공합니다. 관리자는 고정한 원본 리비전의 호환성을 검토한 뒤 upstream 스킬을 승인할 수 있습니다. 애플리케이션의 후보 목록을 코드로 수정하는 절차는 거치지 않습니다. + +로컬 스킬 관리는 후보 승인과 독립적으로 사용할 수 있습니다. 서비스 자격 증명, 민감한 문서 접근, MCP 어댑터 개발은 후보별로 검토합니다. 각 후보의 적용 조건과 전용 런타임 호환성을 확인한 결과에 따라 설치를 승인할 수 있습니다. diff --git a/docs/SKILL_MARKETPLACE.md b/docs/SKILL_MARKETPLACE.md new file mode 100644 index 00000000..2173afec --- /dev/null +++ b/docs/SKILL_MARKETPLACE.md @@ -0,0 +1,47 @@ +# Skill marketplace and remote catalog + +As of October 25, 2026, the marketplace implementation targets the TableCloth `develop` line. It reads a separate XML skill catalog from TableClothCatalog and manages the skills in TableCloth AI's dedicated Codex profile. This work does not change the published Preview release. + +The marketplace combines candidate discovery, source and license information, installation review, and local skill management. The initial catalog lists twelve candidates. Their installation reviews remain pending. + +This guide explains the window, catalog contract, installation policy, local storage, and verification boundaries in that order. [한국어](SKILL_MARKETPLACE.ko.md) + +## Marketplace access from AI settings + +Open **Options > AI skills > Open skill marketplace**. The marketplace provides separate catalog and installed-skill views. Search narrows the lists, and the catalog also supports a category filter. Selecting a candidate shows its source, author, license, review state, and adoption notes. + +Catalog loading and local management use separate operation states. A failed catalog request leaves installed-skill management available. The [window](../src/TableCloth.App/Dialogs/SkillMarketplaceWindow.axaml) and [view model](../src/TableCloth.App/ViewModels/SkillMarketplaceWindowViewModel.cs) own this behavior. + +## A separate versioned XML catalog + +The application reads `https://catalog.yourtablecloth.app/SkillCatalog.xml`. The source lives in [TableClothCatalog's catalog directory](https://github.com/yourtablecloth/TableClothCatalog/tree/main/docs), alongside `SkillCatalog.xsd` and its contributor guide. The catalog's existing Pages workflow publishes the files after a change reaches `main`. + +`SkillCatalog Version="1"` contains `Skill` entries with stable IDs. Each entry identifies a GitHub repository, a path, and an immutable source commit. Descriptions, authors, SPDX identifiers, license evidence, runtime and network requirements, install mode, review states, and adoption notes describe each candidate. Catalog listing does not grant installation approval. See the [shared model](../src/TableCloth.ManagedAi.Core/SkillCatalog.cs). + +## Review gates before remote installation + +Remote installation accepts only listed upstream skills with a verified license review, an approved installation review, and a fixed source commit. The license source also points to a file in that repository at the same commit. Pending or rejected reviews, unlisted entries, and MCP adapter candidates cannot start a download. Installation rechecks the current catalog by skill ID. + +The client fetches selected files through GitHub REST APIs without a Git checkout. It validates paths and repository entries, bounds requests and downloaded data, rejects links and submodules, and stages files before calling the existing skill importer. It preserves the pinned license file as `LICENSE.upstream`. XML parsing disables external entities and DTDs. The [OpenAI backend](../src/TableCloth.ManagedAi.OpenAi/Skills) implements these checks. + +The initial candidates retain pending reviews. Some need API keys, OAuth credentials, an MCP adapter, or a Node.js CLI. The catalog notes record those dependencies. The marketplace does not configure those services or extend the dedicated runtime's execution permissions. + +## Local management within the dedicated profile + +The installed view supports folder import, enable and disable actions, removal with confirmation, refresh, and opening skill folders. Enabled-state changes apply to subsequent AI operations. Removing a skill removes its dedicated folder. + +A malformed `SKILL.md` remains visible with an invalid-manifest state. It can be disabled, inspected, or removed while other skills remain manageable. Enabling that entry is blocked. AI execution still rejects invalid managed manifests until they are repaired or removed. + +Skills remain under `%LOCALAPPDATA%\TableCloth\ManagedAi\profiles\openai-codex\codex-home\skills`. TableCloth's existing importer and operation lock continue to control mutations. The marketplace manages this profile; the user's global Codex profile and skills remain outside its scope. See [the skill manager](../src/TableCloth.ManagedAi.OpenAi/Skills/OpenAiCodexSkillManager.cs) and [managed paths](../src/TableCloth.ManagedAi.Core/ManagedAiPaths.cs). + +## Verification and publication boundaries + +Automated checks cover catalog parsing, review gates, download validation, and view-model actions. Headless Avalonia checks exercise the actual window. These checks use synthetic skills and HTTP responses. They do not establish that the candidate services work with user credentials or that an MCP adapter exists. See [backend tests](../src/TableCloth.ManagedAi.Test/SkillMarketplaceTests.cs) and [UI tests](../src/TableCloth.Test/SkillMarketplaceTests.cs). + +The catalog and application have separate release paths. The catalog becomes available after TableClothCatalog publishes it. Users receive the window through a subsequent TableCloth build. An application build can manage installed skills while catalog publication is still pending. + +## Candidate review and installation approval + +The catalog records candidates and their adoption conditions. A maintainer can review a pinned revision and approve a compatible upstream skill without changing the application's candidate list. + +Local management is available independently of candidate approval. Service credentials, sensitive document access, and MCP adaptation remain specific to each candidate. Approval can follow that candidate's documented conditions and runtime compatibility checks. diff --git a/external/TableClothCatalog b/external/TableClothCatalog index 2c6d248f..a470989c 160000 --- a/external/TableClothCatalog +++ b/external/TableClothCatalog @@ -1 +1 @@ -Subproject commit 2c6d248fc1cfc9baba9ff9cdad5612787fcb94a9 +Subproject commit a470989ce6ee2e93b2b2967cd606504f04b5d3ab diff --git a/src/TableCloth.App/Dialogs/OptionsWindow.axaml b/src/TableCloth.App/Dialogs/OptionsWindow.axaml index 0aeb4df6..89d403ef 100644 --- a/src/TableCloth.App/Dialogs/OptionsWindow.axaml +++ b/src/TableCloth.App/Dialogs/OptionsWindow.axaml @@ -186,11 +186,13 @@