# Contributing to OmniRoute (Ελληνικά) 🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇦🇿 [az](../az/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇧🇩 [bn](../bn/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇪🇪 [et](../et/CONTRIBUTING.md) · 🇮🇷 [fa](../fa/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇮🇪 [ga](../ga/CONTRIBUTING.md) · 🇮🇳 [gu](../gu/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇮🇳 [hi](../hi/CONTRIBUTING.md) · 🇭🇷 [hr](../hr/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇱🇹 [lt](../lt/CONTRIBUTING.md) · 🇱🇻 [lv](../lv/CONTRIBUTING.md) · 🇮🇳 [mr](../mr/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇲🇹 [mt](../mt/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇸🇮 [sl](../sl/CONTRIBUTING.md) · 🇷🇸 [sr](../sr/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇰🇪 [sw](../sw/CONTRIBUTING.md) · 🇮🇳 [ta](../ta/CONTRIBUTING.md) · 🇮🇳 [te](../te/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇹🇷 [tr](../tr/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇵🇰 [ur](../ur/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇹🇼 [zh-TW](../zh-TW/CONTRIBUTING.md) --- Σας ευχαριστούμε για το ενδιαφέρον σας να συνεισφέρετε! Αυτός ο οδηγός καλύπτει όλα όσα χρειάζεστε για να ξεκινήσετε. Για την επίσημη ροή εργασίας ανά αλλαγή, ξεκινήστε με το [Contribution Golden Path](docs/ops/CONTRIBUTION_GOLDEN_PATH.md). Αντιστοιχίζει αλλαγές σε provider, routing, UI/UX, i18n, CLI, βάση δεδομένων και build/deploy στα συμβόλαιά τους, εστιασμένα tests, κάλυψη CI και βήματα συμφωνίας. --- ## Ρύθμιση Περιβάλλοντος Ανάπτυξης ### Προαπαιτούμενα - **Node.js** `>=22.22.3 <23`, ή `>=24.0.0 <27` (συνιστάται: 24 LTS) - **npm** 10+ > **Χρήστες npm v11+ (Node 24+):** Μετά το `npm install`, επαληθεύστε ότι τα native modules εγκαταστάθηκαν: > `node -e "require('better-sqlite3')"`. Αν αποτύχει με `MODULE_NOT_FOUND`, > εκτελέστε `npm approve-scripts better-sqlite3 && npm install`. Δείτε > [Troubleshooting](docs/guides/TROUBLESHOOTING.md#npm-v11-better-sqlite3-not-installed-cannot-find-module). - **Git** ### Κλωνοποίηση & Εγκατάσταση ```bash git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute npm install ``` ### Μεταβλητές Περιβάλλοντος ```bash # Δημιουργήστε το .env σας από το πρότυπο cp .env.example .env # Δημιουργήστε τα απαιτούμενα secrets echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env ``` Βασικές μεταβλητές για ανάπτυξη: | Μεταβλητή | Προεπιλογή Ανάπτυξης | Περιγραφή | | ---------------------- | ------------------------ | --------------------------------- | | `PORT` | `20128` | Θύρα διακομιστή | | `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Βασικό URL για το frontend | | `JWT_SECRET` | (δημιουργήστε παραπάνω) | Secret υπογραφής JWT | | `INITIAL_PASSWORD` | `CHANGEME` | Κωδικός πρόσβασης πρώτης σύνδεσης | | `APP_LOG_LEVEL` | `info` | Επίπεδο λεπτομέρειας καταγραφής | ### Ρυθμίσεις Dashboard Το dashboard παρέχει εναλλάκτες UI για λειτουργίες που μπορούν επίσης να ρυθμιστούν μέσω μεταβλητών περιβάλλοντος: | Τοποθεσία Ρύθμισης | Εναλλάκτης | Περιγραφή | | ----------------------------- | ----------------- | ---------------------------------------------------- | | Ρυθμίσεις → Για προχωρημένους | Λειτουργία Debug | Ενεργοποίηση αρχείων καταγραφής αιτημάτων debug (UI) | | Ρυθμίσεις → Γενικά | Ορατότητα Sidebar | Εμφάνιση/απόκρυψη τμημάτων sidebar | Αυτές οι ρυθμίσεις αποθηκεύονται στη βάση δεδομένων και διατηρούνται μετά από επανεκκινήσεις, παρακάμπτοντας τις προεπιλογές μεταβλητών περιβάλλοντος όταν έχουν οριστεί. ### Εκτέλεση Τοπικά ```bash # Λειτουργία ανάπτυξης (hot reload) npm run dev # Build παραγωγής npm run build # next build → .build/next/ μετά assembleStandalone → dist/ npm run start # Γρήγορη μεταγλώττιση μόνο backend/API για αλλαγές συνεισφερόντων npm run build:contributor # Build έκδοσης (καθαρό rebuild + sentinel HEAD — απαιτείται για deploy) npm run build:release # rm -rf .build dist && build + γράφει dist/BUILD_SHA # Συνηθισμένη ρύθμιση θύρας PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev ``` Το contributor build εκτελεί επικύρωση μόνο μεταγλώττισης: δεν συναρμολογεί την αυτόνομη διανομή ούτε δημιουργεί προαιρετικά native assets συσκευασίας. Χρησιμοποιήστε το κανονικό build παραγωγής όταν χρειάζεται να επικυρώσετε το παραδοτέο πακέτο. ### Διάταξη Εξόδου Build | Κατάλογος | Περιεχόμενα | Παρακολουθείται | | --------- | ------------------------------------------------------------------------ | --------------- | | `src/` | Πηγαίος κώδικας εφαρμογής (TypeScript / TSX) | Ναι | | `.build/` | Ενδιάμεσα — έξοδος `next build` (gitignored, `distDir = .build/next`) | Όχι | | `dist/` | Παραδοτέο πακέτο — συναρμολογείται από `assembleStandalone` (gitignored) | Όχι | Η διοχέτευση build είναι ενιαία: ``` npm run build └─ next build → .build/next/standalone (έξοδος Next.js) └─ assembleStandalone() (αντιγράφει standalone + static + public + native assets) └─ έξοδος: dist/ (server.js, .next/static/, public/, node_modules/) ``` Το `npm run build:release` επιπλέον καθαρίζει και τους δύο καταλόγους πρώτα και γράφει `dist/BUILD_SHA` (= `git rev-parse --short HEAD`) ως sentinel ακεραιότητας deploy. Το `npm run build:contributor` χρησιμοποιεί το προφίλ build μόνο backend. Δημιουργεί προσωρινά stubs για αρχεία UI του dashboard κατά τη διάρκεια του build, διατηρεί τους χειριστές διαδρομών API και επαναφέρει τα αρχικά αρχεία μετά το build. Χρησιμοποιήστε `npm run build` για αλλαγές που επηρεάζουν το UI του dashboard ή για πλήρη επικύρωση έκδοσης· το προφίλ contributor δεν αντικαθιστά το build έκδοσης. > **Σημείωση deploy σε VPS:** ο απομακρυσμένος κατάλογος εικόνων `/usr/lib/node_modules/omniroute/app/` > παραμένει αμετάβλητος. Τα deploy skills κάνουν rsync τα περιεχόμενα του `dist/` σε αυτόν. > Μόνο η διαδρομή εξόδου build εντός του repo άλλαξε (`app/` → `dist/`). Προεπιλεγμένα URLs: - **Dashboard**: `http://localhost:20128/dashboard` - **API**: `http://localhost:20128/v1` --- ## Ροή Εργασίας Git > ⚠️ **ΠΟΤΕ μην κάνετε commit απευθείας στο `main`.** Χρησιμοποιείτε πάντα feature branches. > > **Βάση PR:** στοχεύστε τον ενεργό κλάδο `release/vX.Y.Z` (όχι το `main`). Δείτε > [`docs/ops/BRANCHING_MODEL.md`](docs/ops/BRANCHING_MODEL.md) για το μοντέλο release-per-branch + tag-at-ship. ```bash # Δημιουργία κλάδου από την ενεργή κορυφή release (παράδειγμα: release/v3.8.49) git fetch origin git checkout -b feat/your-feature-name origin/release/v3.8.49 # ... πραγματοποιήστε αλλαγές ... git commit -m "feat: describe your change" git push -u origin feat/your-feature-name # Ανοίξτε ένα Pull Request με base = release/v3.8.49 ``` ### Ονοματολογία Κλάδων | Πρόθεμα | Σκοπός | | ----------- | ------------------------- | | `feat/` | Νέες λειτουργίες | | `fix/` | Διορθώσεις σφαλμάτων | | `refactor/` | Αναδόμηση κώδικα | | `docs/` | Αλλαγές τεκμηρίωσης | | `test/` | Προσθήκη/διόρθωση δοκιμών | | `chore/` | Εργαλεία, CI, εξαρτήσεις | ### Μηνύματα Commit Ακολουθήστε τα [Conventional Commits](https://www.conventionalcommits.org/): ``` feat: add circuit breaker for provider calls fix: resolve JWT secret validation edge case docs: update SECURITY.md with PII protection test: add observability unit tests refactor(db): consolidate rate limit tables ``` Εύρη (v3.8): `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`, `cloud-agent`, `guardrails`, `compression`, `auto-combo`, `resilience`, `providers`, `executors`, `translator`, `domain`, `authz`. --- ## Εκτέλεση Δοκιμών ```bash # Όλες οι δοκιμές (unit + vitest + ecosystem + e2e) npm run test:all # Μεμονωμένο αρχείο δοκιμής (native test runner του Node.js — οι περισσότερες δοκιμές το χρησιμοποιούν) node --import tsx/esm --test tests/unit/your-file.test.ts # Μόνο οι unit δοκιμές που επηρεάζονται από την αλλαγή σας (ίδιος επιλογέας TIA με την πύλη CI, #8084) npm run test:scoped # αλλαγές στο τελευταίο commit (ή στο working tree) npm run test:scoped:staged # μόνο staged αλλαγές — ταιριάζει καλά με εκτέλεση pre-commit npm run test:scoped:full # ανακατασκευή του χάρτη import-graph πρώτα (μετά από προσθήκη/μετακίνηση αρχείων) # Έξοδος 1 + "run the full suite" σημαίνει ότι ένα hub αρχείο (tsconfig, package.json, …) ή μια # μη-αντιστοιχισμένη πηγή άλλαξε — ο επιλογέας αποτυγχάνει με ασφάλεια, ποτέ δεν παραλείπει σιωπηλά. # Vitest (MCP server, autoCombo, cache) npm run test:vitest # E2E δοκιμές (απαιτεί Playwright) npm run test:e2e # E2E δοκιμές protocol clients (MCP transports, A2A) npm run test:protocols:e2e # Δοκιμές συμβατότητας ecosystem npm run test:ecosystem # Πύλη κάλυψης: 60% statements/lines/functions/branches npm run test:coverage npm run coverage:report # Έλεγχος lint + μορφοποίησης npm run lint npm run check # Δοκιμή καπνού combo με πραγματικά upstream (απαιτεί πρόσβαση VPS + πραγματικές χρεώσεις παρόχου) # Χτυπά ΠΡΑΓΜΑΤΙΚΟΥΣ παρόχους — κοστίζει λίγο. ΠΟΤΕ δεν εκτελείται στο CI. Παραλείπεται καθαρά χωρίς την πύλη. # Απαιτεί: πρόσβαση ssh root@192.168.0.15 (φορτώνει ένα read-only στιγμιότυπο DB από το VPS). RUN_COMBO_LIVE=1 npm run test:combo:live # Phase-3 VPS live smoke — απλά Node ESM scripts, χτυπούν απευθείας τον live server .15. # Απαιτεί: πρόσβαση ssh root@192.168.0.15 (combos δημιουργούνται/διαγράφονται μέσω SSH sqlite). # Χτυπά ΠΡΑΓΜΑΤΙΚΟΥΣ παρόχους (μικρό κόστος). Δημιουργεί/διαγράφει μόνο combos __live_test__*. ΠΟΤΕ δεν εκτελείται στο CI. # REQUIRE_API_KEY=false στο .15, οπότε δεν χρειάζεται API key, αλλά τιμά τα COMBO_LIVE_BASE_URL / COMBO_LIVE_API_KEY αν έχουν οριστεί. npm run test:combo:live:vps # 7 HTTP σενάρια (priority/round-robin/weighted/cost/fusion/auto + health) npm run test:combo:live:vps:failover # προσθέτει ένα πραγματικό σενάριο cross-provider failover (συνολικά 8) ``` Σημειώσεις κάλυψης: - Το `npm run test:coverage` μετρά κάλυψη πηγαίου κώδικα για την κύρια σουίτα unit δοκιμών, εξαιρεί τα `tests/**` και συμπεριλαμβάνει το `open-sse/**` - Τα Pull Requests πρέπει να διατηρούν την πύλη κάλυψης στο **60%+** statements/lines/functions/branches - Εάν ένα PR αλλάζει κώδικα παραγωγής στα `src/`, `open-sse/`, `electron/` ή `bin/`, πρέπει να προσθέσει ή να ενημερώσει αυτοματοποιημένες δοκιμές στο ίδιο PR - Το `npm run coverage:report` εκτυπώνει την αναλυτική αναφορά ανά αρχείο από την τελευταία εκτέλεση κάλυψης - Το `npm run test:coverage:legacy` διατηρεί την παλαιότερη μέτρηση για ιστορική σύγκριση - Δείτε `docs/ops/COVERAGE_PLAN.md` για τον οδικό χάρτη βελτίωσης κάλυψης σε φάσεις ### Απαιτήσεις Pull Request Πριν ανοίξετε ένα PR, χρησιμοποιήστε το [Contribution Golden Path](docs/ops/CONTRIBUTION_GOLDEN_PATH.md) για να εκτελέσετε τον εστιασμένο βρόχο για ό,τι αλλάξατε. Η πλήρης σουίτα unit (4 CI shards), το Vitest, η πύλη κάλυψης **60%+** και το build παραγωγής είναι ευθύνη του CI — η εκτέλεσή τους τοπικά δεν προσφέρει επιπλέον πληροφορία που δεν θα δώσουν ήδη οι έλεγχοι PR, και σε μικρότερα μηχανήματα μπορεί να κορεστεί ο host (#8084): - Εκτελέστε τα αρχεία δοκιμών που καλύπτουν την αλλαγή σας: `node --import tsx/esm --test tests/unit/.test.ts` - Εκτελέστε `npm run lint` - Συμπεριλάβετε ή ενημερώστε αυτοματοποιημένες δοκιμές στο ίδιο PR κάθε φορά που αλλάζει κώδικας παραγωγής - Συμπεριλάβετε τα αλλαγμένα ή προστεθέντα αρχεία δοκιμών στην περιγραφή του PR όταν αλλάζει κώδικας παραγωγής - Ελέγξτε το αποτέλεσμα SonarQube στο PR όταν τα project secrets είναι διαμορφωμένα στο CI Τρέχουσα κατάσταση δοκιμών: **122 αρχεία unit δοκιμών** που καλύπτουν: - Μεταφραστές παρόχων και μετατροπή μορφών - Περιορισμός ρυθμού, circuit breaker και ανθεκτικότητα - Σημασιολογική cache, idempotency, παρακολούθηση προόδου - Λειτουργίες βάσης δεδομένων και σχήμα (21 ενότητες DB) - Ροές OAuth και πιστοποίηση ταυτότητας - Επικύρωση API endpoint (Zod v4) - Εργαλεία MCP server και επιβολή εύρους - Συστήματα Memory και Skills --- ## Στυλ Κώδικα - **ESLint** — Εκτελέστε `npm run lint` πριν από κάθε commit - **Prettier** — Αυτόματη μορφοποίηση μέσω `lint-staged` κατά το commit (2 κενά, ελληνικά ερωτηματικά, διπλά εισαγωγικά, πλάτος 100 χαρακτήρων, κόμματα τύπου es5 στο τέλος) - **TypeScript** — Όλος ο κώδικας στο `src/` χρησιμοποιεί `.ts`/`.tsx`· το `open-sse/` χρησιμοποιεί `.ts`/`.js`· τεκμηρίωση με TSDoc (`@param`, `@returns`, `@throws`) - **Απαγόρευση `eval()`** — Το ESLint επιβάλλει `no-eval`, `no-implied-eval`, `no-new-func` - **Επικύρωση με Zod** — Χρησιμοποιείτε σχήματα Zod v4 για όλη την επικύρωση εισόδου API - **Ονοματολογία**: Αρχεία = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE ### Διαχείριση σφαλμάτων / κενά μπλοκ catch Μην αφήνετε ποτέ ένα `catch` αναιτιολόγητο. Κατατάξτε το σε μία από τις δύο κατηγορίες (εφαρμόζει τον αυστηρό κανόνα «ποτέ μην αποκρύπτετε σιωπηλά σφάλματα σε SSE streams»): - **Σκόπιμο (δική μας προσπάθεια καλύτερης δυνατής εκκαθάρισης/τηλεμετρίας)** — μια αποτυχία εδώ είναι αναμενόμενη και ακίνδυνη· προσθέστε ένα σχόλιο μιας γραμμής με αιτιολόγηση, χωρίς logging (το logging σε κάθε αίτημα είναι ο θόρυβος που αποφεύγει αυτή η σύμβαση). ```ts } catch {} // το κλείσιμο ενός ήδη κλειστού controller μετά την αποσύνδεση του client είναι αναμενόμενο ``` - **Πρέπει να καταγραφεί (εξωτερικός κώδικας/κώδικας από τον καλούντα, ή η αποκάλυψη αλλάζει τη ροή ελέγχου)** — διατηρήστε το catch (μην αφήνετε ποτέ να σπάσει το stream) αλλά εκπέμψτε ένα εξατομικευμένο `console.debug`/`warn` ώστε η αποτυχία να είναι ανιχνεύσιμη. ```ts } catch (e) { console.debug("[STREAM] onFailure callback error:", e); } ``` Δείτε τα `open-sse/utils/stream.ts` και `open-sse/utils/streamHandler.ts` για πρακτικά παραδείγματα. --- ## Δομή Έργου ``` src/ # TypeScript (.ts / .tsx) ├── app/ # Next.js 16 App Router │ ├── (dashboard)/ # Σελίδες Dashboard (23 ενότητες) │ ├── api/ # Διαδρομές API (51 κατάλογοι) │ └── login/ # Σελίδες πιστοποίησης (.tsx) ├── domain/ # Μηχανισμός πολιτικής (policyEngine, comboResolver, costRules, κ.λπ.) ├── lib/ # Βασική επιχειρησιακή λογική (.ts) │ ├── a2a/ # Διακομιστής πρωτοκόλλου Agent-to-Agent v0.3 │ ├── acp/ # Μητρώο Agent Communication Protocol │ ├── compliance/ # Μηχανισμός πολιτικής συμμόρφωσης │ ├── db/ # Ενότητες τομέα SQLite + 130 μεταναστεύσεις │ ├── memory/ # Μόνιμη μνήμη συνομιλιών │ ├── oauth/ # Πάροχοι OAuth, υπηρεσίες και βοηθητικά εργαλεία │ ├── skills/ # Επεκτάσιμο πλαίσιο δεξιοτήτων │ ├── usage/ # Παρακολούθηση χρήσης και υπολογισμός κόστους │ └── localDb.ts # Μόνο επίπεδο επανεξαγωγής — μην προσθέτετε ποτέ λογική εδώ ├── middleware/ # Middleware αιτημάτων (promptInjectionGuard) ├── mitm/ # MITM proxy (πιστοποιητικό, DNS, δρομολόγηση στόχου) ├── shared/ │ ├── components/ # React components (.tsx) │ ├── constants/ # Ορισμοί παρόχων (329), πεδία MCP, 19 στρατηγικές δρομολόγησης │ ├── utils/ # Circuit breaker, sanitizer, βοηθητικά πιστοποίησης │ └── validation/ # Σχήματα Zod v4 └── sse/ # Αγωγός proxy SSE open-sse/ # Χώρος εργασίας @omniroute/open-sse ├── executors/ # 89 ενότητες υλοποίησης executor ├── handlers/ # 11 χειριστές αιτημάτων (chat, responses, embeddings, images, κ.λπ.) ├── mcp-server/ # Διακομιστής MCP (110 μοναδικά εργαλεία, 3 μεταφορές, 33 πεδία) ├── services/ # 178 υπηρεσίες ανώτατου επιπέδου (combo, autoCombo, rateLimitManager, κ.λπ.) ├── translator/ # Μεταφραστές μορφής (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama) ├── transformer/ # Μετασχηματιστής Responses API └── utils/ # 22 ενότητες βοηθητικών εργαλείων (stream, TLS, proxy, logging) electron/ # Εφαρμογή desktop Electron (cross-platform) tests/ ├── unit/ # Εκτελεστής δοκιμών Node.js (1.574 αρχεία δοκιμών) ├── integration/ # Δοκιμές ενσωμάτωσης ├── e2e/ # Δοκιμές Playwright ├── security/ # Δοκιμές ασφαλείας ├── translator/ # Δοκιμές ειδικά για τον translator └── load/ # Δοκιμές φόρτου docs/ ├── adr/ # Αρχεία Αποφάσεων Αρχιτεκτονικής ├── architecture/ # Αρχιτεκτονική συστήματος & ανθεκτικότητα ├── comparison/ # OmniRoute έναντι εναλλακτικών ├── compression/ # Οδηγοί & κανόνες συμπίεσης ├── dev/ # Οδηγοί ανάπτυξης ├── diagrams/ # Διαγράμματα αρχιτεκτονικής ├── frameworks/ # MCP, A2A, OpenCode, Memory, Skills ├── guides/ # Οδηγός χρήστη, Docker, εγκατάσταση, αντιμετώπιση προβλημάτων ├── i18n/ # Διεθνοποιημένες μεταφράσεις README ├── marketing/ # Υλικό μάρκετινγκ ├── ops/ # Ανάπτυξη, proxy, κάλυψη, εκδόσεις ├── providers/ # Τεκμηρίωση ανά πάροχο ├── reference/ # Αναφορά API, μεταβλητές περιβάλλοντος, εργαλεία CLI, δωρεάν επίπεδα ├── releases/ # Σημειώσεις έκδοσης ├── routing/ # Μηχανισμός auto-combo, αναπαραγωγή συλλογισμού ├── screenshots/ # Στιγμιότυπα οθόνης Dashboard ├── security/ # Προστατευτικά μέτρα, συμμόρφωση, stealth, tokens └── specs/ # Προδιαγραφές σχεδιασμού ``` --- ## Προσθήκη Νέου Παρόχου ### Βήμα 1: Καταχώριση Σταθερών Παρόχου Προσθέστε στο `src/shared/constants/providers.ts` — επικυρώνεται με Zod κατά τη φόρτωση του module. ### Βήμα 2: Προσθήκη Executor (εάν απαιτείται προσαρμοσμένη λογική) Δημιουργήστε executor στο `open-sse/executors/your-provider.ts` επεκτείνοντας τον βασικό executor. ### Βήμα 3: Προσθήκη Translator (εάν η μορφή δεν είναι OpenAI) Δημιουργήστε translators αιτήματος/απόκρισης στο `open-sse/translator/`. ### Βήμα 4: Προσθήκη Διαμόρφωσης OAuth (εάν βασίζεται σε OAuth) Προσθέστε διαπιστευτήρια OAuth στο `src/lib/oauth/constants/oauth.ts` και την υπηρεσία στο `src/lib/oauth/services/`. Εάν ο upstream πάροχος διανέμει δημόσιο OAuth `client_id`/secret ή Firebase Web API key μέσα στο δημόσιο CLI / bundle του προγράμματος περιήγησής του, **μην** το ενσωματώνετε ως string literal. Χρησιμοποιήστε το `resolvePublicCred()` από το `open-sse/utils/publicCreds.ts` και προσθέστε μια καταχώριση masked byte στο `EMBEDDED_DEFAULTS`. Η πλήρης υποχρεωτική ροή εργασίας τεκμηριώνεται στο [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md). Μέσα σε handlers/executors, τα μηνύματα σφάλματος που φτάνουν στον client πρέπει να περνούν μέσα από τα `buildErrorBody()` / `sanitizeErrorMessage()` από το `open-sse/utils/error.ts` — ποτέ μην τοποθετείτε raw `err.stack` ή `err.message` στο σώμα ενός Response. Δείτε [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md). ### Βήμα 5: Καταχώριση Μοντέλων Προσθέστε ορισμούς μοντέλων στο `open-sse/config/providerRegistry.ts`. ### Βήμα 6: Προσθήκη Tests Γράψτε unit tests στο `tests/unit/` που καλύπτουν τουλάχιστον: - Καταχώριση παρόχου - Μετάφραση αιτήματος/απόκρισης - Διαχείριση σφαλμάτων --- ## Λίστα Ελέγχου Pull Request - [ ] Τα tests περνούν (`npm test`) - [ ] Το linting περνά (`npm run lint`) - [ ] Το build ολοκληρώνεται επιτυχώς (`npm run build`) - [ ] Προστέθηκαν TypeScript types για νέες δημόσιες συναρτήσεις και interfaces - [ ] Δεν υπάρχουν hardcoded secrets ή fallback τιμές - [ ] Τα δημόσια upstream διαπιστευτήρια ενσωματώνονται μέσω `resolvePublicCred()` (δείτε [`docs/security/PUBLIC_CREDS.md`](./docs/security/PUBLIC_CREDS.md)), ποτέ ως literals - [ ] Οι αποκρίσεις σφαλμάτων δρομολογούνται μέσω `buildErrorBody()` / `sanitizeErrorMessage()` — χωρίς raw stack traces στα σώματα απόκρισης (δείτε [`docs/security/ERROR_SANITIZATION.md`](./docs/security/ERROR_SANITIZATION.md)) - [ ] Οι εντολές shell (`exec` / `spawn`) μεταβιβάζουν τιμές runtime μέσω `env`, όχι μέσω string interpolation - [ ] Όλες οι εισόδοι επικυρώνονται με Zod schemas - [ ] Προστέθηκε **fragment** Changelog στο `changelog.d/{features|fixes|maintenance}/-.md` για αλλαγές που επηρεάζουν τον χρήστη (δείτε [`changelog.d/README.md`](./changelog.d/README.md)) — **μην** επεξεργάζεστε απευθείας το `CHANGELOG.md`· τα fragments συγκεντρώνονται κατά την έκδοση και δεν δημιουργούν ποτέ συγκρούσεις μεταξύ PRs - [ ] Η τεκμηρίωση ενημερώθηκε (εάν απαιτείται) - [ ] Δεν ανοίχτηκαν νέες ειδοποιήσεις CodeQL / Secret-Scanning, ή κάθε μία απορρίφθηκε με τεχνική αιτιολόγηση που παραπέμπει στο σχετικό έγγραφο `docs/security/` - [ ] Τα routes που εκκινούν child processes (`/api/mcp/`, `/api/cli-tools/runtime/`) ταξινομούνται ως `isLocalOnlyPath()` στο `src/server/authz/routeGuard.ts` — δείτε [Κανόνα #15](docs/security/ROUTE_GUARD_TIERS.md) - [ ] Δεν υπάρχουν trailers `Co-Authored-By` στα μηνύματα commit — τα commits πρέπει να εμφανίζονται αποκλειστικά υπό την Git ταυτότητα του ιδιοκτήτη του αποθετηρίου (Κανόνας #16) ## Κυκλοφορία Εκδόσεων Οι εκδόσεις διαχειρίζονται μέσω της ροής εργασιών `/generate-release`. Όταν δημιουργείται μια νέα GitHub Release, το πακέτο **δημοσιεύεται αυτόματα στο npm** μέσω του GitHub Actions. Για αναπτύξεις σε VPS, χρησιμοποιήστε `npm run build:release` (όχι `npm run build`) — εκτελεί μια καθαρή επαναδόμηση, συναρμολογεί το bundle στον φάκελο `dist/`, και γράφει το αρχείο σηματοδότη `dist/BUILD_SHA`. Στη συνέχεια χρησιμοποιήστε τις δεξιότητες `/deploy-vps-*-cc` που συγχρονίζουν τον φάκελο `dist/` με τον απομακρυσμένο κατάλογο `app/` μέσω rsync. --- ## Λήψη Βοήθειας - **Αρχιτεκτονική**: Δείτε [`docs/architecture/ARCHITECTURE.md`](docs/architecture/ARCHITECTURE.md) - **Αναφορά API**: Δείτε [`docs/reference/API_REFERENCE.md`](docs/reference/API_REFERENCE.md) - **Έγγραφα ασφαλείας**: [`docs/security/CLI_TOKEN.md`](docs/security/CLI_TOKEN.md), [`docs/security/ROUTE_GUARD_TIERS.md`](docs/security/ROUTE_GUARD_TIERS.md), [`docs/security/ERROR_SANITIZATION.md`](docs/security/ERROR_SANITIZATION.md), [`docs/security/PUBLIC_CREDS.md`](docs/security/PUBLIC_CREDS.md) - **Έγγραφα λειτουργίας**: [`docs/ops/SQLITE_RUNTIME.md`](docs/ops/SQLITE_RUNTIME.md) - **Ζητήματα**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) - **ADRs**: Δείτε τον φάκελο `docs/adr/` για αρχεία αποφάσεων αρχιτεκτονικής