Nodaro 문서
문서노드 레퍼런스모델템플릿AI 에이전트(MCP)개발자셀프 호스팅리서치비교

기여

GitHub에서 Nodaro에 코드를 기여하세요. 개발 환경을 준비하고 dev에서 브랜치를 만든 뒤, 테스트를 실행하고 changeset을 추가하고 기여자 계약에 서명합니다.

Nodaro에 기여한다는 것은 공개 리포지토리 github.com/nodaroai/app.nodaro.ai에 풀 리퀘스트로 코드를 보내는 것입니다. Nodaro는 Nodaro Sustainable Use License에 따라 source-available로 제공됩니다. 이 페이지에서는 개발 환경 설정, 브랜치, 풀 리퀘스트, 테스트, 기여자 계약을 다룹니다.

내 서버에서 Nodaro를 실행하려는 경우라면 빠른 시작부터 보세요. API를 기반으로 개발하려면 SDK를 참고하세요.

리포지토리

리포지토리는 npm 워크스페이스로 구성된 모노레포 하나입니다.

폴더들어 있는 것
backend/Fastify API, BullMQ 워커, 오케스트레이터. Node.js 22, TypeScript.
frontend/Vite 앱: 편집기, 앱 실행기, 관리자 패널. React 19, React Router 7, React Flow.
packages/스택 전체에서 공유하는 순수 로직인 @nodaro/shared, 타입이 지정된 REST 클라이언트인 @nodaro/sdk, @nodaro/cli, 프롬프트 계층인 @nodaro/prompts, Remotion 동영상 컴포지션.
supabase/앞으로만 진행되는 SQL 마이그레이션으로 관리하는 데이터베이스 스키마.
docs/리포지토리 안의 문서. 주요 기능의 설계 이유를 설명하는 설계 노트도 포함됩니다.
scripts/아키텍처 그래프 생성기와 감사 도구 같은 리포지토리 유틸리티.
.changeset/공개 패키지의 대기 중인 버전 올림.

프로젝트 규칙은 리포지토리 루트의 CLAUDE.md에 있습니다. 코딩 표준, 모델 공급자 추가 체크리스트, 노드 추가 체크리스트가 담겨 있습니다. 간단하지 않은 풀 리퀘스트를 보내기 전에 읽어 보세요. 구성 요소가 어떻게 맞물리는지는 아키텍처에서 설명합니다.

개발 환경 준비

npm이 포함된 Node.js 22 이상이 필요합니다.

클론과 설치

git clone https://github.com/nodaroai/app.nodaro.ai
cd app.nodaro.ai
# linux/x64 only: skip the CUDA download of onnxruntime-node
export ONNXRUNTIME_NODE_INSTALL=skip
npm install        # installs every workspace

linux/x64에서는 설치하기 전에 export 줄을 실행하세요. 이 줄이 없으면 얼굴 감지기의 런타임인 onnxruntime-node를 설치할 때 CUDA 12와 TensorRT 라이브러리를 내려받습니다. 얼굴 감지기는 이 라이브러리를 불러오지 않으며, 나중에 변수를 설정하고 다시 설치해도 이미 받은 라이브러리는 지워지지 않습니다. 이후 설치에서도 매번 다운로드를 건너뛰도록 이 줄을 셸 프로필에 넣으세요. macOS, Windows, linux/arm64에서는 이 라이브러리를 내려받지 않습니다.

환경 구성

cp .env.example .env

최소한 SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_ANON_KEY, INTERNAL_ORCHESTRATOR_SECRET과 KIE_API_KEY, REPLICATE_API_TOKEN, ANTHROPIC_API_KEY 같은 공급자 키 하나를 설정하세요. 시크릿을 생성하세요.

echo "INTERNAL_ORCHESTRATOR_SECRET=$(openssl rand -hex 32)" >> .env
echo "NODARO_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env

가장 쉬운 데이터베이스는 supabase.com의 무료 프로젝트입니다. Supabase CLI의 supabase start로 완전한 로컬 스택을 띄워도 되지만 설정이 더 필요합니다. 워크플로 실행에는 Redis도 필요하며, 기본값이 redis://localhost:6379인 REDIS_URL로 지정합니다. .env.example에 지원하는 모든 변수가 나열되어 있고, 구성에서 각 변수를 설명합니다.

공유 패키지를 한 번 빌드

프런트엔드는 @nodaro/shared를 빌드 출력에서 읽으므로, 처음 시작하기 전에 빌드하세요. 그 뒤에는 공유 코드를 편집하면 패키지 자체의 dev 스크립트가 다시 빌드합니다.

npm -w @nodaro/shared run build

개발 서버 시작

터미널 두 개에서 실행하세요.

# Terminal 1: the API on port 9000
cd backend
npm run dev

# Terminal 2: the frontend on port 3000, which forwards /v1/* to port 9000
cd frontend
npm run dev

코딩 표준

CLAUDE.md의 가장 중요한 규칙은 다음과 같습니다.

  • 파일 크기. 일반적으로 200~400줄이며, 800줄이 절대 상한입니다. 그보다 커지는 파일은 나누세요.
  • 프로덕션 코드에 console.log 금지. 기존 로거 패턴을 쓰세요.
  • Conventional Commits: feat:, fix:, refactor:, docs:, chore:, test:와 구체적인 제목 줄을 씁니다.
  • 커밋하기 전마다 타입 검사. backend/와 frontend/ 양쪽에서 npx tsc --noEmit을 실행하세요. 타입 검사를 통과하지 못한 풀 리퀘스트는 CI가 막습니다.
  • Express 라우터가 아니라 Fastify 플러그인. 모든 라우트 파일은 Fastify 인스턴스를 받는 async 함수를 내보냅니다.
  • 모든 API 엔드포인트에 Zod 스키마를 예외 없이 둡니다. 스키마는 요청을 검증하고 OpenAPI 문서도 만들어 냅니다.
  • 프런트엔드 상태: 서버 상태는 React Query, 인터페이스 상태는 Zustand, 캔버스 상태는 React Flow로 관리합니다. 섞지 마세요.
  • 객체나 배열을 절대 변경하지 마세요. 항상 새 사본을 만드세요. Zustand와 React Flow 모두 참조 동등성에 의존합니다.

브랜치와 풀 리퀘스트

  • 리포지토리에는 오래 유지되는 브랜치가 두 개 있습니다. 스테이징용 dev와 프로덕션용 main입니다.
  • 리포지토리를 포크하고, dev에서 브랜치를 만든 뒤 dev로 풀 리퀘스트를 여세요. main에서 브랜치를 만들거나 main에 직접 커밋하지 마세요.
  • 브랜치 이름은 유형으로 시작하세요: feat/, fix/, refactor/, docs/, chore/, test/. 예: feat/whisper-tts-node.
  • 병합된 변경 사항은 먼저 스테이징 인스턴스 next.nodaro.ai에서 실행됩니다. 약 24시간 검증한 뒤 메인테이너가 dev를 main으로 승격합니다.

풀 리퀘스트에서는 다음을 지켜 주세요.

  • 관련된 GitHub 이슈를 연결하세요.
  • 인터페이스를 바꾸는 경우 스크린숏이나 GIF를 추가하세요.
  • 노드를 추가하거나 바꿀 때는 CLAUDE.md의 노드 체크리스트를 따르세요.
  • 공개 패키지를 바꿀 때는 changeset을 추가하세요. Changesets를 참고하세요.
  • 데이터베이스 마이그레이션을 추가할 때는 다음 빈 번호로 supabase/migrations/NNN_description.sql이라고 이름을 붙이세요. 빈 번호는 dev와 열려 있는 모든 풀 리퀘스트에 있는 가장 큰 번호보다 1 큰 번호입니다. supabase/migrations/.sequence도 같은 번호로 설정하세요. Migration Number Guard 검사는 dev가 이미 그 번호를 쓰고 있으면 실패하며, 대신 쓸 번호를 메시지로 알려 줍니다.

테스트

워크스페이스마다 자체 Vitest 스위트가 있습니다. 리포지토리 루트에서 전부 실행하거나 워크스페이스를 하나씩 실행하세요.

npm test                       # every workspace's test script

npm -w @nodaro/shared test     # pure-logic unit tests
npm -w @nodaro/sdk test        # SDK contract tests against a mocked API
cd backend && npm test         # route and service tests
cd frontend && npm test        # component and hook tests

테스트할 대상:

  • API 라우트: 기본 경로와, 스키마에 나열된 경계 사례를 테스트합니다. Supabase와 AI 공급자는 모의 객체로 대체하세요. 단위 테스트는 실제 공급자 API를 절대 호출하지 않습니다. 대부분의 기존 테스트에 복사해 쓸 수 있는 설정이 있습니다.
  • 프런트엔드 컴포넌트: React Testing Library로 스모크 테스트를 합니다. 무거운 로직은 따로 단위 테스트할 수 있도록 훅이나 헬퍼에 두고, React Flow나 Zustand 스토어의 내부는 테스트하지 마세요.
  • 공유 패키지: 순수 함수 단위 테스트입니다. 패키지의 내보내기는 프런트엔드와 백엔드 사이에서 직렬화할 수 있어야 합니다.

CI는 tsc --noEmit, Vitest, 간단한 린트 검사를 실행합니다. 로컬에서는 실패하는데 CI에서는 통과하거나 그 반대라면, 재현 단계를 적어 이슈를 여세요.

ffmpeg 출력 검사

일반 단위 테스트는 ffmpeg의 렌더링 결과가 아니라 ffmpeg에 전달되는 인수를 검사합니다. 별도의 특성화 스위트는 ffmpeg 기반의 모든 작업으로 테스트 픽스처를 렌더링합니다. 그런 다음 디코딩한 출력에서 측정한 속성을 커밋된 기준값과 비교합니다. 비교하는 속성은 에너지, 스펙트럼, 감쇠, 길이, 프레임별 밝기입니다.

이 스위트는 npm test에서 빠져 있습니다. 측정값이 프로덕션 이미지에 고정된 정확한 ffmpeg 빌드에서만 유효하기 때문입니다. 그 이미지 안에서 실행하세요.

backend/scripts/characterize-in-image.sh check   # compare with the reference values
backend/scripts/characterize-in-image.sh bless   # rewrite the reference values, on purpose only
cd backend && npm run characterize:report -- --against ffmpeg-X.json

ffmpeg 기반 작업을 바꿨다면 풀 리퀘스트를 열기 전에 check를 실행하세요. CI도 실행합니다. 렌더링 결과를 바꾸려는 변경이라면 이미지 안에서 bless를 실행하고 새 기준값을 커밋하되, 바뀐 측정값마다 설명을 붙이세요. 기준값을 손으로 편집하지 말고, 로컬 ffmpeg 빌드로 bless하지 마세요. 스위트의 버전 검사가 이를 거부합니다.

노드나 모델 공급자 추가

노드를 추가하면 API 라우트, 프런트엔드 컴포넌트, 실행기, 여러 레지스트리 등 많은 파일을 건드리게 됩니다. 하나라도 빠뜨리면 노드가 피커 중 하나에 나타나지 않거나 실행 버튼이 아무 동작도 하지 않는 등 헷갈리는 결과가 생깁니다. CLAUDE.md의 New Node Registration(새 노드 등록) 체크리스트를 단계별로 따르세요.

기존 노드에 모델을 추가하는 일은 더 짧으며, CLAUDE.md에 전용 Provider Enum Sync(공급자 열거형 동기화) 체크리스트가 있습니다. 가장 자주 빠뜨리는 단계는 API 라우트의 스키마입니다. 스키마를 고치지 않으면 편집기가 API가 400으로 거부하는 옵션을 보여 주게 됩니다.

Changesets

npm에 공개되는 패키지는 @nodaro/shared, @nodaro/sdk, @nodaro/cli 세 개입니다. 릴리스는 Changesets를 쓰며 자동화되어 있습니다. 변경 사항이 이 중 하나를 건드리면 다음을 실행하세요.

npx changeset

패키지, 버전 올림 유형(patch, minor, major), 한 줄 요약을 선택하세요. .changeset/ 아래에 생성된 파일을 풀 리퀘스트와 함께 커밋하세요. Changeset Guard 검사는 changeset 없이 공개 패키지를 바꾼 풀 리퀘스트를 실패시킵니다. 릴리스 노트가 필요 없는 변경이면 npx changeset --empty를 쓰세요.

나머지는 모두 자동입니다. dev에서는 Version Packages 풀 리퀘스트가 대기 중인 changeset을 모읍니다. dev가 main으로 승격되면 릴리스 워크플로가 새 버전을 npm에 공개하고, 태그를 달고, GitHub 릴리스를 만들고, 독립 실행형 CLI 바이너리를 다시 빌드합니다. backend, frontend, Remotion 워크스페이스는 공개되지 않으므로 changeset이 필요 없습니다.

행동 강령

친절하고, 서로 존중하고, 선의를 전제하세요. 이 프로젝트는 CODE_OF_CONDUCT.md에 있는 Contributor Covenant 2.1을 따릅니다. 어떤 종류든 괴롭힘은 프로젝트에서 제외되는 사유가 됩니다.

  • 사람이 아니라 코드를 비판하세요.
  • 무례하지 않게 반대 의견을 내세요. “Y 때문에 여기서는 패턴 X가 더 깔끔할 것 같습니다”는 괜찮지만, “이건 별로입니다”는 안 됩니다.
  • 처음 기여하는 사람을 리뷰하는 메인테이너는 인내심을 가져 주세요.

질문할 곳

  • GitHub Discussions: 열린 질문, 아이디어, Nodaro로 만든 것을 나누는 곳입니다. 버그가 아닌 것은 Issues보다 이곳을 쓰세요.
  • GitHub Issues: 버그 신고와 기능 요청.
  • 보안 문제: GitHub의 비공개 보안 권고로 신고하세요.

프로젝트에 관해 메인테이너에게 개인적으로 이메일을 보내지 마세요. 공개된 답변은 모두에게 도움이 됩니다. 보안 신고와 이해 상충 문제는 개인적으로 연락해도 됩니다.

라이선스와 기여자 계약

리포지토리에는 네 가지 라이선스 등급이 있습니다. 대부분의 코드는 Nodaro Sustainable Use License를 따릅니다. 모든 ee 폴더 안의 코드와 이름에 .ee.가 들어간 파일은 Nodaro Enterprise License를 따릅니다. @nodaro/prompts는 FSL-1.1-Apache-2.0을, @nodaro/sdk, @nodaro/shared, @nodaro/cli는 Apache 2.0을 따릅니다. 라이선스를 참고하세요.

새 코드를 둘 곳. Apache 패키지는 공개되는 버전마다 취소할 수 없는 권리 부여가 됩니다. 새로운 프롬프트 엔지니어링, 카탈로그, 프리셋은 @nodaro/prompts나 backend/에 둡니다. @nodaro/shared에는 공개 API와 SDK 계약에 필요한 것, 즉 타입, 와이어 열거형, API 사용자와 공유하는 검증 같은 것이나, 재사용을 위해 의도적으로 공개하는 것만 추가하세요. 둘 중 어느 쪽인지 풀 리퀘스트에 적어 주세요.

기여자 계약. 기여를 제출하면 Nodaro Contributor License Agreement에 동의하는 것입니다. 개인 기여와 회사 기여 모두 같은 계약이 적용되며, 계약의 2조가 고용주의 허락을 다룹니다. 첫 풀 리퀘스트에서 cla-assistant 봇이 서명을 요청합니다. 고용주를 대신해 기여한다면 고용주의 지식 재산권 정책이 이를 허용하는지 확인하세요. 이 계약에 따라 Nodaro는 내 기여를 자사의 어떤 라이선스로든 제공할 수 있으며, Sustainable Use License와 Enterprise License 사이에서 옮기는 것도 포함됩니다.

자주 묻는 질문

풀 리퀘스트는 어느 브랜치를 대상으로 해야 하나요?

dev에서 브랜치를 만들고 dev로 풀 리퀘스트를 여세요. main에서 브랜치를 만들거나 main에 직접 커밋하지 마세요. 변경 사항은 스테이징 인스턴스에서 충분히 검증된 뒤 main에 반영됩니다.

기여자 라이선스 계약에 서명해야 하나요?

네. 기여를 제출하면 Nodaro Contributor License Agreement에 동의하는 것입니다. 첫 풀 리퀘스트에서 cla-assistant 봇이 서명을 요청하며, 개인 기여와 회사 기여 모두 같은 계약이 적용됩니다.

테스트는 어떻게 실행하나요?

리포지토리 루트에서 npm test를 실행하면 모든 워크스페이스의 Vitest 스위트가 실행됩니다. npm -w @nodaro/shared test처럼 워크스페이스 하나만 실행할 수도 있습니다. 커밋하기 전마다 npx tsc --noEmit으로 backend와 frontend의 타입을 검사하세요.

changeset은 언제 필요한가요?

변경 사항이 공개 패키지인 @nodaro/shared, @nodaro/sdk, @nodaro/cli를 건드릴 때 필요합니다. npx changeset을 실행하고 생성된 파일을 커밋하세요. 릴리스 노트가 필요 없는 변경이면 npx changeset --empty를 쓰세요.

기여에 관한 질문은 어디에서 하나요?

자유로운 질문과 아이디어는 GitHub Discussions에, 버그와 기능 요청은 GitHub Issues에 올리세요. 보안 문제는 비공개 보안 권고로 신고하세요.

최종 업데이트

목차