@cachly-dev/mcp-server 0.5.48 → 0.5.49
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 +3 -2
- package/dist/index.js +59 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +58 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cachly-dev/mcp-server",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.49",
|
|
4
4
|
"mcpName": "io.github.cachly-dev/mcp-server",
|
|
5
5
|
"description": "AI memory brain for Claude Code, Cursor, Copilot & Windsurf — persistent sessions, lessons learned, semantic search, team brain. 51 MCP tools.",
|
|
6
6
|
"type": "module",
|
package/src/index.ts
CHANGED
|
@@ -55,7 +55,7 @@ import { Redis } from 'ioredis';
|
|
|
55
55
|
const API_URL = process.env.CACHLY_API_URL ?? 'https://api.cachly.dev';
|
|
56
56
|
const JWT = process.env.CACHLY_JWT ?? '';
|
|
57
57
|
const EMBED_MODEL = process.env.CACHLY_EMBED_MODEL ?? '';
|
|
58
|
-
const CURRENT_VERSION = '0.5.
|
|
58
|
+
const CURRENT_VERSION = '0.5.49';
|
|
59
59
|
/**
|
|
60
60
|
* ┌──────────────────────────────────────────────────────────────────────┐
|
|
61
61
|
* │ EMBEDDING PROVIDER — pluggable, client-side first │
|
|
@@ -425,6 +425,9 @@ const SEGMENT_RE = /([\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uac00
|
|
|
425
425
|
|
|
426
426
|
// RTL Unicode ranges: Arabic (U+0600–U+06FF + extended), Hebrew (U+0590–U+05FF)
|
|
427
427
|
const RTL_RE = /[\u0590-\u05ff\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb1d-\ufb4f\ufb50-\ufdff\ufe70-\ufeff]/;
|
|
428
|
+
// Distinguish Arabic from Hebrew within RTL segments
|
|
429
|
+
const HEBREW_CHAR_RE = /[\u0590-\u05ff\ufb1d-\ufb4f]/;
|
|
430
|
+
const ARABIC_CHAR_RE = /[\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb50-\ufdff\ufe70-\ufeff]/;;
|
|
428
431
|
|
|
429
432
|
// ── Katakana → Romaji conversion table (Hepburn system) ──────────────────────
|
|
430
433
|
// Digraphs must be listed before single chars so they match first.
|
|
@@ -522,6 +525,33 @@ function arabicLightStem(word: string): string {
|
|
|
522
525
|
return result;
|
|
523
526
|
}
|
|
524
527
|
|
|
528
|
+
/**
|
|
529
|
+
* Hebrew light stemmer — strips the definite article and common prefix particles
|
|
530
|
+
* that attach directly to words (no space) in Hebrew.
|
|
531
|
+
*
|
|
532
|
+
* Handles:
|
|
533
|
+
* ה (ha-) — definite article: הפריסה → פריסה
|
|
534
|
+
* ו (ve-/u-) — conjunction “and”: ופריסה → פריסה
|
|
535
|
+
* ב (be-/bi-) — preposition “in”: בסביבה → סביבה
|
|
536
|
+
* ל (le-/li-) — preposition “for”: לשרת → שרת
|
|
537
|
+
* מ (mi-/me-) — preposition “from”: מהשרת → השרת → שרת
|
|
538
|
+
* כ (ke-/ki-) — preposition “like”: כשרת → שרת
|
|
539
|
+
*
|
|
540
|
+
* Iterative (max 3 passes): מהפריסה → הפריסה → פריסה.
|
|
541
|
+
* Only strips when result is still ≥ 3 chars.
|
|
542
|
+
*/
|
|
543
|
+
function hebrewLightStem(word: string): string {
|
|
544
|
+
let result = word;
|
|
545
|
+
for (let i = 0; i < 3; i++) {
|
|
546
|
+
const prev = result;
|
|
547
|
+
if (result.length > 3 && 'הובלמכ'.includes(result[0]) && HEBREW_CHAR_RE.test(result[1])) {
|
|
548
|
+
result = result.slice(1);
|
|
549
|
+
}
|
|
550
|
+
if (result === prev) break;
|
|
551
|
+
}
|
|
552
|
+
return result;
|
|
553
|
+
}
|
|
554
|
+
|
|
525
555
|
// ── Cross-lingual tech term dictionary ────────────────────────────────────────
|
|
526
556
|
// Maps tokens (English, Japanese katakana, Chinese, Korean, Arabic, Hebrew)
|
|
527
557
|
// to their equivalents in other languages. Used to expand tokens at search time
|
|
@@ -530,8 +560,8 @@ function arabicLightStem(word: string): string {
|
|
|
530
560
|
// Keys must be lowercase. CJK values will be bigram-expanded at use time.
|
|
531
561
|
const CROSS_LINGUAL_MAP = new Map<string, string[]>([
|
|
532
562
|
// English → all
|
|
533
|
-
['deploy', ['デプロイ', '部署', '배포', 'deployment', 'deploying', 'نشر', 'bereitstellen', 'bereitstellung', 'déployer', 'déploiement', 'desplegar', 'despliegue', 'distribuire', 'distribuzione', 'implantar', 'implantação']],
|
|
534
|
-
['deployment', ['デプロイ', '部署', '배포', 'deploy', 'bereitstellung', 'déploiement', 'despliegue', 'distribuzione', 'implantação']],
|
|
563
|
+
['deploy', ['デプロイ', '部署', '배포', 'deployment', 'deploying', 'نشر', 'פריסה', 'bereitstellen', 'bereitstellung', 'déployer', 'déploiement', 'desplegar', 'despliegue', 'distribuire', 'distribuzione', 'implantar', 'implantação']],
|
|
564
|
+
['deployment', ['デプロイ', '部署', '배포', 'deploy', 'نشر', 'פריסה', 'bereitstellung', 'déploiement', 'despliegue', 'distribuzione', 'implantação']],
|
|
535
565
|
['container', ['コンテナ', '容器', '컨테이너', 'docker']],
|
|
536
566
|
['server', ['サーバー', 'サーバ', '服务器', '서버', 'سيرفر', 'שרת']],
|
|
537
567
|
['database', ['データベース', '数据库', '데이터베이스', 'db', 'قاعدة البيانات', 'datenbank', 'base de données', 'base de datos', 'banco de dados']],
|
|
@@ -543,6 +573,9 @@ const CROSS_LINGUAL_MAP = new Map<string, string[]>([
|
|
|
543
573
|
['test', ['テスト', '测试', '테스트', 'اختبار', 'בדיקה', 'testen', 'tester', 'probar', 'testare', 'testar']],
|
|
544
574
|
['auth', ['認証', '认证', '인증', 'authentication', 'login', 'oauth', 'مصادقة', 'אימות', 'authentifizierung', 'authentification', 'autenticación', 'autenticazione', 'autenticação']],
|
|
545
575
|
['authentication', ['auth', 'مصادقة', 'אימות', '認証', '认证', '인증', 'login', 'oauth']],
|
|
576
|
+
['environment', ['環境', '环境', '환경', 'env', 'بيئة', 'סביבה', 'umgebung', 'environnement', 'entorno', 'ambiente']],
|
|
577
|
+
['secret', ['key', 'token', 'password', 'jwt', 'مفتاح', 'מפתח', 'geheimnis', 'schlüssel', 'clave', 'clé', 'chiave', 'chave']],
|
|
578
|
+
['problem', ['error', 'issue', 'bug', 'failure', 'مشكلة', 'بعيا', '問題', '問題', '오류', 'fehler', 'problème', 'problema']],
|
|
546
579
|
['kubernetes', ['クベルネテス', 'k8s', 'kube']],
|
|
547
580
|
['network', ['ネットワーク', '网络', '네트워크', 'شبكة', 'רשת', 'netzwerk', 'réseau', 'red', 'rete', 'rede']],
|
|
548
581
|
['timeout', ['タイムアウト', '超时', '타임아웃', 'مهلة']],
|
|
@@ -720,6 +753,13 @@ const CROSS_LINGUAL_MAP = new Map<string, string[]>([
|
|
|
720
753
|
['قرص', ['disk', 'storage']],
|
|
721
754
|
['خادم', ['server']],
|
|
722
755
|
['برنامج', ['application', 'software', 'app']],
|
|
756
|
+
// Arabic terms from blog examples
|
|
757
|
+
['مشكلة', ['error', 'issue', 'bug', 'problem', 'failure']],
|
|
758
|
+
['بيئة', ['environment', 'env']],
|
|
759
|
+
['متغيرات', ['variables', 'env', 'environment']],
|
|
760
|
+
['إنتاج', ['production', 'prod']],
|
|
761
|
+
['سري', ['secret', 'key', 'token']],
|
|
762
|
+
['مفتاح سري', ['secret', 'key']],
|
|
723
763
|
// Hebrew → English
|
|
724
764
|
['שגיאה', ['error']],
|
|
725
765
|
['תיקון', ['fix']],
|
|
@@ -755,6 +795,13 @@ const CROSS_LINGUAL_MAP = new Map<string, string[]>([
|
|
|
755
795
|
['ממשק תכנות', ['api', 'interface']],
|
|
756
796
|
['ביצועים', ['performance']],
|
|
757
797
|
['אחסון', ['storage', 'disk']],
|
|
798
|
+
// Hebrew terms from blog examples
|
|
799
|
+
['פריסה', ['deploy', 'deployment']],
|
|
800
|
+
['בעיה', ['error', 'issue', 'bug', 'problem']],
|
|
801
|
+
['סביבה', ['environment', 'env']],
|
|
802
|
+
['ייצור', ['production', 'prod']],
|
|
803
|
+
['סודי', ['secret', 'key', 'token']],
|
|
804
|
+
['מפתח סודי', ['secret', 'key']],
|
|
758
805
|
|
|
759
806
|
// ── European languages → English ─────────────────────────────────────────
|
|
760
807
|
// German (Deutsch) → English
|
|
@@ -959,8 +1006,9 @@ function expandCrossLingual(token: string): string[] {
|
|
|
959
1006
|
* Features:
|
|
960
1007
|
* • CJK → character bigrams
|
|
961
1008
|
* • Katakana → additionally emits Hepburn romaji tokens (enables romaji queries)
|
|
962
|
-
* • Arabic
|
|
963
|
-
* •
|
|
1009
|
+
* • Arabic → word tokenization + iterative prefix stemming (al-, wa-, bi-, li-, fa-)
|
|
1010
|
+
* • Hebrew → word tokenization + iterative prefix stemming (ha-, ve-, be-, le-, mi-, ke-)
|
|
1011
|
+
* • All scripts → cross-lingual synonym expansion (EN↔JA↔ZH↔KO↔AR↔HE↔DE↔FR↔ES↔IT↔PT)
|
|
964
1012
|
*/
|
|
965
1013
|
function tokenize(text: string): string[] {
|
|
966
1014
|
const tokens: string[] = [];
|
|
@@ -998,11 +1046,14 @@ function tokenize(text: string): string[] {
|
|
|
998
1046
|
}
|
|
999
1047
|
}
|
|
1000
1048
|
} else if (RTL_RE.test(seg)) {
|
|
1001
|
-
// RTL segment
|
|
1049
|
+
// RTL segment — split on spaces, apply language-specific prefix stemming
|
|
1050
|
+
// Arabic: strips ال/و/ب/ل/ف/ك prefixes iteratively
|
|
1051
|
+
// Hebrew: strips ה/ו/ב/ל/מ/כ prefixes iteratively
|
|
1052
|
+
const isHebrew = HEBREW_CHAR_RE.test(seg);
|
|
1002
1053
|
const words = seg.trim().split(/\s+/);
|
|
1003
1054
|
for (const w of words) {
|
|
1004
1055
|
if (w.length <= 1 || STOPWORDS.has(w)) continue;
|
|
1005
|
-
const stemmed = arabicLightStem(w);
|
|
1056
|
+
const stemmed = isHebrew ? hebrewLightStem(w) : arabicLightStem(w);
|
|
1006
1057
|
if (stemmed.length > 1 && !STOPWORDS.has(stemmed)) tokens.push(stemmed);
|
|
1007
1058
|
}
|
|
1008
1059
|
} else {
|