원문 캡처 · github.com
원문 캡처 · github.com

Omasharp는 C#과 QML로 Omarchy 앱을 만들 수 있는 템플릿이다. 제작자에 따르면 앱은 Omarchy에 기본 포함된 C++ 앱처럼 빠르게 시작하며, 배포된 앱을 실행하는 데 .NET 설치가 필요하지 않다.

sh
dotnet new install Omasharp.Templates
dotnet new omarchy-app -n Tally

앱의 로직은 Backend.cs에, UI는 Main.qml에 작성한다. dotnet publish는 C#을 네이티브 코드로 컴파일하고 작은 Qt 호스트와 결합한다. 앱은 Omarchy가 이미 제공하는 Qt에서 실행된다. --kind panel을 추가하면 Omarchy 셸 패널을 만들 수 있다. 이때도 같은 Backend.cs를 사용하지만 별도 프로세스에서 실행하므로 코드가 충돌해도 셸이 함께 종료되지 않는다.

모든 앱에는 .agents/skills/omasharp/에 에이전트 스킬도 들어간다. 코딩 에이전트는 이 스킬을 읽고 앱을 빌드하고 검사하고 설치하는 방법을 익힌다. Omasharp는 Linux x64와 Omarchy 4(Hyprland, Qt 6.7 이상)에서 실행된다. Omarchy나 Basecamp와 제휴한 프로젝트는 아니다.

C#을 사용하는 이유와 성능 비교

프로젝트 설명에 따르면 C++과 qmake는 작은 Omarchy 유틸리티에 적합하지만, 앱에 복잡한 로직이 들어가면 C#의 NuGet, 비동기 I/O, 메모리 안전성, 에이전트가 처리할 수 있는 컴파일 오류가 이점이 될 수 있다. C# 앱의 일반적인 단점으로는 느린 시작 시간과 메모리 사용량이 꼽히지만, Omasharp 앱은 그 비용을 치르지 않는다고 제작자는 설명한다.

프로젝트는 Omarchy의 계산기 omacalc와 이를 C#으로 포팅한 앱을 비교했다. 아래 수치는 7회씩 교차 실행한 결과의 중앙값이며, 전체 결과는 저장소의 예제에서 확인할 수 있다.

측정 항목omacalc (C++)Omasharp (C#)
창이 뜨기까지 걸린 시간618 ms593 ms
메모리(PSS)74.6 MB77.8 MB
유휴 상태 깨우기 횟수3/s3/s
실행에 .NET 필요아니요아니요

테마와 빠른 시작

앱은 현재 Omarchy 테마를 따르며 테마를 바꾸면 화면을 다시 그린다. QML에서는 theme.accent, theme.background 등 테마의 colors.toml에 있는 모든 키를 바인딩할 수 있다. C#에서는 같은 색을 Theme에서 가져오며 Changed 이벤트도 사용할 수 있다.

앱을 만들고 실행하려면 먼저 Omarchy에서 .NET SDK를 설치한다. 터미널에서 omarchy pkg add dotnet-sdk를 실행하거나 Omarchy 메뉴의 Install › Development › .NET을 이용할 수 있다. 그다음 템플릿을 설치하고 앱을 만든다.

sh
dotnet new install Omasharp.Templates
dotnet new omarchy-app -n Tally

패널로 만들 때는 --kind panel을 추가한다. --app-id는 앱 ID를 설정하며, 기본값은 tally다. 앱 디렉터리에서 dotnet run을 실행하면 앱이 열린다. 에이전트는 스킬에 포함된 check.sh로 화면 밖에서 앱을 검사할 수 있다. dotnet publish -t:Install은 앱을 ~/.local/bin/tally에 설치하고 실행기 항목을 만든다.

창 앱을 공유하려면 GitHub에 푸시하고 버전에 태그를 붙인다. 템플릿의 릴리스 워크플로가 앱을 GitHub 릴리스에 첨부한다. 사용자는 sudo나 .NET 없이 다음 명령 하나로 설치할 수 있다. 자세한 내용은 창 앱 공유 안내를 참조하면 된다.

sh
curl -fsSL https://github.com/<owner>/<repo>/releases/latest/download/install.sh | sh

빌드에는 SDK와 qmake6, g++, Qt 6이 필요하며, Qt 6은 Omarchy에 포함돼 있다. 게시된 앱을 실행하는 데 필요한 것은 Qt뿐이다. 아직 릴리스되지 않은 버전을 시험하려면 소스에서 템플릿을 빌드하면 된다. 방법은 CONTRIBUTING.md에 나와 있다.

코딩 에이전트로 앱 만들기

저장소를 에이전트에 제공하고 원하는 앱을 말하면 된다. 예를 들어 Omarchy 에이전트에 다음과 같이 요청할 수 있다.

sh
omarchy agent prompt "Build me a pomodoro timer for Omarchy with https://github.com/luisrudge/omasharp"

에이전트는 create-omasharp-app 스킬 설치를 제안한다. 설치한 뒤에는 저장소 링크를 주지 않아도 “Omarchy 앱을 만들어 줘”라고 요청할 수 있다.

에이전트가 스킬을 설치할 때 따라야 할 안내는 다음과 같다.

  • 스킬 파일을 가져온다: SKILL.md를 다운로드한다. 이 파일은 create-omasharp-app이라는 스킬의 SKILL.md이며, 사용자가 요청한 앱을 빌드하는 단계가 담겨 있다.
  • 사용자에게 에이전트용 스킬 설치를 제안한다. 먼저 동의를 구하고, 설치하면 다음부터 “Omarchy 앱을 만들어 줘”라는 요청만으로 이용할 수 있다고 설명한다. 거절하면 3단계로 넘어간다.
  • 각 코딩 에이전트의 사용자 수준 스킬 폴더를 확인한다. 에이전트마다 버전이 바뀌면서 폴더 위치가 달라질 수 있으므로 기억에 의존하지 말고 현재 환경을 살핀다.
  • 설치된 에이전트는 PATH에 있는 명령어로 확인한다. 예를 들면 claude, codex, pi, opencode, gemini 등이 있다. Omarchy에서는 omarchy default agent를 실행하면 사용자가 선택한 에이전트를 확인할 수 있다.
  • 각 에이전트가 스킬을 읽는 경로는 해당 에이전트의 문서나 현재 버전의 --help로 확인한다. 홈 디렉터리 안에 이미 스킬이 있는 폴더도 참고할 수 있다. 예를 들어 Omarchy는 설정한 각 에이전트의 스킬 폴더에 자체 omarchy 스킬을 연결한다.
  • 여러 에이전트가 공용 ~/.agents/skills도 읽을 수 있다. 에이전트가 공용 폴더와 자체 폴더를 모두 읽는다면 공용 폴더만 사용해도 된다. 두 곳에 설치하면 스킬이 중복해서 보일 수 있다. 어떤 에이전트의 경로인지 확인할 수 없다면 그 에이전트는 제외하고 사용자에게 알린다.
  • 파일을 쓰기 전에 폴더별로 어떤 에이전트가 읽는지 목록을 사용자에게 보여 주고 확인을 받는다. 사용자는 설치 대상을 줄일 수 있다.
  • 설치할 때는 첫 번째 폴더에 <folder>/create-omasharp-app/SKILL.md로 저장한다. 목록에 ~/.agents/skills가 있다면 그곳을 첫 번째 폴더로 쓴다. 나머지 확인된 폴더에는 다음 명령으로 연결한다.
sh
ln -sfn <that copy's folder> <folder>/create-omasharp-app
  • 기존 create-omasharp-app이 있으면 교체하기 전에 사용자에게 묻는다. 설치 후에는 설치한 위치를 알린다. 일부 에이전트는 새 스킬을 새 세션에서만 읽는다.
  • 사용자가 요청한 앱은 스킬을 설치했는지와 관계없이 스킬의 단계에 따라 만든다.

제공 기능

QML에서는 C# 클래스를 사용할 수 있다. 공개 속성과 메서드는 QML에서 backend.*로 표시되며 값이 바뀌면 바인딩이 업데이트된다. 비동기 메서드는 Promise를 반환하고, 레코드와 목록은 JavaScript 객체로 전달된다. C#에서 QML로 이벤트를 보낼 수 있으며, 백그라운드 스레드에서 상태를 바꾸는 것도 안전하다고 프로젝트는 설명한다. 자세한 내용은 작동 방식을 참조하면 된다.

앱은 Omarchy 테마 색과 글꼴을 사용하며, Hyprland 창 규칙에 맞춰 앱 ID를 정할 수 있다. C#의 Drawing과 QML의 DrawView는 Qt 장면 그래프를 이용해 차트, 지도, 트리맵을 그린다.

개발 과정에서는 에이전트가 코드를 수정한 뒤 스킬의 check.sh를 실행할 수 있다. 개발 빌드와 보이지 않는 상태에서의 실행까지 약 3초가 걸린다고 설명한다. 직접 앱을 확인하려면 dotnet run을 실행하면 된다.

빌드 경고는 오류로 처리된다. Omasharp 분석기는 Backend가 QML에서 사용할 수 있는지 검사한다. QML에서 사용할 수 없는 이름, QML에서 보이지 않는 멤버, 변경 사실을 알리지 않는 setter, 서로 전달할 수 없는 형식을 찾아내며, 각 오류에 수정 방법을 표시한다. 자세한 규칙은 분석기 안내에 있다.

에이전트가 실행할 수 있는 검사도 제공한다. 스킬의 check.sh는 단위 테스트를 실행한 다음 사용자가 볼 수 없는 비공개 컴포지터에서 앱을 시작한다. 화면에 표시되는 텍스트를 모두 출력하고 스크린샷을 저장하며, QML 오류가 있으면 실패 처리한다. --keys "12{Tab}3{Enter}"를 지정하면 먼저 앱에 해당 키 입력을 보낸다.

각 앱에는 shadcn 구성 요소처럼 브리지의 복사본이 포함되므로 필요에 따라 수정할 수 있다. dotnet build -t:UpdateBridge를 실행하면 수정 사항을 유지하면서 브리지의 최신 버전을 가져온다. 같은 Backend.cs를 창 앱과 패널 양쪽에서 사용할 수 있다.

저장소 구성과 참여

  • template/에는 새 앱이 받는 omarchy-app 템플릿이 있다. C# 브리지, C++ 호스트, 빌드 대상이 포함된 bridge/와 .agents/skills/omasharp/의 에이전트 스킬도 들어 있다.
  • skills/에는 새 앱을 시작할 때 에이전트가 한 번 설치하는 create-omasharp-app 스킬이 있다. 자세한 내용은 에이전트로 앱 만들기를 참조하면 된다.
  • analyzers/에는 각 앱에 적용되는 빌드 시점 검사 도구 Omasharp.Analyzers가 있다. 검사 규칙을 확인할 수 있다.
  • pack/은 Omasharp.Templates 패키지를 빌드한다.
  • examples/에는 Backend.cs 하나를 창 앱과 패널로 각각 사용하는 hello와 Omarchy 계산기를 C#으로 포팅한 omacalc가 있다.
  • scripts/의 test.sh는 CI에서 실행하는 모든 검사를 수행하고, lint.sh는 형식을 검사한다.
  • tools/에는 기여자를 위한 벤치마크 도구가 있다.
  • docs/에는 Omasharp의 작동 방식이 설명돼 있다.
  • assets/에는 로고와 아이콘이 있다.

이슈와 풀 리퀘스트는 본인이 작성했는지 에이전트가 작성했는지와 관계없이 환영한다고 프로젝트는 안내한다. 참여 방법은 CONTRIBUTING.md에 나와 있다. 라이선스는 MIT이며 LICENSE에서 확인할 수 있다. omacalc 예제는 omacalc의 MIT 라이선스와 글꼴의 OFL을 따른다. 자세한 내용은 라이선스 안내를 참조하면 된다.