# תרומה לפרויקט

> תרומת קוד ל-Nodaro ב-GitHub: הכנת סביבת הפיתוח, יצירת ענף מ-dev, הרצת הבדיקות, הוספת changeset וחתימה על הסכם התורמים.

Source: https://nodaro.ai/he/docs/self-hosting/contributing

**תרומה** ל-Nodaro פירושה שליחת קוד למאגר הקוד הציבורי, [github.com/nodaroai/app.nodaro.ai](https://github.com/nodaroai/app.nodaro.ai), כ-pull request. Nodaro הוא source-available תחת הרישיון Nodaro Sustainable Use License. הדף הזה עוסק בסביבת הפיתוח, בענפים, ב-pull requests, בבדיקות ובהסכם התורמים.

כדי להריץ את Nodaro בשרת שלכם במקום זאת, התחילו מהדף [התחלה מהירה](https://nodaro.ai/docs/self-hosting/quickstart). כדי לפתח על בסיס ה-API, ראו את הדף [SDK](https://nodaro.ai/docs/developers/sdk).

## מאגר הקוד
מאגר הקוד הוא monorepo אחד של npm workspaces:

| תיקייה | מה יש בה |
| --- | --- |
| `backend/` | ה-API ב-Fastify, ה-workers של BullMQ וה-orchestrator. Node.js 22, TypeScript. |
| `frontend/` | אפליקציית Vite: העורך, מריץ האפליקציות וממשק הניהול. React 19, React Router 7, React Flow. |
| `packages/` | `@nodaro/shared`, לוגיקה טהורה שמשותפת לכל חלקי הסטאק; `@nodaro/sdk`, לקוח REST עם טיפוסים; `@nodaro/cli`; `@nodaro/prompts`, שכבת הפרומפטים; וקומפוזיציות הווידאו של Remotion. |
| `supabase/` | הסכמה של מסד הנתונים, כמיגרציות SQL שמתקדמות רק קדימה. |
| `docs/` | התיעוד שבמאגר הקוד, כולל הערות תכנון שמסבירות את הסיבות שמאחורי תכונות מרכזיות. |
| `scripts/` | כלי עזר למאגר הקוד, כגון המחולל של גרף הארכיטקטורה וכלי ביקורת. |
| `.changeset/` | העלאות גרסה ממתינות לחבילות שמתפרסמות. |

כללי הבית נמצאים בקובץ `CLAUDE.md` בתיקיית השורש של מאגר הקוד: תקני הקוד, רשימת הבדיקה להוספת ספק מודלים ורשימת הבדיקה להוספת רכיב. קראו אותו לפני pull request שהוא לא טריוויאלי. הדף [ארכיטקטורה](https://nodaro.ai/docs/self-hosting/architecture) מסביר איך החלקים משתלבים זה בזה.

## הכנת סביבת הפיתוח
צריך Node.js 22 ומעלה, עם npm.

### שכפול והתקנה
```bash
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. גלאי הפנים אף פעם לא טוען אותן, והתקנה מאוחרת יותר עם המשתנה לא מסירה אותן. הוסיפו את השורה לקובץ הפרופיל של ה-shell שלכם, כדי שכל התקנה מאוחרת יותר תדלג על ההורדה. ב-macOS, ב-Windows וב-linux/arm64 הספריות האלה אף פעם לא יורדות.

### הגדרת הסביבה
```bash
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`. צרו את הסודות:

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

מסד הנתונים הפשוט ביותר הוא פרויקט חינמי ב-supabase.com. גם מערך מקומי לגמרי עם ה-CLI של Supabase, `supabase start`, עובד, אבל הוא דורש יותר הגדרות. הרצות של תהליכים צריכות גם Redis, בכתובת `REDIS_URL`, שברירת המחדל שלה היא `redis://localhost:6379`. הקובץ `.env.example` מפרט את כל המשתנים הנתמכים, והדף [תצורה](https://nodaro.ai/docs/self-hosting/configuration) מסביר אותם.

### בניית החבילה המשותפת פעם אחת
הפרונטאנד קורא את `@nodaro/shared` מתוצרי הבנייה של החבילה, ולכן בנו אותה לפני ההפעלה הראשונה. אחר כך, סקריפט ה-dev של החבילה בונה אותה מחדש כשאתם עורכים קוד משותף.

```bash
npm -w @nodaro/shared run build
```

### הפעלת שרתי הפיתוח
בשני טרמינלים:

```bash
# 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` בקוד של סביבת הייצור.** השתמשו בדפוסי ה-logger הקיימים.
- **Conventional Commits:** `feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, `test:`, עם שורת נושא ספציפית.
- **בדיקת טיפוסים לפני כל commit**, עם `npx tsc --noEmit` גם ב-`backend/` וגם ב-`frontend/`. ה-CI חוסם pull requests שלא עוברים בדיקת טיפוסים.
- **תוספים של Fastify, לא routers של Express.** כל קובץ נתיב מייצא פונקציה אסינכרונית שמקבלת את המופע של Fastify.
- **לכל נקודת קצה של ה-API יש סכמת Zod**, בלי יוצאים מן הכלל. הסכמה מאמתת את הבקשה, וממנה גם נוצר מסמך ה-OpenAPI.
- **מצב בפרונטאנד:** React Query למצב שמגיע מהשרת, Zustand למצב הממשק ו-React Flow למצב הקנבס. אל תערבבו ביניהם.
- **אף פעם אל תשנו אובייקטים או מערכים במקום.** תמיד צרו עותקים חדשים: גם Zustand וגם React Flow מסתמכים על השוואת הפניות.

## ענפים ו-pull requests
- במאגר הקוד יש שני ענפים קבועים: `dev`, ל-staging, ו-`main`, לסביבת הייצור.
- צרו fork של מאגר הקוד, **צרו ענף מ-`dev`**, ופתחו את ה-pull request אל `dev`. אף פעם אל תיצרו ענף מ-`main` ואל תעשו אליו commit ישירות.
- תנו לענף שם לפי הסוג שלו: `feat/`, `fix/`, `refactor/`, `docs/`, `chore/` או `test/`, למשל `feat/whisper-tts-node`.
- שינויים שמוזגו רצים קודם במופע ה-staging, `next.nodaro.ai`. אחרי תקופת הרצה ניסיונית של כ-24 שעות, מתחזק מקדם את `dev` ל-`main`.

ב-pull request שלכם:

- הוסיפו קישור ל-Issue ב-GitHub שה-pull request עוסק בו.
- הוסיפו צילומי מסך או קובצי GIF לשינויים בממשק.
- כשאתם מוסיפים או משנים רכיב, עבדו לפי רשימת הבדיקה של הרכיבים ב-`CLAUDE.md`.
- כשאתם משנים חבילה שמתפרסמת, הוסיפו changeset. ראו את הסעיף [Changesets](#changesets).
- כשאתם מוסיפים מיגרציה למסד הנתונים, תנו לה את השם `supabase/migrations/NNN_description.sql` עם המספר הפנוי הבא: אחד מעל המספר הגבוה ביותר ב-`dev` ובכל pull request פתוח. הגדירו את `supabase/migrations/.sequence` לאותו מספר. הבדיקה **Migration Number Guard** נכשלת כשהענף `dev` כבר משתמש במספר שלכם, וההודעה שלה מציינת את המספר שצריך להשתמש בו במקומו.

## בדיקות
לכל workspace יש חבילת בדיקות משלו ב-Vitest. הריצו הכול מתיקיית השורש של מאגר הקוד, או workspace אחד בכל פעם:

```bash
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 ב-mocks: בדיקת יחידה אף פעם לא קוראת ל-API אמיתי של ספק. לרוב הבדיקות הקיימות יש הגדרה שאפשר להעתיק.
- **קומפוננטות בפרונטאנד** — בדיקות smoke עם React Testing Library. העבירו לוגיקה כבדה ל-hooks או לפונקציות עזר, שבהן אפשר לבדוק אותה בבדיקות יחידה בנפרד, ואל תבדקו את המימוש הפנימי של React Flow או של ה-stores של Zustand.
- **החבילה המשותפת** — בדיקות יחידה לפונקציות טהורות. כל מה שהחבילה מייצאת חייב להישאר בר־סריאליזציה בין הפרונטאנד לבקאנד.

ה-CI מריץ את `tsc --noEmit`, את Vitest ובדיקת lint קצרה. אם בדיקה נכשלת אצלכם ועוברת ב-CI, או להפך, פתחו Issue עם השלבים לשחזור הבעיה.

### בדיקות הפלט של ffmpeg
בדיקות יחידה רגילות בודקות את הארגומנטים שמועברים ל-ffmpeg, לא את מה ש-ffmpeg מרנדר. חבילת בדיקות אפיון נפרדת מרנדרת קובצי בדיקה דרך כל פעולה שמבוססת על ffmpeg. אחר כך היא משווה תכונות שנמדדו בפלט המפוענח לערכי השוואה שנשמרו ב-commit: אנרגיה, ספקטרום, דעיכה, משך ובהירות של כל פריים.

חבילת הבדיקות הזו לא נכללת ב-`npm test`: המספרים שלה תקפים רק מול אותו build בדיוק של ffmpeg שמקובע באימג׳ של סביבת הייצור. הריצו אותה בתוך האימג׳ הזה:

```bash
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` לפני שאתם פותחים את ה-pull request. ה-CI מריץ אותה גם כן. אם השינוי שלכם אמור לשנות את הפלט המרונדר, הריצו את `bless` בתוך האימג׳ ועשו commit לערכי ההשוואה החדשים, עם הסבר לכל מדד שזז. אף פעם אל תערכו ערכי השוואה ידנית, ואף פעם אל תריצו `bless` מול ffmpeg מקומי: בדיקת הגרסה של חבילת הבדיקות דוחה את זה.

## הוספת רכיב או ספק מודלים
הוספת רכיב נוגעת בקבצים רבים: נתיב API, קומפוננטה בפרונטאנד, ה-executor וכמה מרשמים. אם מפספסים אחד מהם, התוצאות מבלבלות, כגון רכיב שלא מופיע באחד מתפריטי הבחירה או כפתור **הרצה** שלא עושה כלום. עבדו לפי רשימת הבדיקה **New Node Registration** ב-`CLAUDE.md`, שלב אחר שלב.

הוספת מודל לרכיב קיים היא עבודה קצרה יותר, עם רשימת בדיקה משלה ב-`CLAUDE.md`, **Provider Enum Sync**. השלב שנשכח לרוב הוא הסכמה של נתיב ה-API: בלעדיה, העורך מציע אפשרות שה-API דוחה עם `400`.

## Changesets
שלוש חבילות מתפרסמות ב-npm: `@nodaro/shared`, `@nodaro/sdk` ו-`@nodaro/cli`. הגרסאות יוצאות עם Changesets, באופן אוטומטי. כשהשינוי שלכם נוגע באחת מהן:

```bash
npx changeset
```

בחרו את החבילות, את סוג העדכון (patch, minor או major) ותקציר בשורה אחת. עשו commit לקובץ שהפקודה כותבת תחת `.changeset/` יחד עם ה-pull request שלכם. הבדיקה **Changeset Guard** מכשילה pull requests שמשנים חבילה שמתפרסמת בלי changeset. לשינוי שלא צריך רשומה בעדכוני הגרסה, הריצו `npx changeset --empty`.

כל השאר אוטומטי. ב-`dev`, pull request בשם **Version Packages** אוסף את ה-changesets הממתינים. כש-`dev` מקודם ל-`main`, פייפליין השחרור מפרסם את הגרסאות החדשות ב-npm, מתייג אותן, יוצר את הגרסאות ב-GitHub ובונה מחדש את הקבצים הבינאריים העצמאיים של ה-CLI. ה-workspaces `backend`, `frontend` ו-Remotion אף פעם לא מתפרסמים, ולא צריכים changeset.

## קוד התנהגות
היו אדיבים, היו מכבדים והניחו כוונה טובה. הפרויקט פועל לפי Contributor Covenant 2.1, בקובץ [CODE_OF_CONDUCT.md](https://github.com/nodaroai/app.nodaro.ai/blob/main/CODE_OF_CONDUCT.md). הטרדה מכל סוג שהוא היא עילה להרחקה מהפרויקט.

- בקרו את הקוד, לא את האנשים.
- אפשר לא להסכים בלי להיות גסים: ״לדעתי דפוס X יהיה נקי יותר כאן, כי Y״ זה בסדר, ״זה גרוע״ לא.
- מתחזקים שבודקים קוד של מי שתורם בפעם הראשונה: התאזרו בסבלנות.

## איפה לשאול
- **GitHub Discussions** — שאלות פתוחות, רעיונות ודברים שבניתם עם Nodaro. העדיפו את Discussions על פני Issues לכל מה שהוא לא באג.
- **GitHub Issues** — דיווחי באגים ובקשות לתכונות.
- **בעיות אבטחה** — דווחו עליהן דרך security advisory פרטי ב-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. ראו את הדף [רישיון](https://nodaro.ai/docs/self-hosting/license).

**לאן הולך קוד חדש.** כל גרסה שמתפרסמת של חבילות ה-Apache היא הענקת זכויות בלתי חוזרת. הנדסת פרומפטים, קטלוגים וערכות חדשים שייכים ל-`@nodaro/prompts` או ל-`backend/`. הוסיפו ל-`@nodaro/shared` רק מה שה-API הציבורי והחוזה של ה-SDK צריכים, כגון טיפוסים, ערכי enum שעוברים ב-API ואימות שמשותף עם משתמשי ה-API, או מה שאתם מפרסמים בכוונה לשימוש חוזר. ציינו ב-pull request לאיזה מהשניים הקוד שייך.

**הסכם התורמים.** כשאתם שולחים תרומה, אתם מסכימים להסכם [Nodaro Contributor License Agreement](https://github.com/nodaroai/app.nodaro.ai/blob/main/CLA.md). אותו הסכם חל על תרומות של יחידים ושל חברות: סעיף 2 שלו עוסק בהרשאה מהמעסיק שלכם. הבוט cla-assistant מבקש מכם לחתום עליו ב-pull request הראשון שלכם. אם אתם תורמים בשם מעסיק, ודאו שמדיניות הקניין הרוחני שלו מתירה זאת. ההסכם מאפשר ל-Nodaro לתת רישיון לתרומה שלכם תחת כל אחד מהרישיונות שלו, כולל העברה שלה בין הרישיון Sustainable Use License לרישיון Enterprise License.

## שאלות נפוצות

### לאיזה ענף צריך לפתוח את ה-pull request?

צרו ענף מ-dev ופתחו את ה-pull request אל dev. אף פעם אל תיצרו ענף מ-main ואל תעשו אליו commit ישירות. שינויים מגיעים ל-main אחרי תקופת הרצה ניסיונית במופע ה-staging.

### האם צריך לחתום על הסכם רישיון לתורמים?

כן. כשאתם שולחים תרומה, אתם מסכימים להסכם Nodaro Contributor License Agreement. הבוט cla-assistant מבקש מכם לחתום עליו ב-pull request הראשון שלכם, ואותו הסכם חל על תרומות של יחידים ושל חברות.

### איך מריצים את הבדיקות?

כדי להריץ את חבילות הבדיקות של Vitest בכל ה-workspaces, הריצו npm test מתיקיית השורש של מאגר הקוד. אפשר גם להריץ workspace אחד, למשל npm -w @nodaro/shared test. לפני כל commit, הריצו בדיקת טיפוסים בבקאנד ובפרונטאנד עם npx tsc --noEmit.

### מתי צריך changeset?

צריך changeset כשהשינוי שלכם נוגע בחבילה שמתפרסמת: ‎@nodaro/shared, ‎@nodaro/sdk או ‎@nodaro/cli. הריצו npx changeset ועשו commit לקובץ שהפקודה כותבת. כשהשינוי לא צריך רשומה בעדכוני הגרסה, הריצו npx changeset --empty.

### איפה שואלים שאלות על תרומה לפרויקט?

שאלות פתוחות ורעיונות מעלים ב-GitHub Discussions, ועל באגים ובקשות לתכונות מדווחים ב-GitHub Issues. על בעיות אבטחה מדווחים דרך security advisory פרטי.
