अनुवाद
blume translate एक AI एजेंट की मदद से आपके लोकेल भरता है — यह हर भाषा में गायब या पुराने पेज ढूँढता है, उन्हें आपके पास पहले से मौजूद एजेंट CLI से अनुवादित करता है, और CI को एक ऐसा गेट देता है जो अनुवादों के पिछड़ने पर विफल हो जाता है।
i18n चालू होने के बाद, स्रोत पेज में किया गया हर संपादन चुपचाप उसके अनुवादों को पुराना कर देता है। blume translate इस कमी को पूरा करता है: यह ठीक-ठीक गणना करता है कि हर लोकेल में कौन-से पेज गायब या पुराने हैं, उन्हें एक स्थानीय एजेंट CLI से हेडलेस तरीके से अनुवादित करता है, और जो कुछ किया गया उसे एक कमिट किए गए लेजर में दर्ज करता है, ताकि अगला रन — और CI — जान सके कि क्या अद्यतन है।
blume translate --codex
blume translate 3 item(s) · 2 locale(s) · Codex
✔ docs/guides/install.mdx → fr 24.2s
✔ docs/guides/install.mdx → de 22.8s
✔ meta titles (2) → de 4.1s
Translated 3 files into 2 locales · 1 adopted · 14 already up to date · 51.1s
यह कैसे काम करता है
पाइपलाइन Blume के नियंत्रण में रहती है; एजेंट केवल टेक्स्ट का अनुवाद करता है। जिस भी फ़ाइल पर काम करना हो, उसके लिए Blume एक अनुवाद प्रॉम्प्ट तैयार करता है, एजेंट CLI को उसके फ़ाइल, शेल और वेब टूल अक्षम करके हेडलेस रूप से चलाता है, उत्तर की संरचना को सत्यापित करता है, और लक्ष्य फ़ाइल स्वयं लिखता है — --codex के साथ Codex, या --claude के साथ Claude Code। Blume न तो कोई API कुंजी रखता है और न ही स्वयं किसी मॉडल को कॉल करता है।
हर सत्यापित लेखन प्रोजेक्ट रूट पर स्थित blume.translations.json में दर्ज होता है: हर स्रोत फ़ाइल और लोकेल के लिए, अनुवाद के समय स्रोत का एक हैश। इस फ़ाइल को कमिट करें। इसी के ज़रिए दोबारा चलाए गए रन को “पहले से अनुवादित” और “अनुवादित, लेकिन तब से स्रोत बदल गया है” के बीच का अंतर पता चलता है — और यही CI गेट को संभव बनाता है।
हर फ़ाइल पूरी होने के बाद लेजर सहेज दिया जाता है, इसलिए किसी लंबे रन को रोकने (Ctrl+C) पर अधिक से अधिक वही अनुवाद खोते हैं जो उस समय चल रहे थे — अगला रन वहीं से शुरू होता है जहाँ आपने छोड़ा था। डिफ़ॉल्ट रूप से एक साथ 4 फ़ाइलें चलती हैं; यदि आपकी मशीन और एजेंट की रेट लिमिट अनुमति दें, तो --concurrency से इसे बढ़ाएँ।
दोबारा चलाए गए रन इंक्रीमेंटल होते हैं: जो स्रोत अपने पिछले अनुवाद के बाद से नहीं बदला, उसे छोड़ दिया जाता है, इसलिए एक पेज संपादित करने के बाद blume translate चलाने पर हर लोकेल में केवल एक पेज अनुवादित होता है। जब किसी पुराने पेज का दोबारा अनुवाद किया जाता है, तो एजेंट को मौजूदा अनुवाद दिखाया जाता है और उसकी भाषा-शैली, बोली और शब्दावली से मेल खाने को कहा जाता है — स्रोत में एक अनुच्छेद का संपादन अनुवाद में भी केवल एक अनुच्छेद का अंतर (diff) पैदा करता है, शुरुआत से पूरा पुनर्लेखन नहीं।
पहले अनुवाद के पास मेल खाने के लिए कोई पूर्व उदाहरण नहीं होता, इसलिए लोकेल पर style के ज़रिए यह चुनाव पहले से तय कर दें ({ code: "pt", label: "Português", style: "Brazilian Portuguese, informal você" })। यह निर्देश हर अनुवाद प्रॉम्प्ट के साथ भेजा जाता है, और जहाँ कोई मौजूदा अनुवाद इससे असहमत हो, वहाँ style को प्राथमिकता मिलती है — इसलिए दोबारा अनुवाद पुराने पेजों को भी धीरे-धीरे कॉन्फ़िगर की गई शैली की ओर ले जाता है।
किन चीज़ों का अनुवाद होता है
- पेज — डिफ़ॉल्ट लोकेल की
.md/.mdxफ़ाइलें। एजेंट गद्य का और केवल मनुष्यों को दिखने वाले फ्रंटमैटर मानों (title,description,sidebar.label,sidebar.badge,seo.title,seo.description) का अनुवाद करता है। लक्ष्य फ़ाइलें आपके पार्सर का अनुसरण करती हैं:dirके अंतर्गतfr/guides/install.mdx, औरdotके अंतर्गतguides/install.fr.mdx। जो अनुवाद पहले से मौजूद है, उसे वहीं दोबारा लिखा जाता है जहाँ वह स्थित है, भले ही उसका नाम अलग हो (जैसे हाथ से लिखी गईfr/guides/install.md), ताकि दोबारा अनुवाद करने पर पेज की कोई दूसरी प्रति कभी न जुड़े। - फ़ोल्डर नेविगेशन शीर्षक —
dirपार्सर के अंतर्गत, हर लोकेल के लिए आवश्यकmeta.tsशीर्षकों का अनुवाद एक ही बैच कॉल में किया जाता है, और हर लोकेल के लिए जनरेट की गईmeta.tsबाकी सभी कुंजियों (order,pages,icon,collapsed) को ज्यों का त्यों कॉपी करती है, ताकि उस लोकेल का साइडबार अपना क्रम बनाए रखे। इसे लोकेल के उसी फ़ोल्डर में रखा जाता है जैसा वह डिस्क पर मौजूद है (कॉन्फ़िगर किए गएpt-BRके लिएpt-br/), और यदि वहाँ पहले से कोईmeta.jsयाmeta.mjsमौजूद है, तो उसके बगल में एक नईmeta.tsजोड़ने के बजाय उसी को दोबारा लिखा जाता है।
आपके द्वारा हाथ से लिखे गए अनुवाद अपना लिए जाते हैं, कभी ओवरराइट नहीं किए जाते: जो अनुवाद मौजूद है लेकिन जिसकी लेजर में कोई प्रविष्टि नहीं है, उसे अद्यतन के रूप में चिह्नित करके वैसे ही छोड़ दिया जाता है। केवल --force ही उसका दोबारा अनुवाद करता है।
सत्यापन
संरचना के मामले में एजेंट पर कभी भरोसा नहीं किया जाता। लिखने से पहले, Blume हर उत्तर की जाँच करता है और फ़ाइल को स्रोत से दोबारा बनाता है:
- फ्रंटमैटर को स्रोत फ़ाइल के डेटा से दोबारा बनाया जाता है, और उस पर केवल छह अनुवाद-योग्य मान रखे जाते हैं — एजेंट द्वारा गढ़ी गई कुंजियाँ हटा दी जाती हैं, उसके द्वारा हटाई गई कुंजियाँ बहाल कर दी जाती हैं, और
slug,icon,orderतथा तिथियाँ इस बनावट के कारण हमेशा हूबहू स्रोत जैसी रहती हैं। seo.canonicalस्रोत की एकमात्र कुंजी है जिसे शामिल नहीं किया जाता। यह स्रोत भाषा के किसी पेज की ओर इंगित करती है, और जिस अनुवाद का कैनोनिकल किसी दूसरी भाषा के पेज की ओर इंगित करता है, वह अपनी ही भाषा की खोज से बाहर हो जाता है, इसलिए अनुवाद को डिफ़ॉल्ट कैनोनिकल — यानी उसका अपना URL — मिलता है।- कोड फ़ेंस की संख्या स्रोत से मेल खानी चाहिए, बॉडी खाली नहीं होनी चाहिए, और फ्रंटमैटर पार्स होना चाहिए।
- हर हेडिंग को अंत में लगे
[#id]मार्कर के ज़रिए उसकी स्रोत हेडिंग की एंकर id से पिन कर दिया जाता है, जब तक कि अनुवाद में पहले से कोई पिन न हो, ताकि#fragmentलिंक हर भाषा में एक जैसे रिज़ॉल्व हों। हेडिंग्स का मिलान उनकी स्थिति के आधार पर होता है, इसलिए जिस अनुवाद की हेडिंग संरचना स्रोत से मेल नहीं खाती, उसे कोई पिन नहीं मिलता।
सत्यापन में विफल होने वाला उत्तर कुछ भी नहीं लिखता — उस आइटम को विफल के रूप में रिपोर्ट किया जाता है और रन आगे बढ़ जाता है। जो कुछ सफल हुआ, वह लेजर में दर्ज रहता है, इसलिए दोबारा चलाने पर केवल विफल आइटम ही फिर से आज़माए जाते हैं।
CI को विफल करना
blume translate --check केवल-पढ़ने वाला (read-only) गेट है: यह हर गायब और पुराने जोड़े की रिपोर्ट करता है और विचलन (drift) होने पर नॉन-ज़ीरो कोड के साथ बाहर निकलता है, बिना कोई एजेंट चलाए या कुछ भी लिखे।
blume translate --check # exit 1 when translations are missing or stale
blume translate --check --json # machine-readable drift report on stdout
- run: npx blume translate --check
JSON रिपोर्ट का diagnostics + summary स्वरूप वही है जो blume validate --json, blume audit --json और blume eval --json का है, और इसमें विचलन को लोकेल के अनुसार समूहित किया जाता है। हर गायब या पुराना अनुवाद एक त्रुटि डायग्नोस्टिक (BLUME_TRANSLATE_MISSING, BLUME_TRANSLATE_STALE) होता है, इसलिए summary.error एग्ज़िट कोड से मेल खाता है। हाथ से लिखे गए (अनट्रैक्ड) अनुवाद कभी भी गेट को विफल नहीं करते।
सीमाएँ
- मेटा शीर्षकों का अनुवाद केवल
dirपार्सर के साथ होता है —dotपार्सर में प्रति-लोकेलmeta.tsकी कोई व्यवस्था नहीं है। जोmeta.tsडिफ़ॉल्ट रूप से कोई फ़ंक्शन एक्सपोर्ट करती है, उसे एक चेतावनी के साथ छोड़ दिया जाता है; उस लोकेल की प्रति आप स्वयं हाथ से लिखें। - रिमोट और CMS-आधारित स्रोत छोड़ दिए जाते हैं: उनके लिए अनुवाद लिखने हेतु कोई स्थानीय फ़ाइल नहीं होती।
- हेडर टैब लेबल सामग्री में नहीं, बल्कि
blume.config.tsमें रहते हैं — उन्हें वहीं प्रति-लोकेल लेबल मैप के ज़रिए स्थानीयकृत करें। - अनुवाद की गुणवत्ता एजेंट पर निर्भर करती है। आउटपुट की समीक्षा किसी भी अन्य योगदान की तरह करें — लेजर केवल ताज़गी की गारंटी देता है, भाषा की सहजता की नहीं।
फ़्लैग
--codex/--claude— अनुवाद करने वाला एजेंट CLI। इनमें से ठीक एक आवश्यक है, सिवाय--checkके, जो कोई एजेंट नहीं चलाता और इनमें से कोई भी फ़्लैग नहीं लेता।--check— कुछ भी लिखे बिना विचलन की रिपोर्ट करता है और नॉन-ज़ीरो कोड के साथ बाहर निकलता है।--concurrency <n>— समानांतर एजेंट सत्र। डिफ़ॉल्ट4, अधिकतम16।--locale <codes>— अल्पविराम से अलग किए गए लक्ष्य लोकेल (डिफ़ॉल्ट रूप से हर गैर-डिफ़ॉल्ट लोकेल)।--force— अद्यतन और हाथ से लिखी गई फ़ाइलों सहित, सब कुछ दोबारा अनुवादित करता है।--timeout <seconds>— प्रति फ़ाइल एजेंट की समय-सीमा। डिफ़ॉल्ट600; यह ऊपरी सीमा अटके हुए एजेंटों को पकड़ने के लिए है, इसलिए बड़े पेजों को पूरा होने के लिए पर्याप्त समय मिलता है। अधिकतम2147483(लगभग 24 दिन), जो किसी टाइमर की सबसे लंबी प्रतीक्षा अवधि है।--json— दोनों मोड में, रिपोर्ट को stdout पर JSON के रूप में आउटपुट करता है।