* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
24 KiB
Contributing to OmniRoute (Bahasa Indonesia)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Terima kasih atas minat Anda untuk berkontribusi! Panduan ini mencakup semua hal yang Anda perlukan untuk memulai.
Untuk alur kerja resmi bagi setiap perubahan, mulailah dengan Alur Utama Kontribusi. Panduan tersebut memetakan perubahan penyedia, perutean, UI/UX, i18n, CLI, basis data, serta build/deploy ke kontrak, pengujian terfokus, cakupan CI, dan langkah-langkah rekonsiliasinya.
Penyiapan Pengembangan
Prasyarat
- Node.js
>=22.22.3 <23, atau>=24.0.0 <27(disarankan: 24 LTS) - npm 10+
Pengguna npm v11+ (Node 24+): Setelah
npm install, pastikan modul native telah terinstal:node -e "require('better-sqlite3')". Jika gagal denganMODULE_NOT_FOUND, jalankannpm approve-scripts better-sqlite3 && npm install. Lihat Pemecahan Masalah.
- Git
Kloning & Instalasi
git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
npm install
Variabel Lingkungan
# Buat .env Anda dari templat
cp .env.example .env
# Buat secret yang diperlukan
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
Variabel utama untuk pengembangan:
| Variabel | Nilai Default Pengembangan | Deskripsi |
|---|---|---|
PORT |
20128 |
Port server |
NEXT_PUBLIC_BASE_URL |
http://localhost:20128 |
URL dasar untuk frontend |
JWT_SECRET |
(buat seperti di atas) | Secret penandatanganan JWT |
INITIAL_PASSWORD |
CHANGEME |
Kata sandi login pertama |
APP_LOG_LEVEL |
info |
Tingkat verbositas log |
Pengaturan Dasbor
Dasbor menyediakan tombol UI untuk fitur yang juga dapat dikonfigurasi melalui variabel lingkungan:
| Lokasi Pengaturan | Tombol Visibilitas | Deskripsi |
|---|---|---|
| Settings → Advanced | Mode Debug | Aktifkan log permintaan debug (UI) |
| Settings → General | Visibilitas Bilah Sisi | Tampilkan/sembunyikan bagian bilah sisi |
Pengaturan ini disimpan dalam basis data dan tetap tersedia setelah aplikasi dimulai ulang, serta menggantikan nilai default variabel lingkungan jika ditetapkan.
Menjalankan Secara Lokal
# Mode pengembangan (muat ulang otomatis)
npm run dev
# Build produksi
npm run build # next build → .build/next/ lalu assembleStandalone → dist/
npm run start
# Kompilasi cepat khusus backend/API untuk perubahan kontributor
npm run build:contributor
# Build rilis (build ulang bersih + sentinel HEAD — diwajibkan untuk deployment)
npm run build:release # rm -rf .build dist && build + menulis dist/BUILD_SHA
# Konfigurasi port umum
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
Build kontributor melakukan validasi kompilasi saja: build ini tidak merakit distribusi mandiri atau membuat aset pemaketan native opsional. Gunakan build produksi reguler saat Anda perlu memvalidasi bundel yang dapat didistribusikan.
Tata Letak Output Build
| Direktori | Isi | Dilacak |
|---|---|---|
src/ |
Sumber aplikasi (TypeScript / TSX) | Ya |
.build/ |
Berkas perantara — output next build (diabaikan git, distDir = .build/next) |
Tidak |
dist/ |
Bundel siap didistribusikan — dirakit oleh assembleStandalone (diabaikan git) |
Tidak |
Pipeline build dilakukan dalam satu tahap:
npm run build
└─ next build → .build/next/standalone (output Next.js)
└─ assembleStandalone() (menyalin standalone + static + public + aset native)
└─ output: dist/ (server.js, .next/static/, public/, node_modules/)
npm run build:release juga membersihkan kedua direktori terlebih dahulu dan menulis
dist/BUILD_SHA (= git rev-parse --short HEAD) sebagai sentinel integritas deployment.
npm run build:contributor menggunakan profil build khusus backend. Build ini untuk sementara mengganti
file UI dasbor dengan stub selama proses build, mempertahankan handler rute API, dan memulihkan file asli
setelah build selesai. Gunakan npm run build untuk perubahan yang memengaruhi UI dasbor atau untuk
validasi rilis lengkap; profil kontributor bukan pengganti build rilis.
Catatan deployment VPS: direktori image jarak jauh
/usr/lib/node_modules/omniroute/app/tidak berubah. Skill deployment melakukan rsync terhadap isidist/ke direktori tersebut. Hanya jalur output build dalam repositori yang berpindah (app/→dist/).
URL default:
- Dasbor:
http://localhost:20128/dashboard - API:
http://localhost:20128/v1
Alur Kerja Git
⚠️ JANGAN PERNAH melakukan commit langsung ke
main. Selalu gunakan branch fitur.Basis PR: targetkan branch
release/vX.Y.Zyang aktif (bukanmain). Lihatdocs/ops/BRANCHING_MODEL.mduntuk model satu branch per rilis + tag saat peluncuran.
# Buat branch dari ujung rilis aktif (contoh: release/v3.8.49)
git fetch origin
git checkout -b feat/your-feature-name origin/release/v3.8.49
# ... lakukan perubahan ...
git commit -m "feat: describe your change"
git push -u origin feat/your-feature-name
# Buka Pull Request dengan base = release/v3.8.49
Penamaan Branch
| Prefiks | Tujuan |
|---|---|
feat/ |
Fitur baru |
fix/ |
Perbaikan bug |
refactor/ |
Restrukturisasi kode |
docs/ |
Perubahan dokumentasi |
test/ |
Penambahan/perbaikan pengujian |
chore/ |
Peralatan, CI, dependensi |
Pesan Commit
Ikuti Conventional Commits:
feat: tambahkan circuit breaker untuk pemanggilan penyedia
fix: selesaikan kasus khusus validasi rahasia JWT
docs: perbarui SECURITY.md dengan perlindungan PII
test: tambahkan pengujian unit observabilitas
refactor(db): gabungkan tabel batas laju
Cakupan (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.
Menjalankan Pengujian
# Semua pengujian (unit + vitest + ekosistem + e2e)
npm run test:all
# Satu file pengujian (runner pengujian bawaan Node.js — sebagian besar pengujian menggunakan ini)
node --import tsx/esm --test tests/unit/your-file.test.ts
# Hanya pengujian unit yang terdampak oleh perubahan Anda (pemilih TIA yang sama dengan gerbang CI, #8084)
npm run test:scoped # perubahan dalam commit terakhir (atau working tree)
npm run test:scoped:staged # hanya perubahan yang di-stage — cocok dipasangkan dengan eksekusi pre-commit
npm run test:scoped:full # bangun ulang peta grafik impor terlebih dahulu (setelah menambah/memindahkan file)
# Exit 1 + "run the full suite" berarti file hub (tsconfig, package.json, …) atau sumber
# yang belum dipetakan berubah — pemilih gagal secara aman dan tidak pernah melewati pengujian secara diam-diam.
# Vitest (server MCP, autoCombo, cache)
npm run test:vitest
# Pengujian E2E (memerlukan Playwright)
npm run test:e2e
# E2E klien protokol (transport MCP, A2A)
npm run test:protocols:e2e
# Pengujian kompatibilitas ekosistem
npm run test:ecosystem
# Gerbang cakupan: 60% pernyataan/baris/fungsi/cabang
npm run test:coverage
npm run coverage:report
# Pemeriksaan lint + format
npm run lint
npm run check
# Smoke combo upstream nyata berpagar (memerlukan akses VPS + kredit penyedia nyata)
# Mengakses penyedia NYATA — memerlukan sedikit biaya. TIDAK PERNAH dijalankan di CI. Dilewati dengan aman tanpa gerbang.
# Memerlukan: akses ssh root@192.168.0.15 (mengambil snapshot DB hanya-baca dari VPS).
RUN_COMBO_LIVE=1 npm run test:combo:live
# Smoke live VPS fase-3 — skrip Node ESM biasa, mengakses server .15 yang aktif secara langsung.
# Memerlukan: akses ssh root@192.168.0.15 (combo dibuat/dihapus melalui SSH sqlite).
# Mengakses penyedia NYATA (biaya kecil). Hanya membuat/menghapus combo __live_test__*. TIDAK PERNAH dijalankan di CI.
# REQUIRE_API_KEY=false pada .15 sehingga tidak memerlukan kunci API, tetapi mematuhi COMBO_LIVE_BASE_URL / COMBO_LIVE_API_KEY jika ditetapkan.
npm run test:combo:live:vps # 7 skenario HTTP (prioritas/round-robin/berbobot/biaya/fusi/otomatis + kesehatan)
npm run test:combo:live:vps:failover # menambahkan skenario failover lintas-penyedia nyata (total 8)
Catatan cakupan:
npm run test:coveragemengukur cakupan sumber untuk rangkaian pengujian unit utama, mengecualikantests/**, dan menyertakanopen-sse/**- Pull request harus mempertahankan gerbang cakupan pada 60%+ pernyataan/baris/fungsi/cabang
- Jika PR mengubah kode produksi di
src/,open-sse/,electron/, ataubin/, PR tersebut harus menambahkan atau memperbarui pengujian otomatis dalam PR yang sama npm run coverage:reportmencetak laporan terperinci per file dari eksekusi cakupan terbarunpm run test:coverage:legacymempertahankan metrik lama untuk perbandingan historis- Lihat
docs/ops/COVERAGE_PLAN.mduntuk peta jalan peningkatan cakupan bertahap
Persyaratan Pull Request
Sebelum membuka PR, gunakan Alur Utama Kontribusi untuk menjalankan siklus terfokus bagi hal yang Anda ubah. Rangkaian unit lengkap (4 shard CI), Vitest, gerbang cakupan 60%+, dan build produksi merupakan tanggung jawab CI — menjalankannya secara lokal tidak memberikan informasi tambahan yang belum diberikan oleh pemeriksaan PR, dan pada mesin yang lebih kecil dapat memenuhi kapasitas host (#8084):
- Jalankan file pengujian yang mencakup perubahan Anda:
node --import tsx/esm --test tests/unit/<file>.test.ts - Jalankan
npm run lint - Sertakan atau perbarui pengujian otomatis dalam PR yang sama setiap kali kode produksi berubah
- Sertakan file pengujian yang diubah atau ditambahkan dalam deskripsi PR saat kode produksi berubah
- Periksa hasil SonarQube pada PR ketika secret proyek dikonfigurasi di CI
Status pengujian saat ini: 122 file pengujian unit yang mencakup:
- Penerjemah penyedia dan konversi format
- Pembatasan laju, circuit breaker, dan ketahanan
- Cache semantik, idempotensi, pelacakan progres
- Operasi dan skema basis data (21 modul DB)
- Alur OAuth dan autentikasi
- Validasi endpoint API (Zod v4)
- Alat server MCP dan penerapan cakupan
- Sistem Memori dan Skills
Gaya Kode
- ESLint — Jalankan
npm run lintsebelum melakukan commit - Prettier — Diformat otomatis melalui
lint-stagedsaat commit (2 spasi, titik koma, tanda kutip ganda, lebar 100 karakter, koma penutup es5) - TypeScript — Semua kode
src/menggunakan.ts/.tsx;open-sse/menggunakan.ts/.js; dokumentasikan dengan TSDoc (@param,@returns,@throws) - Tanpa
eval()— ESLint memberlakukanno-eval,no-implied-eval,no-new-func - Validasi Zod — Gunakan skema Zod v4 untuk semua validasi input API
- Penamaan: File = camelCase/kebab-case, komponen = PascalCase, konstanta = UPPER_SNAKE
Penanganan kesalahan / blok catch kosong
Jangan pernah membiarkan catch tanpa penjelasan. Klasifikasikan ke dalam salah satu dari dua kategori (menerapkan
aturan tegas "jangan pernah mengabaikan kesalahan secara diam-diam dalam aliran SSE"):
-
Disengaja (pembersihan/telemetri best-effort milik kita sendiri) — kegagalan di sini memang diharapkan dan tidak berbahaya; tambahkan komentar alasan satu baris, tanpa logging (logging pada setiap permintaan merupakan gangguan yang ingin dihindari oleh konvensi ini).
} catch {} // menutup controller yang sudah ditutup setelah klien terputus memang diharapkan -
Harus dicatat (kode eksternal/yang disediakan pemanggil, atau pengabaian mengubah alur kontrol) — pertahankan catch (jangan pernah membiarkannya merusak aliran), tetapi keluarkan
console.debug/warnkontekstual agar kegagalan dapat ditemukan.} catch (e) { console.debug("[STREAM] onFailure callback error:", e); }
Lihat open-sse/utils/stream.ts dan open-sse/utils/streamHandler.ts untuk contoh penerapannya.
Struktur Proyek
src/ # TypeScript (.ts / .tsx)
├── app/ # Next.js 16 App Router
│ ├── (dashboard)/ # Halaman dasbor (23 bagian)
│ ├── api/ # Rute API (51 direktori)
│ └── login/ # Halaman autentikasi (.tsx)
├── domain/ # Mesin kebijakan (policyEngine, comboResolver, costRules, dll.)
├── lib/ # Logika bisnis inti (.ts)
│ ├── a2a/ # Server protokol Agent-to-Agent v0.3
│ ├── acp/ # Registri Agent Communication Protocol
│ ├── compliance/ # Mesin kebijakan kepatuhan
│ ├── db/ # Modul domain SQLite + 130 migrasi
│ ├── memory/ # Memori percakapan persisten
│ ├── oauth/ # Penyedia, layanan, dan utilitas OAuth
│ ├── skills/ # Kerangka kerja skill yang dapat diperluas
│ ├── usage/ # Pelacakan penggunaan dan penghitungan biaya
│ └── localDb.ts # Hanya lapisan ekspor ulang — jangan pernah menambahkan logika di sini
├── middleware/ # Middleware permintaan (promptInjectionGuard)
├── mitm/ # Proksi MITM (sertifikat, DNS, perutean target)
├── shared/
│ ├── components/ # Komponen React (.tsx)
│ ├── constants/ # Definisi penyedia (329), cakupan MCP, 19 strategi perutean
│ ├── utils/ # Circuit breaker, sanitizer, helper autentikasi
│ └── validation/ # Skema Zod v4
└── sse/ # Pipeline proksi SSE
open-sse/ # Workspace @omniroute/open-sse
├── executors/ # 89 modul implementasi executor
├── handlers/ # 11 handler permintaan (chat, respons, embedding, gambar, dll.)
├── mcp-server/ # Server MCP (110 alat unik, 3 transport, 33 cakupan)
├── services/ # 178 layanan tingkat atas (combo, autoCombo, rateLimitManager, dll.)
├── translator/ # Penerjemah format (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
├── transformer/ # Transformer Responses API
└── utils/ # 22 modul utilitas (aliran, TLS, proksi, logging)
electron/ # Aplikasi desktop Electron (lintas platform)
tests/
├── unit/ # Test runner Node.js (1.574 file pengujian)
├── integration/ # Pengujian integrasi
├── e2e/ # Pengujian Playwright
├── security/ # Pengujian keamanan
├── translator/ # Pengujian khusus penerjemah
└── load/ # Pengujian beban
docs/
├── adr/ # Catatan Keputusan Arsitektur
├── architecture/ # Arsitektur & ketahanan sistem
├── comparison/ # OmniRoute vs alternatif
├── compression/ # Panduan & aturan kompresi
├── dev/ # Panduan pengembangan
├── diagrams/ # Diagram arsitektur
├── frameworks/ # MCP, A2A, OpenCode, Memory, Skills
├── guides/ # Panduan pengguna, Docker, penyiapan, pemecahan masalah
├── i18n/ # Terjemahan README yang diinternasionalisasi
├── marketing/ # Materi pemasaran
├── ops/ # Deployment, proksi, cakupan, rilis
├── providers/ # Dokumentasi khusus penyedia
├── reference/ # Referensi API, variabel lingkungan, alat CLI, tingkat gratis
├── releases/ # Catatan rilis
├── routing/ # Mesin auto-combo, pemutaran ulang penalaran
├── screenshots/ # Tangkapan layar dasbor
├── security/ # Guardrail, kepatuhan, stealth, token
└── specs/ # Spesifikasi desain
Menambahkan Provider Baru
Langkah 1: Daftarkan Konstanta Provider
Tambahkan ke src/shared/constants/providers.ts — divalidasi dengan Zod saat modul dimuat.
Langkah 2: Tambahkan Executor (jika memerlukan logika khusus)
Buat executor di open-sse/executors/your-provider.ts dengan memperluas executor dasar.
Langkah 3: Tambahkan Translator (jika formatnya bukan OpenAI)
Buat translator permintaan/respons di open-sse/translator/.
Langkah 4: Tambahkan Konfigurasi OAuth (jika berbasis OAuth)
Tambahkan kredensial OAuth di src/lib/oauth/constants/oauth.ts dan layanan di src/lib/oauth/services/.
Jika provider upstream mendistribusikan client_id/secret OAuth publik atau kunci Firebase Web API di dalam CLI publik / bundle browser-nya, jangan menyematkannya sebagai literal string. Gunakan resolvePublicCred() dari open-sse/utils/publicCreds.ts dan tambahkan entri byte yang disamarkan ke EMBEDDED_DEFAULTS. Alur kerja wajib selengkapnya didokumentasikan di docs/security/PUBLIC_CREDS.md.
Di dalam handler/executor, pesan kesalahan yang sampai ke klien harus diproses melalui buildErrorBody() / sanitizeErrorMessage() dari open-sse/utils/error.ts — jangan pernah memasukkan err.stack atau err.message mentah ke dalam body Response. Lihat docs/security/ERROR_SANITIZATION.md.
Langkah 5: Daftarkan Model
Tambahkan definisi model di open-sse/config/providerRegistry.ts.
Langkah 6: Tambahkan Pengujian
Tulis pengujian unit di tests/unit/ yang sekurang-kurangnya mencakup:
- Pendaftaran provider
- Translasi permintaan/respons
- Penanganan kesalahan
Daftar Periksa Pull Request
- Pengujian lulus (
npm test) - Linting lulus (
npm run lint) - Build berhasil (
npm run build) - Tipe TypeScript ditambahkan untuk fungsi dan antarmuka publik baru
- Tidak ada secret atau nilai fallback yang di-hardcode
- Kredensial upstream publik disematkan melalui
resolvePublicCred()(lihatdocs/security/PUBLIC_CREDS.md), jangan pernah sebagai literal - Respons kesalahan diproses melalui
buildErrorBody()/sanitizeErrorMessage()— tidak ada stack trace mentah dalam body respons (lihatdocs/security/ERROR_SANITIZATION.md) - Perintah shell (
exec/spawn) meneruskan nilai runtime melaluienv, bukan melalui interpolasi string - Semua input divalidasi dengan skema Zod
- Fragmen changelog ditambahkan di bawah
changelog.d/{features|fixes|maintenance}/<PR>-<slug>.mduntuk perubahan yang terlihat oleh pengguna (lihatchangelog.d/README.md) — jangan mengeditCHANGELOG.mdsecara langsung; fragmen digabungkan saat rilis dan tidak pernah menimbulkan konflik antar-PR - Dokumentasi diperbarui (jika berlaku)
- Tidak ada peringatan CodeQL / Secret-Scanning baru yang dibuka, atau setiap peringatan telah ditutup dengan justifikasi teknis yang merujuk pada dokumen
docs/security/yang relevan - Route yang menjalankan proses anak (
/api/mcp/,/api/cli-tools/runtime/) diklasifikasikan sebagaiisLocalOnlyPath()disrc/server/authz/routeGuard.ts— lihat Aturan Ketat #15 - Tidak ada trailer
Co-Authored-Bydalam pesan commit — commit harus ditampilkan hanya di bawah identitas Git pemilik repositori (Aturan Ketat #16)
Rilis
Rilis dikelola melalui alur kerja /generate-release. Saat GitHub Release baru dibuat, paket akan secara otomatis dipublikasikan ke npm melalui GitHub Actions.
Untuk deployment VPS, gunakan npm run build:release (bukan npm run build) — perintah ini melakukan build ulang secara bersih, menyusun bundle ke dalam dist/, dan menulis sentinel dist/BUILD_SHA.
Kemudian gunakan skill /deploy-vps-*-cc yang menyinkronkan dist/ melalui rsync ke direktori app/ jarak jauh.
Mendapatkan Bantuan
- Arsitektur: Lihat
docs/architecture/ARCHITECTURE.md - Referensi API: Lihat
docs/reference/API_REFERENCE.md - Dokumentasi keamanan:
docs/security/CLI_TOKEN.md,docs/security/ROUTE_GUARD_TIERS.md,docs/security/ERROR_SANITIZATION.md,docs/security/PUBLIC_CREDS.md - Dokumentasi operasional:
docs/ops/SQLITE_RUNTIME.md - Isu: github.com/diegosouzapw/OmniRoute/issues
- ADR: Lihat
docs/adr/untuk catatan keputusan arsitektural