@cachly-dev/mcp-server 0.5.49 → 0.5.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -3
- package/dist/index.js +201 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +186 -39
package/dist/index.d.ts
CHANGED
|
@@ -33,9 +33,11 @@ declare function expandCrossLingual(token: string): string[];
|
|
|
33
33
|
* Features:
|
|
34
34
|
* • CJK → character bigrams
|
|
35
35
|
* • Katakana → additionally emits Hepburn romaji tokens (enables romaji queries)
|
|
36
|
-
* • Arabic
|
|
37
|
-
* • Hebrew
|
|
38
|
-
* •
|
|
36
|
+
* • Arabic → word tokenization + iterative prefix stemming (ال/و/ب/ل/ف/ك)
|
|
37
|
+
* • Hebrew → word tokenization + iterative prefix stemming (ה/ו/ב/ל/מ/כ)
|
|
38
|
+
* • Farsi → word tokenization + suffix/prefix stemming (ها/های plural, می prefix)
|
|
39
|
+
* • Hindi → Devanagari word tokenization + light suffix stemming
|
|
40
|
+
* • All scripts → cross-lingual synonym expansion (EN↔JA↔ZH↔KO↔AR↔HE↔FA↔HI↔DE↔FR↔ES↔IT↔PT)
|
|
39
41
|
*/
|
|
40
42
|
declare function tokenize(text: string): string[];
|
|
41
43
|
/**
|
package/dist/index.js
CHANGED
|
@@ -47,7 +47,7 @@ import { Redis } from 'ioredis';
|
|
|
47
47
|
const API_URL = process.env.CACHLY_API_URL ?? 'https://api.cachly.dev';
|
|
48
48
|
const JWT = process.env.CACHLY_JWT ?? '';
|
|
49
49
|
const EMBED_MODEL = process.env.CACHLY_EMBED_MODEL ?? '';
|
|
50
|
-
const CURRENT_VERSION = '0.5.
|
|
50
|
+
const CURRENT_VERSION = '0.5.50';
|
|
51
51
|
/**
|
|
52
52
|
* ┌──────────────────────────────────────────────────────────────────────┐
|
|
53
53
|
* │ EMBEDDING PROVIDER — pluggable, client-side first │
|
|
@@ -403,6 +403,23 @@ const STOPWORDS = new Set([
|
|
|
403
403
|
'רק', 'עוד', 'יש', 'אין', 'מה', 'זה', 'זאת', 'אלה', 'כל', 'כן',
|
|
404
404
|
'לו', 'לה', 'להם', 'בו', 'בה', 'בהם', 'שם', 'כך', 'כן', 'מי',
|
|
405
405
|
'אשר', 'אחרי', 'לפני', 'תחת', 'בין', 'מאז', 'עד', 'כמו', 'אז',
|
|
406
|
+
// ── Farsi/Persian — common function words, prepositions, pronouns ──
|
|
407
|
+
'در', 'از', 'به', 'با', 'که', 'این', 'آن', 'را', 'است',
|
|
408
|
+
'بود', 'باشد', 'شد', 'شده', 'می', 'نه', 'نیست', 'هم', 'هر',
|
|
409
|
+
'یک', 'اما', 'و', 'یا', 'تا', 'اگر', 'برای', 'چون', 'چه',
|
|
410
|
+
'کجا', 'کی', 'چطور', 'وقتی', 'بعد', 'قبل', 'مثل', 'همه', 'بعضی',
|
|
411
|
+
'هیچ', 'آیا', 'خود', 'چند', 'دیگر', 'هنوز', 'همان', 'آنها', 'اینها',
|
|
412
|
+
'ما', 'شما', 'آنان', 'من', 'تو', 'او', 'آنان', 'ایشان',
|
|
413
|
+
'روی', 'زیر', 'بین', 'پیش', 'پس', 'طرف', 'داخل', 'خارج', 'کنار',
|
|
414
|
+
'همچنین', 'مگر', 'ولی', 'وگرنه', 'چرا', 'چگونه', 'کدام',
|
|
415
|
+
// ── Hindi — common particles, postpositions, pronouns, auxiliary verbs ──
|
|
416
|
+
'है', 'में', 'से', 'को', 'का', 'की', 'के', 'पर', 'और', 'या',
|
|
417
|
+
'नहीं', 'यह', 'वह', 'एक', 'इस', 'उस', 'भी', 'हो', 'था', 'थी',
|
|
418
|
+
'थे', 'हैं', 'हूँ', 'लिए', 'तक', 'साथ', 'बाद', 'पहले', 'जो',
|
|
419
|
+
'जब', 'कैसे', 'क्यों', 'क्या', 'कहाँ', 'कौन', 'हम', 'आप', 'वे',
|
|
420
|
+
'मैं', 'तुम', 'उन', 'इन', 'ने', 'बहुत', 'सब', 'कुछ', 'फिर',
|
|
421
|
+
'अब', 'तो', 'ही', 'तरह', 'जैसे', 'करना', 'होना', 'रहा', 'रही',
|
|
422
|
+
'रहे', 'गया', 'गई', 'गए', 'किया', 'किए', 'कर', 'हुआ', 'हुई',
|
|
406
423
|
]);
|
|
407
424
|
// CJK Unicode ranges used for bigram extraction
|
|
408
425
|
const CJK_RE = /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uac00-\ud7af]/;
|
|
@@ -412,7 +429,10 @@ const RTL_RE = /[\u0590-\u05ff\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb1d-\ufb
|
|
|
412
429
|
// Distinguish Arabic from Hebrew within RTL segments
|
|
413
430
|
const HEBREW_CHAR_RE = /[\u0590-\u05ff\ufb1d-\ufb4f]/;
|
|
414
431
|
const ARABIC_CHAR_RE = /[\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb50-\ufdff\ufe70-\ufeff]/;
|
|
415
|
-
|
|
432
|
+
// Persian/Farsi: exclusive chars not in Arabic (U+067E=پ, U+0686=چ, U+0698=ژ, U+06AF=گ, U+06CC=ی)
|
|
433
|
+
const FARSI_CHAR_RE = /[\u067e\u0686\u0698\u06af\u06cc]/;
|
|
434
|
+
// Devanagari (Hindi, Sanskrit, Marathi …) — U+0900–U+097F + extended
|
|
435
|
+
const DEVANAGARI_RE = /[\u0900-\u097f]/;
|
|
416
436
|
// ── Katakana → Romaji conversion table (Hepburn system) ──────────────────────
|
|
417
437
|
// Digraphs must be listed before single chars so they match first.
|
|
418
438
|
const KATA_ROMAJI_TABLE = [
|
|
@@ -540,7 +560,59 @@ function hebrewLightStem(word) {
|
|
|
540
560
|
}
|
|
541
561
|
return result;
|
|
542
562
|
}
|
|
543
|
-
|
|
563
|
+
/**
|
|
564
|
+
* Farsi/Persian light stemmer — handles Persian morphology.
|
|
565
|
+
* Strips:
|
|
566
|
+
* \u0647\u0627 / \u0647\u0627\u06cc (ha/haye) — plural suffixes: \u0633\u0631\u0648\u0631\u0647\u0627 \u2192 \u0633\u0631\u0648\u0631
|
|
567
|
+
* \u0645\u06cc\u200c / \u0645\u06cc (mi-) — present-tense prefix: \u0645\u06cc\u200c\u06a9\u0646\u062f \u2192 \u06a9\u0646\u062f
|
|
568
|
+
* \u0646\u0645\u06cc\u200c (nami-) — negated present: \u0646\u0645\u06cc\u200c\u0634\u0648\u062f \u2192 \u0634\u0648\u062f
|
|
569
|
+
* Only strips when the result is still \u2265 3 chars.
|
|
570
|
+
*/
|
|
571
|
+
function farsiLightStem(word) {
|
|
572
|
+
let result = word;
|
|
573
|
+
// Suffixes first (longest first)
|
|
574
|
+
if (result.endsWith('\u0647\u0627\u06cc') && result.length > 5)
|
|
575
|
+
result = result.slice(0, -3);
|
|
576
|
+
else if (result.endsWith('\u0647\u0627') && result.length > 4)
|
|
577
|
+
result = result.slice(0, -2);
|
|
578
|
+
// Prefixes
|
|
579
|
+
if (result.startsWith('\u0646\u0645\u06cc\u200c') && result.length > 5)
|
|
580
|
+
result = result.slice(4);
|
|
581
|
+
else if (result.startsWith('\u0645\u06cc\u200c') && result.length > 4)
|
|
582
|
+
result = result.slice(3);
|
|
583
|
+
else if (result.startsWith('\u0645\u06cc') && result.length > 4)
|
|
584
|
+
result = result.slice(2);
|
|
585
|
+
return result;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Hindi light stemmer — strips the most common inflectional suffixes.
|
|
589
|
+
* Handles basic verb forms and oblique plural markers.
|
|
590
|
+
* Avoids over-stemming loanwords (most tech terms in Hindi are English loanwords).
|
|
591
|
+
* Only strips when result is still \u2265 3 chars.
|
|
592
|
+
*/
|
|
593
|
+
function hindiLightStem(word) {
|
|
594
|
+
const result = word;
|
|
595
|
+
// Infinitive / verb suffixes (longest first to avoid partial match)
|
|
596
|
+
if (result.endsWith('\u0928\u093e') && result.length > 4)
|
|
597
|
+
return result.slice(0, -2); // \u0928\u093e (nā) infinitive
|
|
598
|
+
if (result.endsWith('\u0928\u0947') && result.length > 4)
|
|
599
|
+
return result.slice(0, -2); // \u0928\u0947 (ne) ergative
|
|
600
|
+
if (result.endsWith('\u0928\u0940') && result.length > 4)
|
|
601
|
+
return result.slice(0, -2); // \u0928\u0940 (nī) fem infinitive
|
|
602
|
+
if (result.endsWith('\u0924\u093e') && result.length > 4)
|
|
603
|
+
return result.slice(0, -2); // \u0924\u093e (tā) m present participle
|
|
604
|
+
if (result.endsWith('\u0924\u0940') && result.length > 4)
|
|
605
|
+
return result.slice(0, -2); // \u0924\u0940 (tī) f present participle
|
|
606
|
+
if (result.endsWith('\u0915\u0930') && result.length > 4)
|
|
607
|
+
return result.slice(0, -2); // \u0915\u0930 (kar) conjunctive
|
|
608
|
+
if (result.endsWith('\u0913\u0902') && result.length > 4)
|
|
609
|
+
return result.slice(0, -2); // \u0913\u0902 (oṃ) oblique plural
|
|
610
|
+
if (result.endsWith('\u0907\u092f\u093e\u0902') && result.length > 5)
|
|
611
|
+
return result.slice(0, -4); // \u0907\u092f\u093e\u0902 (iyāṃ) f plural
|
|
612
|
+
if (result.endsWith('\u0940\u092f\u093e\u0902') && result.length > 5)
|
|
613
|
+
return result.slice(0, -4); // \u0940\u092f\u093e\u0902 (īyāṃ)
|
|
614
|
+
return result;
|
|
615
|
+
}
|
|
544
616
|
// Maps tokens (English, Japanese katakana, Chinese, Korean, Arabic, Hebrew)
|
|
545
617
|
// to their equivalents in other languages. Used to expand tokens at search time
|
|
546
618
|
// so "deploy" finds documents containing "デプロイ" / "部署" / "배포", and vice versa.
|
|
@@ -548,30 +620,30 @@ function hebrewLightStem(word) {
|
|
|
548
620
|
// Keys must be lowercase. CJK values will be bigram-expanded at use time.
|
|
549
621
|
const CROSS_LINGUAL_MAP = new Map([
|
|
550
622
|
// English → all
|
|
551
|
-
['deploy', ['デプロイ', '部署', '배포', 'deployment', 'deploying', 'نشر', 'פריסה', 'bereitstellen', 'bereitstellung', 'déployer', 'déploiement', 'desplegar', 'despliegue', 'distribuire', 'distribuzione', 'implantar', 'implantação']],
|
|
552
|
-
['deployment', ['デプロイ', '部署', '배포', 'deploy', 'نشر', 'פריסה', 'bereitstellung', 'déploiement', 'despliegue', 'distribuzione', 'implantação']],
|
|
623
|
+
['deploy', ['デプロイ', '部署', '배포', 'deployment', 'deploying', 'نشر', 'פריסה', 'استقرار', 'तैनाती', 'bereitstellen', 'bereitstellung', 'déployer', 'déploiement', 'desplegar', 'despliegue', 'distribuire', 'distribuzione', 'implantar', 'implantação']],
|
|
624
|
+
['deployment', ['デプロイ', '部署', '배포', 'deploy', 'نشر', 'פריסה', 'استقرار', 'तैनाती', 'bereitstellung', 'déploiement', 'despliegue', 'distribuzione', 'implantação']],
|
|
553
625
|
['container', ['コンテナ', '容器', '컨테이너', 'docker']],
|
|
554
|
-
['server', ['サーバー', 'サーバ', '服务器', '서버', 'سيرفر', 'שרת']],
|
|
555
|
-
['database', ['データベース', '数据库', '데이터베이스', 'db', 'قاعدة البيانات', 'datenbank', 'base de données', 'base de datos', 'banco de dados']],
|
|
556
|
-
['cache', ['キャッシュ', '缓存', '캐시', 'كاش', 'מטמון']],
|
|
557
|
-
['error', ['エラー', '错误', '오류', 'خطأ', '
|
|
558
|
-
['bug', ['バグ', '缺陷', '버그', 'issue', 'defect', 'خلل']],
|
|
559
|
-
['fix', ['修正', '修复', '수정', 'bugfix', 'patch', 'hotfix', 'إصلاح', 'תיקון', 'beheben', 'behoben', 'réparer', 'correction', 'arreglar', 'corrección', 'correggere', 'corrigir']],
|
|
560
|
-
['build', ['ビルド', '构建', '빌드', 'بناء', 'בנייה', 'bauen', 'construire', 'construir', 'costruire']],
|
|
561
|
-
['test', ['テスト', '测试', '테스트', 'اختبار', 'בדיקה', 'testen', 'tester', 'probar', 'testare', 'testar']],
|
|
562
|
-
['auth', ['認証', '认证', '인증', 'authentication', 'login', 'oauth', 'مصادقة', 'אימות', 'authentifizierung', 'authentification', 'autenticación', 'autenticazione', 'autenticação']],
|
|
563
|
-
['authentication', ['auth', 'مصادقة', 'אימות', '認証', '认证', '인증', 'login', 'oauth']],
|
|
626
|
+
['server', ['サーバー', 'サーバ', '服务器', '서버', 'سيرفر', 'שרת', 'سرور', 'सर्वर']],
|
|
627
|
+
['database', ['データベース', '数据库', '데이터베이스', 'db', 'قاعدة البيانات', 'datenbank', 'پایگاه داده', 'डेटाबेس', 'base de données', 'base de datos', 'banco de dados']],
|
|
628
|
+
['cache', ['キャッシュ', '缓存', '캐시', 'كاش', 'מטמון', 'کش', 'कैश']],
|
|
629
|
+
['error', ['エラー', '错误', '오류', 'خطأ', 'شגיאה', 'خطا', 'त्रुटि', 'गलती', 'exception', 'err', 'fehler', 'erreur', 'fallo', 'errore', 'erro']],
|
|
630
|
+
['bug', ['バグ', '缺陷', '버그', 'issue', 'defect', 'خلل', 'اشکال', 'बग']],
|
|
631
|
+
['fix', ['修正', '修复', '수정', 'bugfix', 'patch', 'hotfix', 'إصلاح', 'תיקון', 'رفع', 'सुधार', 'beheben', 'behoben', 'réparer', 'correction', 'arreglar', 'corrección', 'correggere', 'corrigir']],
|
|
632
|
+
['build', ['ビルド', '构建', '빌드', 'بناء', 'בנייה', 'ساخت', 'निर्माण', 'bauen', 'construire', 'construir', 'costruire']],
|
|
633
|
+
['test', ['テスト', '测试', '테스트', 'اختبار', 'בדיקה', 'آزمایش', 'परीक्षण', 'testen', 'tester', 'probar', 'testare', 'testar']],
|
|
634
|
+
['auth', ['認証', '认证', '인증', 'authentication', 'login', 'oauth', 'مصادقة', 'אימות', 'احراز هویت', 'प्रमाणीकरण', 'authentifizierung', 'authentification', 'autenticación', 'autenticazione', 'autenticação']],
|
|
635
|
+
['authentication', ['auth', 'مصادقة', 'אימות', 'احراز هویت', 'प्रमाणीकरण', '認証', '认证', '인증', 'login', 'oauth']],
|
|
564
636
|
['environment', ['環境', '环境', '환경', 'env', 'بيئة', 'סביבה', 'umgebung', 'environnement', 'entorno', 'ambiente']],
|
|
565
637
|
['secret', ['key', 'token', 'password', 'jwt', 'مفتاح', 'מפתח', 'geheimnis', 'schlüssel', 'clave', 'clé', 'chiave', 'chave']],
|
|
566
638
|
['problem', ['error', 'issue', 'bug', 'failure', 'مشكلة', 'بعيا', '問題', '問題', '오류', 'fehler', 'problème', 'problema']],
|
|
567
639
|
['kubernetes', ['クベルネテス', 'k8s', 'kube']],
|
|
568
|
-
['network', ['ネットワーク', '网络', '네트워크', 'شبكة', 'רשת', 'netzwerk', 'réseau', 'red', 'rete', 'rede']],
|
|
640
|
+
['network', ['ネットワーク', '网络', '네트워크', 'شبكة', 'רשת', 'شبکه', 'नेटवर्क', 'netzwerk', 'réseau', 'red', 'rete', 'rede']],
|
|
569
641
|
['timeout', ['タイムアウト', '超时', '타임아웃', 'مهلة']],
|
|
570
|
-
['memory', ['メモリ', '内存', '메모리', 'ram', 'ذاكرة', 'זיכרון', 'speicher', 'mémoire', 'memoria', 'memória']],
|
|
571
|
-
['config', ['設定', '配置', '설정', 'configuration', 'settings', 'conf', 'إعدادات', 'הגדרות', 'konfiguration', 'einstellungen', 'configuración', 'configurazione', 'configuração']],
|
|
572
|
-
['install', ['インストール', '安装', '설치', 'تثبيت', 'התקנה', 'installieren', 'installer', 'instalar', 'installare']],
|
|
573
|
-
['update', ['アップデート', '更新', '업데이트', 'upgrade', 'تحديث', 'עדכון', 'aktualisieren', 'aktualisierung', 'actualizar', 'aggiornare', 'atualizar']],
|
|
574
|
-
['log', ['ログ', '日志', '로그', 'logging', 'سجل', 'יומן', 'protokoll', 'protokolle', 'journal', 'registro']],
|
|
642
|
+
['memory', ['メモリ', '内存', '메모리', 'ram', 'ذاكرة', 'זיכרון', 'حافظه', 'मेमोरी', 'speicher', 'mémoire', 'memoria', 'memória']],
|
|
643
|
+
['config', ['設定', '配置', '설정', 'configuration', 'settings', 'conf', 'إعدادات', 'הגדרות', 'پیکربندی', 'कॉन्फ़िग', 'konfiguration', 'einstellungen', 'configuración', 'configurazione', 'configuração']],
|
|
644
|
+
['install', ['インストール', '安装', '설치', 'تثبيت', 'התקנה', 'نصب', 'इंस्टॉल', 'installieren', 'installer', 'instalar', 'installare']],
|
|
645
|
+
['update', ['アップデート', '更新', '업데이트', 'upgrade', 'تحديث', 'עדכון', 'بهروزرسانی', 'अपडेट', 'aktualisieren', 'aktualisierung', 'actualizar', 'aggiornare', 'atualizar']],
|
|
646
|
+
['log', ['ログ', '日志', '로그', 'logging', 'سجل', 'יומן', 'ثبت', 'लॉग', 'protokoll', 'protokolle', 'journal', 'registro']],
|
|
575
647
|
['port', ['ポート', '端口', '포트', 'منفذ', 'פורט']],
|
|
576
648
|
['file', ['ファイル', '文件', '파일', 'ملف', 'קובץ']],
|
|
577
649
|
['image', ['イメージ', '镜像', '이미지', 'صورة', 'תמונה', 'abbild', 'imagen', 'imagem']],
|
|
@@ -584,10 +656,10 @@ const CROSS_LINGUAL_MAP = new Map([
|
|
|
584
656
|
['token', ['トークン', '令牌', '토큰', 'jwt', 'secret', 'رمز', 'אסימון']],
|
|
585
657
|
['health', ['ヘルス', '健康', '헬스', 'healthcheck', 'probe', 'صحة']],
|
|
586
658
|
['migration', ['マイグレーション', '迁移', '마이그레이션', 'migrate', 'هجرة']],
|
|
587
|
-
['backup', ['バックアップ', '备份', '백업', 'نسخ احتياطي', 'גיבוי', 'sicherung', 'sauvegarde', 'respaldo', 'cópia de segurança']],
|
|
588
|
-
['monitor', ['モニター', '监控', '모니터링', 'monitoring', 'metrics', 'alert', 'مراقبة', 'ניטור', 'überwachung', 'surveiller', 'monitoreo', 'monitorare', 'monitorar']],
|
|
589
|
-
['performance', ['パフォーマンス', '性能', '성능', 'latency', 'throughput', 'leistung', 'performances', 'rendimiento', 'prestazioni', 'desempenho']],
|
|
590
|
-
['connection', ['接続', '连接', '연결', 'conn', 'socket', 'اتصال', 'חיבור', 'verbindung', 'connexion', 'conexión', 'connessione', 'conexão']],
|
|
659
|
+
['backup', ['バックアップ', '备份', '백업', 'نسخ احتياطي', 'גיבוי', 'پشتیبانگیری', 'बैकअप', 'sicherung', 'sauvegarde', 'respaldo', 'cópia de segurança']],
|
|
660
|
+
['monitor', ['モニター', '监控', '모니터링', 'monitoring', 'metrics', 'alert', 'مراقبة', 'ניטור', 'نظارت', 'निगरानी', 'überwachung', 'surveiller', 'monitoreo', 'monitorare', 'monitorar']],
|
|
661
|
+
['performance', ['パフォーマンス', '性能', '성능', 'latency', 'throughput', 'عملکرد', 'प्रदर्शन', 'leistung', 'performances', 'rendimiento', 'prestazioni', 'desempenho']],
|
|
662
|
+
['connection', ['接続', '连接', '연결', 'conn', 'socket', 'اتصال', 'חיבור', 'اتصال', 'कनेक्शन', 'verbindung', 'connexion', 'conexión', 'connessione', 'conexão']],
|
|
591
663
|
['queue', ['キュー', '队列', '큐', 'طابور', 'warteschlange', 'file d\'attente', 'cola', 'coda', 'fila']],
|
|
592
664
|
['redis', ['レディス', '레디스']],
|
|
593
665
|
['nginx', ['エンジンエックス']],
|
|
@@ -601,10 +673,10 @@ const CROSS_LINGUAL_MAP = new Map([
|
|
|
601
673
|
['git', ['version control', 'repo', 'repository', 'commit', 'push', 'pull']],
|
|
602
674
|
['ci', ['pipeline', 'github actions', 'gitlab', 'jenkins', 'build']],
|
|
603
675
|
['cd', ['deploy', 'deployment', 'release']],
|
|
604
|
-
['debug', ['デバッグ', '调试', '디버그', 'debugging', 'breakpoint', 'تصحيح', 'איתור באגים', 'debuggen', 'déboguer', 'depurar']],
|
|
605
|
-
['crash', ['クラッシュ', '崩溃', '크래시', 'panic', 'segfault', 'انهيار', 'קריסה', 'absturz', 'panne', 'plantage', 'caída', 'falha']],
|
|
606
|
-
['restart', ['再起動', '重启', '재시작', 'reboot', 'إعادة تشغيل', 'הפעלה מחדש', 'neustart', 'redémarrer', 'reiniciar', 'riavviare']],
|
|
607
|
-
['permission', ['権限', '权限', '권한', 'access', 'acl', 'chmod', 'صلاحية', 'הרשאה', 'berechtigung', 'berechtigungen', 'permiso', 'permesso', 'permissão']],
|
|
676
|
+
['debug', ['デバッグ', '调试', '디버그', 'debugging', 'breakpoint', 'تصحيح', 'איתור באגים', 'اشکالزدایی', 'डीबग', 'debuggen', 'déboguer', 'depurar']],
|
|
677
|
+
['crash', ['クラッシュ', '崩溃', '크래시', 'panic', 'segfault', 'انهيار', 'קריסה', 'خرابی', 'क्रैश', 'absturz', 'panne', 'plantage', 'caída', 'falha']],
|
|
678
|
+
['restart', ['再起動', '重启', '재시작', 'reboot', 'إعادة تشغيل', 'הפעלה מחדש', 'راهاندازی مجدد', 'पुنरारंभ', 'neustart', 'redémarrer', 'reiniciar', 'riavviare']],
|
|
679
|
+
['permission', ['権限', '权限', '권한', 'access', 'acl', 'chmod', 'صلاحية', 'הרשאה', 'مجوز', 'अनुमति', 'berechtigung', 'berechtigungen', 'permiso', 'permesso', 'permissão']],
|
|
608
680
|
// Japanese katakana → English
|
|
609
681
|
['デプロイ', ['deploy', 'deployment']],
|
|
610
682
|
['コンテナ', ['container', 'docker']],
|
|
@@ -790,6 +862,67 @@ const CROSS_LINGUAL_MAP = new Map([
|
|
|
790
862
|
['ייצור', ['production', 'prod']],
|
|
791
863
|
['סודי', ['secret', 'key', 'token']],
|
|
792
864
|
['מפתח סודי', ['secret', 'key']],
|
|
865
|
+
// ── Farsi/Persian → English ───────────────────────────────────────────────
|
|
866
|
+
['استقرار', ['deploy', 'deployment']],
|
|
867
|
+
['خطا', ['error', 'err']], // Farsi: خطا vs Arabic: خطأ
|
|
868
|
+
['اشکال', ['bug', 'issue', 'error']],
|
|
869
|
+
['رفع اشکال', ['fix', 'debug', 'debugging']],
|
|
870
|
+
['ساخت', ['build']],
|
|
871
|
+
['آزمایش', ['test']],
|
|
872
|
+
['احراز هویت', ['auth', 'authentication']],
|
|
873
|
+
['پیکربندی', ['config', 'configuration']],
|
|
874
|
+
['نصب', ['install']],
|
|
875
|
+
['بهروزرسانی', ['update', 'upgrade']],
|
|
876
|
+
['ثبت', ['log']],
|
|
877
|
+
['سرور', ['server']],
|
|
878
|
+
['پایگاه داده', ['database', 'db']],
|
|
879
|
+
['شبکه', ['network']], // Farsi شبکه vs Arabic شبكة
|
|
880
|
+
['حافظه', ['memory', 'ram']], // Farsi حافظه vs Arabic ذاكرة
|
|
881
|
+
['کش', ['cache']],
|
|
882
|
+
['اشکالزدایی', ['debug', 'debugging']],
|
|
883
|
+
['خرابی', ['crash', 'failure', 'error']],
|
|
884
|
+
['راهاندازی مجدد', ['restart', 'reboot']],
|
|
885
|
+
['مجوز', ['permission', 'access']],
|
|
886
|
+
['پشتیبانگیری', ['backup']],
|
|
887
|
+
['عملکرد', ['performance']],
|
|
888
|
+
['مشکل', ['problem', 'issue', 'error']],
|
|
889
|
+
['سرویس', ['service']],
|
|
890
|
+
['کلید', ['key', 'token', 'secret']],
|
|
891
|
+
['محیط', ['environment', 'env']],
|
|
892
|
+
['تولید', ['production', 'prod']],
|
|
893
|
+
['رمز', ['secret', 'key', 'token']],
|
|
894
|
+
['اتصال', ['connection', 'conn']],
|
|
895
|
+
// ── Hindi (Devanagari) → English ──────────────────────────────────────────
|
|
896
|
+
['तैनाती', ['deploy', 'deployment']],
|
|
897
|
+
['त्रुटि', ['error', 'err']],
|
|
898
|
+
['गलती', ['error', 'bug', 'issue']],
|
|
899
|
+
['सुधार', ['fix', 'bugfix']],
|
|
900
|
+
['निर्माण', ['build']],
|
|
901
|
+
['परीक्षण', ['test']],
|
|
902
|
+
['प्रमाणीकरण', ['auth', 'authentication']],
|
|
903
|
+
['विन्यास', ['config', 'configuration']],
|
|
904
|
+
['कॉन्फ़िगरेशन', ['config', 'configuration']],
|
|
905
|
+
['इंस्टॉल', ['install']],
|
|
906
|
+
['अपडेट', ['update', 'upgrade']],
|
|
907
|
+
['लॉग', ['log']],
|
|
908
|
+
['सर्वर', ['server']],
|
|
909
|
+
['डेटाबेस', ['database', 'db']],
|
|
910
|
+
['नेटवर्क', ['network']],
|
|
911
|
+
['मेमोरी', ['memory', 'ram']],
|
|
912
|
+
['कैश', ['cache']],
|
|
913
|
+
['डीबग', ['debug', 'debugging']],
|
|
914
|
+
['क्रैश', ['crash', 'panic']],
|
|
915
|
+
['पुनरारंभ', ['restart', 'reboot']],
|
|
916
|
+
['अनुमति', ['permission', 'access']],
|
|
917
|
+
['बैकअप', ['backup']],
|
|
918
|
+
['प्रदर्शन', ['performance']],
|
|
919
|
+
['समस्या', ['problem', 'issue', 'error']],
|
|
920
|
+
['सेवा', ['service']],
|
|
921
|
+
['कनेक्शन', ['connection', 'conn']],
|
|
922
|
+
['पासवर्ड', ['password']],
|
|
923
|
+
['टोकन', ['token', 'secret']],
|
|
924
|
+
['वातावरण', ['environment', 'env']],
|
|
925
|
+
['उत्पादन', ['production', 'prod']],
|
|
793
926
|
// ── European languages → English ─────────────────────────────────────────
|
|
794
927
|
// German (Deutsch) → English
|
|
795
928
|
['fehler', ['error', 'err']],
|
|
@@ -987,9 +1120,11 @@ function expandCrossLingual(token) {
|
|
|
987
1120
|
* Features:
|
|
988
1121
|
* • CJK → character bigrams
|
|
989
1122
|
* • Katakana → additionally emits Hepburn romaji tokens (enables romaji queries)
|
|
990
|
-
* • Arabic
|
|
991
|
-
* • Hebrew
|
|
992
|
-
* •
|
|
1123
|
+
* • Arabic → word tokenization + iterative prefix stemming (ال/و/ب/ل/ف/ك)
|
|
1124
|
+
* • Hebrew → word tokenization + iterative prefix stemming (ה/ו/ב/ל/מ/כ)
|
|
1125
|
+
* • Farsi → word tokenization + suffix/prefix stemming (ها/های plural, می prefix)
|
|
1126
|
+
* • Hindi → Devanagari word tokenization + light suffix stemming
|
|
1127
|
+
* • All scripts → cross-lingual synonym expansion (EN↔JA↔ZH↔KO↔AR↔HE↔FA↔HI↔DE↔FR↔ES↔IT↔PT)
|
|
993
1128
|
*/
|
|
994
1129
|
function tokenize(text) {
|
|
995
1130
|
const tokens = [];
|
|
@@ -1028,15 +1163,33 @@ function tokenize(text) {
|
|
|
1028
1163
|
}
|
|
1029
1164
|
}
|
|
1030
1165
|
else if (RTL_RE.test(seg)) {
|
|
1031
|
-
// RTL segment —
|
|
1032
|
-
// Arabic: strips ال/و/ب/ل/ف/ك prefixes iteratively
|
|
1033
|
-
// Hebrew: strips ה/ו/ב/ל/מ/כ prefixes iteratively
|
|
1034
|
-
const isHebrew = HEBREW_CHAR_RE.test(seg);
|
|
1166
|
+
// RTL segment — 3-way branch: Farsi / Hebrew / Arabic
|
|
1035
1167
|
const words = seg.trim().split(/\s+/);
|
|
1168
|
+
let stemFn;
|
|
1169
|
+
if (FARSI_CHAR_RE.test(seg))
|
|
1170
|
+
stemFn = farsiLightStem;
|
|
1171
|
+
else if (HEBREW_CHAR_RE.test(seg))
|
|
1172
|
+
stemFn = hebrewLightStem;
|
|
1173
|
+
else
|
|
1174
|
+
stemFn = arabicLightStem;
|
|
1036
1175
|
for (const w of words) {
|
|
1037
1176
|
if (w.length <= 1 || STOPWORDS.has(w))
|
|
1038
1177
|
continue;
|
|
1039
|
-
const stemmed =
|
|
1178
|
+
const stemmed = stemFn(w);
|
|
1179
|
+
if (stemmed.length > 1 && !STOPWORDS.has(stemmed))
|
|
1180
|
+
tokens.push(stemmed);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
else if (DEVANAGARI_RE.test(seg)) {
|
|
1184
|
+
// Devanagari segment (Hindi / Marathi) — naturally space-separated
|
|
1185
|
+
// Words don't need bigram expansion; stems reduce inflected forms.
|
|
1186
|
+
const words = seg.trim().split(/[\s\u200c\u200d]+/); // handle zero-width joiners
|
|
1187
|
+
for (const w of words) {
|
|
1188
|
+
// Keep Devanagari chars + digits; discard pure Latin portions (e.g. embedded numbers)
|
|
1189
|
+
const deva = w.replace(/[^\u0900-\u097f0-9]/g, '');
|
|
1190
|
+
if (deva.length <= 1 || STOPWORDS.has(deva))
|
|
1191
|
+
continue;
|
|
1192
|
+
const stemmed = hindiLightStem(deva);
|
|
1040
1193
|
if (stemmed.length > 1 && !STOPWORDS.has(stemmed))
|
|
1041
1194
|
tokens.push(stemmed);
|
|
1042
1195
|
}
|
|
@@ -1075,8 +1228,17 @@ function tokenize(text) {
|
|
|
1075
1228
|
}
|
|
1076
1229
|
}
|
|
1077
1230
|
else if (RTL_RE.test(syn)) {
|
|
1078
|
-
// RTL synonym
|
|
1079
|
-
const
|
|
1231
|
+
// RTL synonym — apply correct stemmer per language
|
|
1232
|
+
const rtlStem = FARSI_CHAR_RE.test(syn) ? farsiLightStem
|
|
1233
|
+
: HEBREW_CHAR_RE.test(syn) ? hebrewLightStem
|
|
1234
|
+
: arabicLightStem;
|
|
1235
|
+
const stemmed = rtlStem(syn);
|
|
1236
|
+
if (stemmed.length > 1 && !STOPWORDS.has(stemmed))
|
|
1237
|
+
expansions.push(stemmed);
|
|
1238
|
+
}
|
|
1239
|
+
else if (DEVANAGARI_RE.test(syn)) {
|
|
1240
|
+
// Devanagari synonym (Hindi)
|
|
1241
|
+
const stemmed = hindiLightStem(syn);
|
|
1080
1242
|
if (stemmed.length > 1 && !STOPWORDS.has(stemmed))
|
|
1081
1243
|
expansions.push(stemmed);
|
|
1082
1244
|
}
|