# Remote Mode (বাংলা) 🌐 **Languages:** 🇺🇸 [English](../../../../guides/REMOTE-MODE.md) · 🇪🇹 [am](../../../am/docs/guides/REMOTE-MODE.md) · 🇸🇦 [ar](../../../ar/docs/guides/REMOTE-MODE.md) · 🇦🇿 [az](../../../az/docs/guides/REMOTE-MODE.md) · 🇧🇬 [bg](../../../bg/docs/guides/REMOTE-MODE.md) · 🇧🇦 [bs](../../../bs/docs/guides/REMOTE-MODE.md) · 🇨🇿 [cs](../../../cs/docs/guides/REMOTE-MODE.md) · 🇩🇰 [da](../../../da/docs/guides/REMOTE-MODE.md) · 🇩🇪 [de](../../../de/docs/guides/REMOTE-MODE.md) · 🇬🇷 [el](../../../el/docs/guides/REMOTE-MODE.md) · 🇪🇸 [es](../../../es/docs/guides/REMOTE-MODE.md) · 🇪🇪 [et](../../../et/docs/guides/REMOTE-MODE.md) · 🇮🇷 [fa](../../../fa/docs/guides/REMOTE-MODE.md) · 🇫🇮 [fi](../../../fi/docs/guides/REMOTE-MODE.md) · 🇫🇷 [fr](../../../fr/docs/guides/REMOTE-MODE.md) · 🇮🇪 [ga](../../../ga/docs/guides/REMOTE-MODE.md) · 🇮🇳 [gu](../../../gu/docs/guides/REMOTE-MODE.md) · 🇳🇬 [ha](../../../ha/docs/guides/REMOTE-MODE.md) · 🇮🇱 [he](../../../he/docs/guides/REMOTE-MODE.md) · 🇮🇳 [hi](../../../hi/docs/guides/REMOTE-MODE.md) · 🇭🇷 [hr](../../../hr/docs/guides/REMOTE-MODE.md) · 🇭🇺 [hu](../../../hu/docs/guides/REMOTE-MODE.md) · 🇦🇲 [hy](../../../hy/docs/guides/REMOTE-MODE.md) · 🇮🇩 [id](../../../id/docs/guides/REMOTE-MODE.md) · 🇳🇬 [ig](../../../ig/docs/guides/REMOTE-MODE.md) · 🇮🇹 [it](../../../it/docs/guides/REMOTE-MODE.md) · 🇯🇵 [ja](../../../ja/docs/guides/REMOTE-MODE.md) · 🇬🇪 [ka](../../../ka/docs/guides/REMOTE-MODE.md) · 🇰🇭 [km](../../../km/docs/guides/REMOTE-MODE.md) · 🇮🇳 [kn](../../../kn/docs/guides/REMOTE-MODE.md) · 🇰🇷 [ko](../../../ko/docs/guides/REMOTE-MODE.md) · 🇱🇹 [lt](../../../lt/docs/guides/REMOTE-MODE.md) · 🇱🇻 [lv](../../../lv/docs/guides/REMOTE-MODE.md) · 🇮🇳 [ml](../../../ml/docs/guides/REMOTE-MODE.md) · 🇮🇳 [mr](../../../mr/docs/guides/REMOTE-MODE.md) · 🇲🇾 [ms](../../../ms/docs/guides/REMOTE-MODE.md) · 🇲🇹 [mt](../../../mt/docs/guides/REMOTE-MODE.md) · 🇲🇲 [my](../../../my/docs/guides/REMOTE-MODE.md) · 🇳🇵 [ne](../../../ne/docs/guides/REMOTE-MODE.md) · 🇳🇱 [nl](../../../nl/docs/guides/REMOTE-MODE.md) · 🇳🇴 [no](../../../no/docs/guides/REMOTE-MODE.md) · 🇮🇳 [or](../../../or/docs/guides/REMOTE-MODE.md) · 🇮🇳 [pa](../../../pa/docs/guides/REMOTE-MODE.md) · 🇵🇭 [phi](../../../phi/docs/guides/REMOTE-MODE.md) · 🇵🇱 [pl](../../../pl/docs/guides/REMOTE-MODE.md) · 🇵🇹 [pt](../../../pt/docs/guides/REMOTE-MODE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/guides/REMOTE-MODE.md) · 🇷🇴 [ro](../../../ro/docs/guides/REMOTE-MODE.md) · 🇷🇺 [ru](../../../ru/docs/guides/REMOTE-MODE.md) · 🇱🇰 [si](../../../si/docs/guides/REMOTE-MODE.md) · 🇸🇰 [sk](../../../sk/docs/guides/REMOTE-MODE.md) · 🇸🇮 [sl](../../../sl/docs/guides/REMOTE-MODE.md) · 🇷🇸 [sr](../../../sr/docs/guides/REMOTE-MODE.md) · 🇸🇪 [sv](../../../sv/docs/guides/REMOTE-MODE.md) · 🇰🇪 [sw](../../../sw/docs/guides/REMOTE-MODE.md) · 🇮🇳 [ta](../../../ta/docs/guides/REMOTE-MODE.md) · 🇮🇳 [te](../../../te/docs/guides/REMOTE-MODE.md) · 🇹🇭 [th](../../../th/docs/guides/REMOTE-MODE.md) · 🇹🇷 [tr](../../../tr/docs/guides/REMOTE-MODE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/guides/REMOTE-MODE.md) · 🇵🇰 [ur](../../../ur/docs/guides/REMOTE-MODE.md) · 🇺🇿 [uz](../../../uz/docs/guides/REMOTE-MODE.md) · 🇻🇳 [vi](../../../vi/docs/guides/REMOTE-MODE.md) · 🇳🇬 [yo](../../../yo/docs/guides/REMOTE-MODE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/guides/REMOTE-MODE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/guides/REMOTE-MODE.md) --- OmniRoute অন্য কোথাও চললেও আপনার ল্যাপটপে `omniroute` CLI চালান (একটি VPS, একটি হোম সার্ভার, আপনার Tailnet-এর অন্য কোনো মেশিন)। আপনি `omniroute connect` দিয়ে একবার লগ ইন করেন, এরপর থেকে **প্রতিটি** CLI কমান্ড সেই রিমোট সার্ভারকে লক্ষ্য করে — একই কমান্ড, একই আউটপুট, শুধু রিমোট সার্ভারের বিরুদ্ধে কার্যকর হয়। ইনস্টল করার জন্য দ্বিতীয় কোনো টুল নেই: রিমোট মোড হলো নিয়মিত `omniroute` CLI, সঙ্গে সীমিত-পরিসরের **অ্যাক্সেস টোকেন**। ```bash npm install -g omniroute # সাধারণ CLI omniroute connect 192.168.0.15 # লগ ইন করুন (পাসওয়ার্ড → সীমিত-পরিসরের টোকেন) omniroute models list # ← এখন রিমোট সার্ভারের মডেলগুলোর তালিকা দেখায় omniroute configure codex # ← রিমোট ক্যাটালগ থেকে একটি লোকাল Codex প্রোফাইল লেখে ``` --- ## এটি যেভাবে কাজ করে ``` আপনার ল্যাপটপ রিমোট OmniRoute (VPS) ┌────────────────────┐ ┌───────────────────────────────┐ │ omniroute CLI │ POST /api/cli/connect (পাসওয়ার্ড → টোকেন) │ │ কনটেক্সট: vps │ ───────────────► │ সীমিত-পরিসরের অ্যাক্সেস টোকেন তৈরি করে │ │ baseUrl, token │ Authorization: Bearer oma_live_… │ │ │ ───────────────► │ প্রতিটি ব্যবস্থাপনা রুট, টোকেনের │ │ কনফিগগুলো │ ◄─────────────── │ স্কোপ অনুযায়ী যাচাই করা হয় │ │ লোকালভাবে লেখে │ └───────────────────────────────┘ └────────────────────┘ ``` - **কনটেক্সটগুলো** প্রতিটি একটি করে সার্ভার সংরক্ষণ করে (`~/.omniroute/config.json`, `chmod 600`)। `omniroute contexts use ` সক্রিয় সার্ভার পরিবর্তন করে; `default` হলো লোকাল। - **অ্যাক্সেস টোকেনগুলো** (`oma_live_…`) ব্যবস্থাপনা কমান্ড অনুমোদন করে। এগুলো ইনফারেন্স API কী (`sk-…`, যা `/v1/chat/completions`-এর জন্য ব্যবহৃত হয়) থেকে আলাদা। - সার্ভারে একটি টোকেনের শুধু SHA-256 হ্যাশ সংরক্ষিত থাকে। প্লেইনটেক্সটটি তৈরির সময় **একবারই** দেখানো হয়। --- ## সংযোগ করা ### ম্যানেজমেন্ট পাসওয়ার্ড দিয়ে (বুটস্ট্র্যাপ) ```bash omniroute connect 192.168.0.15 # http://192.168.0.15:20128-এর ম্যানেজমেন্ট পাসওয়ার্ড: ******** # ✔ http://192.168.0.15:20128-এ সংযুক্ত — কনটেক্সট '192.168.0.15' (স্কোপ: admin) ``` পাসওয়ার্ডের প্রবাহ ডিফল্টভাবে একটি **admin** টোকেন তৈরি করে (আপনার কাছে পাসওয়ার্ড আছে, তাই আপনার ইতিমধ্যেই পূর্ণ নিয়ন্ত্রণ রয়েছে)। `--scope` দিয়ে স্কোপ কমিয়ে নিন: ```bash omniroute connect 192.168.0.15 --scope write ``` বিকল্প: `--port

` (হোস্টে পোর্ট না থাকলে), `--name ` (কনটেক্সটের নাম), `--scope read|write|admin`। একটি পূর্ণ URL অপরিবর্তিতভাবে ব্যবহার করা হয়: `omniroute connect https://omni.example.com`। সার্ভারে ড্যাশবোর্ডের দ্বি-ফ্যাক্টর প্রমাণীকরণ সক্রিয় থাকলে (সেটিংস → নিরাপত্তা), শুধু পাসওয়ার্ড প্রত্যাখ্যান করা হবে: তখন CLI আপনাকে অথেন্টিকেটর অ্যাপের কোড (অথবা একটি রিকভারি কোড) চাইবে। নন-ইন্টার্যাক্টিভ ব্যবহারের জন্য `--totp ` দিয়ে কোডটি আগে থেকেই দিন। ### আগে থেকে তৈরি টোকেন দিয়ে ড্যাশবোর্ডে (অথবা `omniroute tokens create` দিয়ে) একটি নির্দিষ্ট স্কোপের টোকেন তৈরি করে সেটি পেস্ট করুন — কোনো পাসওয়ার্ডের প্রয়োজন নেই: ```bash omniroute connect 192.168.0.15 --key oma_live_xxxxxxxx ``` CLI `GET /api/cli/whoami` ব্যবহার করে টোকেনটি যাচাই করে এবং সক্রিয় কনটেক্সট হিসেবে সংরক্ষণ করে। --- ## স্কোপসমূহ তিনটি স্তর, ক্রমানুক্রমিক (`admin ⊃ write ⊃ read`): | স্কোপ | যা করা যায় | | ------- | ------------------------------------------------------------------------------ | | `read` | তালিকা/পরিদর্শন — `models list`, `providers status`, `logs`, `usage`, `cost` | | `write` | read **+** কনফিগার/প্রয়োগ — `setup-codex`, `keys add`, `config set`, কম্বো | | `admin` | write **+** ব্যবস্থাপনা — `tokens` CRUD, প্রোভাইডার যোগ, সার্ভিস, পলিসি, oauth | প্রতিটি রুটের জন্য প্রয়োজনীয় স্কোপ সার্ভারটি HTTP মেথড থেকে অনুমান করে (`GET`→read, পরিবর্তন→write), পাশাপাশি সংবেদনশীল ক্ষেত্রগুলোর জন্য একটি admin অনুমোদন-তালিকা ব্যবহার করে (`/api/cli/tokens`, `/api/providers` পরিবর্তন, `/api/oauth`, `/api/services`, …)। অপর্যাপ্ত স্কোপের টোকেন একটি স্পষ্ট বার্তাসহ `403` পায়। > যেসব রুট প্রসেস চালু করে (`/api/services/*`, `/api/mcp/*`, …), সেগুলো > **শুধু লুপব্যাকেই** সীমাবদ্ধ থাকে — স্কোপ যা-ই হোক, কোনো রিমোট টোকেন কখনোই সেগুলোতে পৌঁছাতে পারে না। --- ## রিমোট ইনস্টলে Antigravity সংযুক্ত করা Antigravity Google-এর firstparty/nativeapp সম্মতি স্ক্রিন ব্যবহার করে। Google কেবল তখনই অনুমোদন কোড প্রকাশ করে, যখন **loopback redirect** (`http://127.0.0.1:/callback`) **সাইন-ইন অনুমোদনকারী ব্রাউজার থেকে অ্যাক্সেসযোগ্য** হয়। রিমোট VPS ইনস্টলে ওই loopback আপনার মেশিনে নয়, সার্ভারে থাকে, তাই সম্মতি স্ক্রিনটি **অনির্দিষ্টকাল আটকে থাকে এবং কখনোই কোনো কোড দেয় না** — ফলে সাধারণ "callback URL পেস্ট করুন" বিকল্পটিতে পেস্ট করার মতো কিছুই থাকে না। (এটি Google-এর পক্ষের একটি সীমাবদ্ধতা: শুধু OmniRoute নয়, bundled Antigravity desktop client ব্যবহারকারী যেকোনো proxy-তেই একই সমস্যা ঘটে।) আপনি আটকে যাওয়ার আগেই dashboard এটি শনাক্ত করে: localhost নয় এমন কোনো ঠিকানা থেকে **Providers → Antigravity → Connect** খুললে সাধারণ "callback URL কপি করুন" বিজ্ঞপ্তির বদলে নিচের দুটি সমাধান দেখানো হয়, যেখানে আপনার host ও port আগে থেকেই পূরণ করা থাকে। (একটি LAN ঠিকানাও এর অন্তর্ভুক্ত — এই callback-এর ক্ষেত্রে `192.168.x.x` localhost নয়।) রিমোট OmniRoute-এ Antigravity সংযুক্ত করার দুটি সমর্থিত উপায় রয়েছে। ### বিকল্প A — লোকাল লগইন সহায়ক (প্রস্তাবিত) OAuth **আপনার নিজের কম্পিউটারে** চালান, যেখানে `127.0.0.1` অ্যাক্সেসযোগ্য। সহায়কটি সরাসরি Google-এর সঙ্গে যোগাযোগ করে, তাই dashboard-এর সংস্করণ যেখানে সম্পন্ন হতে পারে না, সেখানে সম্মতি প্রক্রিয়া সম্পন্ন হয়। **আপনি যদি ইতিমধ্যেই সংযুক্ত থাকেন** (`omniroute connect `), তাহলে কিছুই কপি করতে হবে না — সহায়কটি আপনার হয়ে ওই ইনস্টলে credential পৌঁছে দেয়: ```bash # আপনার LOCAL মেশিনে (Node.js + একটি ব্রাউজার প্রয়োজন): omniroute connect 192.168.0.15 # একবার — একটি admin-scoped context token তৈরি করে npx omniroute login antigravity # ↳ Google-এর সম্মতি স্ক্রিন খোলে, একটি লোকাল loopback port-এ callback গ্রহণ করে, # সেটি exchange করে এবং সক্রিয় context-এ credential POST করে: # # Antigravity http://192.168.0.15:20128-এ সংযুক্ত হয়েছে (সংযোগ abc123)। # পেস্ট করার কিছু নেই — আপনি এই terminal বন্ধ করতে পারেন। ``` সক্রিয় context অন্য কোনো মেশিন নির্দেশ করলেই push স্বয়ংক্রিয়ভাবে ঘটে। `--push` / `--no-push` দিয়ে যেকোনো একটি আচরণ বাধ্যতামূলক করুন, অথবা `--context ` দিয়ে নির্দিষ্ট কোনো context লক্ষ্য করুন। **আপনার মেশিন VPS-এ পৌঁছাতে না পারলেও** (firewalled, SSH নেই, air-gapped desk), সহায়কটি তবুও কাজ করে — এর কেবল Google-এ পৌঁছানোই _প্রয়োজন_। `--no-push` ব্যবহার করুন, অথবা push ব্যর্থ হতে দিন: ইতিমধ্যে সম্পন্ন করা authorization বাতিল না করে এটি বিকল্প হিসেবে blob প্রিন্ট করে। ```bash npx omniroute login antigravity --no-push # omniroute-cred-v1.eyJ2IjoxLCJ... ``` এরপর **রিমোট** dashboard-এ: **Providers → Antigravity → Connect**-এ যান এবং **Step 2** ফিল্ডে `omniroute-cred-v1.…` blob-টি পেস্ট করুন (এটি callback URL বা credential blob—দুটির যেকোনোটি গ্রহণ করে)। OmniRoute এটি decode করে, server-side-এ Cloud Code onboarding চালায় এবং সংযোগটি স্থায়ীভাবে সংরক্ষণ করে। > blob-টিতে একটি refresh token রয়েছে — এটিকে password-এর মতো সুরক্ষিত রাখুন। push পদ্ধতিতে এটি আপনার context-এর authenticated connection-এর মাধ্যমে একবার পাঠানো হয়; paste পদ্ধতিতে আপনার dashboard connection-এর মাধ্যমে পাঠানো হয়। উভয় ক্ষেত্রেই এটি সংরক্ষণের সময় encrypted থাকে এবং সফল push কখনোই এটি আপনার terminal-এ প্রিন্ট করে না। Flags: `--no-browser` (স্বয়ংক্রিয়ভাবে খোলার বদলে URL প্রিন্ট করুন), `--port ` (loopback port নির্দিষ্ট করুন), `--timeout `, `--push` / `--no-push` (স্বয়ংক্রিয় delivery override করুন), `--context ` (নির্দিষ্ট একটি context লক্ষ্য করুন)। ### বিকল্প B — SSH local-forward tunnel VPS-এ আপনার SSH access থাকলে dashboard port forward করুন, যাতে loopback callback tunnel-এর মাধ্যমে পুনরায় সার্ভারে পৌঁছায়: ```bash # আপনার LOCAL মেশিনে: ssh -L 20128:127.0.0.1:20128 user@your-vps # এরপর আপনার LOCAL ব্রাউজারে http://localhost:20128 খুলে স্বাভাবিকভাবে Antigravity সংযুক্ত করুন # — 127.0.0.1:20128/callback redirect এখন SSH-এর মাধ্যমে VPS-এ পৌঁছাবে। ``` আপনি যেহেতু `localhost:20128` হিসেবে dashboard-এ পৌঁছাচ্ছেন, তাই Google-এর সম্মতি সম্পন্ন হয় এবং callback একই tunnel-এর মাধ্যমে সার্ভারে পৌঁছে যায় — কোনো blob-এর প্রয়োজন নেই। সংযোগটি সক্রিয় হিসেবে দেখা না যাওয়া পর্যন্ত tunnel খোলা রাখুন। নিচের fixed-loopback provider-গুলোর বিপরীতে, এখানে **একটি forward-ই যথেষ্ট**: Antigravity callback dashboard port-ই ব্যবহার করে, তাই tunnel করার জন্য provider-নির্দিষ্ট দ্বিতীয় কোনো port নেই। > সম্পূর্ণ headless একটি বিকল্প হলো (কোনো সহায়ক বা tunnel ছাড়াই) আপনার **নিজস্ব** > Google OAuth web credentials + একটি public base URL কনফিগার করা; provider-এর OAuth > environment variable-গুলো দেখুন। উপরের দুটি বিকল্পের জন্য অতিরিক্ত কোনো Google setup প্রয়োজন নেই। --- ## রিমোট ইনস্টলে Codex / Grok সংযুক্ত করা (fixed-loopback প্রোভাইডার) Codex, xAI (`xai-oauth`) এবং Grok CLI (`grok-cli`) তাদের upstream OAuth অ্যাপে একটি **নির্দিষ্ট** loopback `redirect_uri` নিবন্ধন করে। OmniRoute এটি পরিবর্তন করতে পারে না — প্রোভাইডারটি সব সময় ব্রাউজারকে একই hardcoded ঠিকানায় ফেরত পাঠায়: | প্রোভাইডার | প্রোভাইডার যে নির্দিষ্ট callback-এ redirect করে | | ----------- | ----------------------------------------------- | | `codex` | `http://localhost:1455/auth/callback` | | `xai-oauth` | `http://127.0.0.1:56121/callback` | | `grok-cli` | `http://127.0.0.1:56122/callback` | এখানে `localhost` বলতে **যে মেশিনে ব্রাউজার চলছে সেটিকে** বোঝায়, অন্যদিকে OmniRoute-এর PKCE callback server **সার্ভারের** loopback-এ শোনে। `http://192.168.0.15:20128`-এর মতো একটি LAN ঠিকানায় ড্যাশবোর্ড খুললে দুটির কখনোই সংযোগ হয় না: authorization code আপনার নিজস্ব ল্যাপটপের `localhost:1455`-এ পৌঁছায়, যেখানে কিছুই শুনছে না, এবং প্রোভাইডার কোনো ত্রুটি না দেখিয়েই sign-in ব্যর্থ করে। ড্যাশবোর্ড popup খোলার আগেই এটি শনাক্ত করে এবং login-কে নীরবে ব্যর্থ হতে না দিয়ে tunnel command দেখায় (#8046)। ### সমাধান — **উভয়** port forward করুন ```bash # যে মেশিনে BROWSER চলছে, সেখানে: ssh -L 20128:127.0.0.1:20128 -L 1455:127.0.0.1:1455 @192.168.0.15 # এরপর http://localhost:20128-এ যান এবং সেখান থেকে Codex সংযুক্ত করুন ``` দুটি forward-ই প্রয়োজন, এবং শুধু একটি forward করলেও ব্যর্থ হবে: - **`20128`** (ড্যাশবোর্ড port) origin-কে প্রকৃত localhost করে, যার কারণে OmniRoute আদৌ PKCE callback server চালু করে — কোনো LAN origin কখনোই সেই branch-এ পৌঁছায় না। - **`1455`** (প্রোভাইডারের নির্দিষ্ট callback port) হলো সেই স্থান যেখানে ব্রাউজারকে ফেরত পাঠানো হয়; এটিকে tunnel-এর মাধ্যমে সার্ভারের loopback-এ পৌঁছাতে হবে। xAI বা Grok CLI সংযুক্ত করার সময় `1455`-এর পরিবর্তে `56121`/`56122` এবং `20128`-এর পরিবর্তে আপনার প্রকৃত ড্যাশবোর্ড port ব্যবহার করুন। সংযোগটি active হিসেবে না দেখানো পর্যন্ত tunnel খোলা রাখুন। > **SSH access নেই?** Codex এবং Grok CLI একটি paste করা token-ও গ্রহণ করে — connect dialog-এর **Paste API > Key** / **Import auth.json** tab। এই পদ্ধতিতে কোনো loopback > callback নেই, তাই এটি যেকোনো origin থেকে কাজ করে। Codex অতিরিক্তভাবে একটি সাধারণ access > token অথবা একটি `~/.codex/auth.json` session blob গ্রহণ করে। --- ## টোকেন ব্যবস্থাপনা ```bash omniroute tokens create --name "laptop" --scope write [--expires 30] # ↳ গোপন মানটি একবারই দেখানো হয় — এখনই কপি করুন omniroute tokens list # মাস্ক করা: id, name, scope, prefix, status, expiry omniroute tokens revoke # সাথে সাথে বাতিল করুন omniroute tokens scopes # তিনটি scope ব্যাখ্যা করে ``` `tokens` কমান্ডের জন্য **admin** credential দরকার। আপনি ড্যাশবোর্ডের **Settings → Access Tokens**-এর অধীনেও টোকেন ব্যবস্থাপনা করতে পারেন (তৈরি, বাতিল, একবার-কপি)। কোনো টোকেন কখনোই তার স্রষ্টার নিজের অধিকারের চেয়ে বেশি অধিকার নিয়ে তৈরি করা যায় না। একটি `admin` টোকেন শুধু operator তৈরি করতে পারে — ড্যাশবোর্ড সেশন, সার্ভারে থাকা স্থানীয় CLI, অথবা পাসওয়ার্ডসহ `omniroute connect`। Machine credentials (`admin` access token, বা `manage`/`admin` scope-সহ API key) শুধু `write` ও `read` টোকেন তৈরি করতে পারে; `--scope admin` চাইলে তারা `403` পায়। লগইন নিষ্ক্রিয় করলে minting খুলে যায় না: যেকোনো scope-এর access token এমন একটি credential যা সবসময় প্রমাণীকৃত রুট গ্রহণ করে, তাই বেনামি কল যেকোনো scope-এ `401` পায়। --- ## রিমোট ক্যাটালগ থেকে একটি কোডিং CLI কনফিগার করা `omniroute configure` **সক্রিয় সার্ভার**-এর লাইভ মডেল ক্যাটালগ পড়ে এবং **আপনার** মেশিনে একটি কনফিগ লেখে। ```bash omniroute configure codex # Providers: glm, kmc, ollamacloud, opencode-go, … # প্রোভাইডার: glm # মডেল id: glm/glm-5.2 # ✔ লেখা হয়েছে ~/.codex/glm52.config.toml # ব্যবহার করুন: codex --profile glm52 # নন-ইন্টারঅ্যাক্টিভ omniroute configure codex --provider glm --model glm/glm-5.2 --name glm52 # প্রায়ই ব্যবহৃত মডেলকে ইন্টারঅ্যাক্টিভ picker-এর শীর্ষে রাখুন omniroute configure codex --provider glm --model glm/glm-5.2 --favorite --yes ``` Picker স্থানীয় `model-preferences.json` ফাইলে শুধু মডেল ID রাখে (কখনো URL বা credential নয়), context ও CLI target অনুযায়ী সীমাবদ্ধ করে। Favorites সাম্প্রতিক নির্বাচনের আগে দেখানো হয়; ওই context/target তালিকা থেকে নির্বাচিত মডেল সরাতে `--unfavorite` ব্যবহার করুন। লেখা profile ইনফারেন্স key-কে env var (`OMNIROUTE_API_KEY`) দিয়ে উল্লেখ করে — গোপন মানটি কখনো ডিস্কে লেখা হয় না। একবারের মূল Codex সেটআপের জন্য (`[model_providers.omniroute]` ব্লক), দেখুন [CODEX-CLI-CONFIGURATION.md](./CODEX-CLI-CONFIGURATION.md)। ### কোনো config না লিখে রিমোটের বিপরীতে CLI চালু করা `omniroute run `-ও সক্রিয় context মেনে চলে: রিমোট base URL এবং context credential শুধু চালু করা প্রক্রিয়ায় ইনজেক্ট করা হয়। ```bash omniroute connect 192.168.0.15 omniroute run claude --model openai/gpt-5.4 # Claude Code → remote omniroute run gemini --model glm/glm-5.2 -- --skip-trust -p "hello" omniroute run opencode --model glm/glm-5.2 -- run "reply OK" # ঠিক কী চালু হবে তার পূর্বরূপ দেখুন (শুধু env KEY NAMES, কখনো মান নয়): omniroute run codex --dry-run --json ``` Targets: `claude`, `codex`, `aider`, `goose`, `opencode`, `qwen`, `gemini` (একক উৎস: `bin/cli/cli-manifest.mjs`)। Qwen ও Gemini একটি অস্থায়ী, বিচ্ছিন্ন home-এ চলে যা বের হওয়ার সময় মুছে ফেলা হয়, তাই চালু করার প্রক্রিয়া কখনো আপনার ব্যক্তিগত tool configuration স্পর্শ করে না — বা সেখানে ফাঁস হয় না। ### প্রতি-CLI সেটআপ কমান্ড প্রতিটি সমর্থিত CLI-এর একটি remote-সচেতন সেটআপ কমান্ড আছে (সবগুলোই সক্রিয় context মানে, অথবা `--remote --api-key `): | CLI | কমান্ড | যা লেখে | | ----------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Codex | `omniroute setup-codex` | `~/.codex/.config.toml` profiles (প্রতি মডেল) | | Claude Code | `omniroute setup-claude` | `~/.claude/profiles//settings.json` (প্রতি মডেল) | | OpenCode | `omniroute setup-opencode` | `~/.config/opencode/opencode.json` — প্রতিটি catalog মডেলসহ `omniroute` openai-compatible প্রোভাইডার (চালান `opencode -m omniroute/`) | | Cline | `omniroute setup-cline` | `~/.cline/data/{globalState,secrets}.json` (CLI মোড) + পেস্ট করার জন্য VS Code extension সেটিং ছাপায় (OpenAI-compatible, Base URL **`/v1` ছাড়া**) | | Kilo Code | `omniroute setup-kilo` | `~/.local/share/kilo/auth.json` (CLI) + VS Code `kilocode.*` সেটিং — OpenAI-compatible, Base URL **`/v1` সহ** | | Continue | `omniroute setup-continue` | `~/.continue/config.yaml` (VS Code/JetBrains + `cn` CLI) — `provider: openai`, `apiBase` **`/v1` সহ**, key `${{ secrets.OMNIROUTE_API_KEY }}` দিয়ে | | Cursor | `omniroute setup-cursor` | অ্যাপের ভেতরের ধাপ ছাপায় (Settings → Models → Override OpenAI Base URL **`/v1` সহ** + key + model)। Cursor কনফিগ অস্বচ্ছ SQLite — শুধু chat panel | | Roo Code | `omniroute setup-roo` | একটি Roo import JSON লেখে (`~/.omniroute/roo-settings.json`) + `roo-cline.autoImportSettingsPath` সেট করে + UI ধাপ ছাপায় (OpenAI-compatible, Base URL **`/v1` সহ**) | | Crush | `omniroute setup-crush` | `~/.config/crush/crush.json` — `openai-compat` প্রোভাইডার, `base_url` **`/v1` সহ**, key `$OMNIROUTE_API_KEY` দিয়ে | | Zed | `omniroute setup-zed` | `~/.config/zed/settings.json` — `language_models.openai_compatible.omniroute`, `api_url` **`/v1` সহ**, key Zed `$OMNIROUTE_API_KEY` থেকে পড়ে (কখনো লেখা হয় না) | | Goose | `omniroute setup-goose` | `~/.config/goose/config.yaml` (`GOOSE_PROVIDER=openai` + `OPENAI_HOST` **`/v1` ছাড়া** + `GOOSE_MODEL`) + env recipe | | Aider | `omniroute setup-aider` | `~/.aider.conf.yml` (`openai-api-base` **`/v1` ছাড়া** + `model: openai/`) + env recipe (`aider --message --yes`) | | Qwen Code | `omniroute setup-qwen` | `~/.qwen/settings.json` V4 `modelProviders.openai` এন্ট্রি + `~/.qwen/.env`-এ `OMNIROUTE_API_KEY` | ```bash # OpenCode (openai-compatible প্রোভাইডার, সব catalog মডেল, remote VPS) omniroute setup-opencode --remote http://192.168.0.15:20128 --api-key oma_live_xxx omniroute setup-opencode --only glm,kimi # শুধু মিলে যাওয়া মডেল রাখুন opencode -m omniroute/glm/glm-5.2 "..." # আগে OMNIROUTE_API_KEY export করুন ``` > OpenCode-এর একটি সমৃদ্ধ **plugin** ইন্টিগ্রেশনও আছে: `omniroute setup opencode` (এখন `--remote`-এর মাধ্যমে remote-সচেতন) `@omniroute/opencode-plugin` ইনস্টল করে। > `setup-opencode` হালকা openai-compatible বিকল্প। API key `{env:OMNIROUTE_API_KEY}` দিয়ে উল্লেখ করা হয় — কখনো ডিস্কে লেখা হয় না। > > OpenCode v2-তে, বরং `@omniroute/opencode-plugin-v2` ব্যবহার করুন: একই catalog, ভিন্ন loader contract। OpenCode-এর নিজস্ব credential store সংযুক্ত থাকলে এটি সেখান থেকেই key পড়ে, তাই একটি remote gateway-এর জন্য `opencode.json`-এ কোনো key লাগে না। --- ## প্রসঙ্গগুলি পরিচালনা করা (সার্ভারগুলির মধ্যে স্যুইচ করা) একটি **প্রসঙ্গ** হলো একটি সংরক্ষিত সার্ভার (baseUrl + credential + scope)। `omniroute connect` একটি তৈরি করে এবং সেটিকে সক্রিয় করে; তারপর থেকে প্রতিটি কমান্ড সেটিকে লক্ষ্য করে। `omniroute contexts` ব্যবহার করে এগুলি পরিচালনা করুন এবং তাদের মধ্যে স্যুইচ করুন: ```bash omniroute contexts list # সমস্ত প্রসঙ্গ; সক্রিয়টি ● দ্বারা চিহ্নিত omniroute contexts current # সক্রিয় সার্ভার, প্রমাণীকরণ স্থিতি, স্কোপ ``` ```text | নাম | বেস ইউআরএল | প্রমাণীকরণ | স্কোপ | বর্ণনা ● | vps | http://100.67.86.91:20128 | token | admin | রিমোট ওমনিরুট (…) | default | http://localhost:20128 | ✗ | | ``` **সার্ভার স্যুইচ করুন** — প্রতিটি পরবর্তী কমান্ড সক্রিয় প্রসঙ্গ অনুসরণ করে: ```bash omniroute contexts use vps # → এখন সমস্ত কমান্ড রিমোট ভিপিএস-কে লক্ষ্য করবে omniroute tokens list # (ভিপিএস-এর বিরুদ্ধে চলে) omniroute contexts use default # → লোকালহোস্টে ফিরে যান omniroute tokens list # (স্থানীয় সার্ভারের বিরুদ্ধে চলে) ``` **ম্যানুয়ালি একটি প্রসঙ্গ যোগ করুন** (`connect`-এর পরিবর্তে), পরিদর্শন করুন, অথবা নাম পরিবর্তন করুন: ```bash omniroute contexts add staging --url https://staging.example.com:20128 \ --access-token oma_live_xxxx --scope write --description "staging box" omniroute contexts show staging # একটি প্রসঙ্গের সম্পূর্ণ বিবরণ omniroute contexts rename staging stg ``` **একটি প্রসঙ্গ সরান** — নিশ্চিতকরণের জন্য প্রম্পট করে; এটি এড়িয়ে যেতে `--yes` পাস করুন (স্ক্রিপ্ট / নন-ইন্টারেক্টিভ শেলগুলির জন্য প্রয়োজন, যা অন্যথায় নিরাপদে প্রত্যাখ্যান করে): ```bash omniroute contexts remove stg --yes ``` > `default` (লোকালহোস্ট) সরানো যাবে না। সক্রিয় প্রসঙ্গটি সরিয়ে দিলে `default`-এ ফিরে আসে। টিপস: একটি প্রসঙ্গ সরানো শুধুমাত্র **স্থানীয়ভাবে** সংরক্ষিত প্রমাণপত্র বাদ দেয় — অ্যাক্সেস সম্পূর্ণরূপে বন্ধ করতে `omniroute tokens revoke ` ব্যবহার করে সার্ভারে টোকেনটি বাতিল করুন। **প্রসঙ্গগুলি এক্সপোর্ট / ইম্পোর্ট করুন** (যেমন, সেগুলিকে মেশিনগুলির মধ্যে সরানোর জন্য)। এক্সপোর্টগুলি ডিফল্টরূপে প্রমাণপত্র বাদ দেয়, ফাইল ফলব্যাক দ্বারা সংরক্ষিত প্রমাণপত্র সহ। যখন একটি পোর্টেবল প্রমাণপত্র-বহনকারী ব্যাকআপের প্রয়োজন হয় তখন স্পষ্টভাবে `--include-secrets` ব্যবহার করুন: ```bash omniroute contexts export --out contexts.json # সংশোধিত; ডিফল্ট গন্তব্য: stdout omniroute contexts export --include-secrets --out private-contexts.json omniroute contexts import contexts.json # ওভাররাইট করুন; বিদ্যমান রাখতে --merge omniroute contexts migrate --yes # লিগ্যাসি প্লেইনটেক্সট টোকেনগুলি কিচেইনে সরান ``` `--include-secrets` এক্সপোর্ট করার আগে কিচেইন রেফারেন্সগুলি সমাধান করে এবং যদি কোনো রেফারেন্স করা প্রমাণপত্র পড়া না যায় তবে ব্যর্থ হয়। `--no-secrets` সর্বদা অগ্রাধিকার পায়। এক্সপোর্ট ফাইলগুলি `0600` মোডে অ্যাটমিকভাবে লেখা হয়। একটি সুস্পষ্ট গোপনীয়তা-বহনকারী এক্সপোর্টকে গোপনীয় উপাদান হিসাবে বিবেচনা করুন। ব্যবহারযোগ্য ওএস কিচেইন ছাড়া হেডলেস সিস্টেমে, CLI `0600` মোড সহ `config.json`-এ ফিরে আসে এবং একটি এককালীন সতর্কতা প্রিন্ট করে; এই মোডে একটি ডিফল্ট এক্সপোর্ট সংশোধিত থাকে। --- ## দ্রুত শুরু-থেকে-শেষ যাচাই শূন্য থেকে একটি দূরবর্তী সেটআপ যাচাই করার জন্য কপি-পেস্টযোগ্য lifecycle — সংযোগ করুন, একটি scoped token তৈরি করুন, একটি কমান্ড route করুন, ফিরে যান এবং সবকিছু সরিয়ে ফেলুন। `192.168.0.15`-এর জায়গায় আপনার সার্ভারের host/IP (Tailscale, LAN, অথবা একটি public `https://…` URL) দিন। ```bash # ১. সংযোগ করুন (password → admin token, এমন একটি context হিসেবে সংরক্ষিত যা সক্রিয় হয়ে যায়) omniroute connect 192.168.0.15 # অথবা: --key oma_live_xxxx (কোনো password নয়) omniroute contexts current # দূরবর্তী server + scope দেখায় # ২. এটি ব্যবহার করুন — management command-গুলো এখন দূরবর্তী server-এর বিপরীতে চলে omniroute tokens create --name laptop --scope read # আরও সীমিত একটি token তৈরি করুন omniroute tokens list # দূরবর্তী server থেকে masked list # ৩. সামনে-পেছনে পরিবর্তন করুন omniroute contexts use default # → স্থানীয় omniroute contexts use 192-168-0-15 # → আবার দূরবর্তী (`contexts list` থেকে পাওয়া নাম) # ৪. সরিয়ে ফেলুন। দ্রষ্টব্য: `contexts remove` কেবল স্থানীয় credential মুছে দেয় — # এটি server-এর token প্রত্যাহার করে না। বাস্তবে access বন্ধ করতে চাইলে প্রথমে # server-side থেকে প্রত্যাহার করুন। omniroute tokens revoke # server-এর access বন্ধ করে omniroute contexts remove 192-168-0-15 --yes # স্থানীয় context সরান (সক্রিয় হলেও → default-এ ফিরে যায়), কোনো prompt নেই ``` > `--yes`, `contexts remove`-কে non-interactive করে (scripts/CI-তে আবশ্যক; এটি ছাড়া > কোনো non-interactive shell আটকে থাকার পরিবর্তে নিরাপদভাবে প্রত্যাখ্যান করে)। **সক্রিয়** > context সরালে স্বয়ংক্রিয়ভাবে `default`-এ ফিরে যায়। --- ## নিরাপত্তা সংক্রান্ত নোট - টোকেনের প্লেইনটেক্সট একবারই দেখানো হয়; শুধুমাত্র SHA-256 হ্যাশ সংরক্ষণ করা হয় (API কীগুলোর মতোই)। - `omniroute connect` লগইনের ব্রুট-ফোর্স লকআউট + অডিট লগিং পুনরায় ব্যবহার করে। - পরিবহনের জন্য HTTPS বা একটি Tailnet ব্যবহার করাই শ্রেয়; LAN/Tailscale-এর সুবিধার্থে শুধু একটি হোস্ট দিলে তা ডিফল্টভাবে `http://` ব্যবহার করে — TLS-এর জন্য একটি পূর্ণ `https://…` URL দিন। - পছন্দের স্থানীয় কনটেক্সট ফাইল হলো `~/.omniroute/config.json` (`chmod 600`), যাতে শুধুমাত্র একটি `credentialRef` থাকে; টোকেনটি নিজে OS কীচেইনে (`keytar`) সংরক্ষিত থাকে এবং কখনোই লগে প্রিন্ট করা হয় না। কার্যকর নেটিভ কীচেইনবিহীন হেডলেস ইনস্টলেশনগুলো স্পষ্ট ফলব্যাক হিসেবে একই `0600` ফাইল ব্যবহার করে এবং একবার একটি সতর্কতা দেখায়। একটি কীচেইন ব্যাকএন্ড ইনস্টল করার পর `omniroute contexts migrate --yes` ব্যবহার করুন। --- ## API endpoints (রেফারেন্স) | Method | Route | Auth | Scope | | ------ | --------------------- | -------------------------- | --------------------------------- | | POST | `/api/cli/connect` | পাসওয়ার্ড; চালু থাকলে 2FA | — (সর্বজনীন, পাসওয়ার্ড-সুরক্ষিত) | | GET | `/api/cli/whoami` | অ্যাক্সেস টোকেন | read | | GET | `/api/cli/tokens` | অ্যাক্সেস টোকেন | admin | | POST | `/api/cli/tokens` | অ্যাক্সেস টোকেন | admin | | DELETE | `/api/cli/tokens/:id` | অ্যাক্সেস টোকেন | admin | সম্পূর্ণ স্কিমার জন্য [openapi.yaml](../openapi.yaml) দেখুন।