@link-assistant/hive-mind 1.72.2 → 1.72.3
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/CHANGELOG.md +6 -0
- package/package.json +2 -1
- package/src/i18n.lib.mjs +35 -32
- package/src/locales/en.lino +878 -310
- package/src/locales/hi.lino +878 -310
- package/src/locales/ru.lino +878 -310
- package/src/locales/zh.lino +878 -310
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@link-assistant/hive-mind",
|
|
3
|
-
"version": "1.72.
|
|
3
|
+
"version": "1.72.3",
|
|
4
4
|
"description": "AI-powered issue solver and hive mind for collaborative problem solving",
|
|
5
5
|
"main": "src/hive.mjs",
|
|
6
6
|
"type": "module",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"dayjs": "^1.11.19",
|
|
77
77
|
"decimal.js-light": "^2.5.1",
|
|
78
78
|
"lino-arguments": "^0.3.0",
|
|
79
|
+
"lino-i18n": "^0.1.1",
|
|
79
80
|
"lino-objects-codec": "^0.3.6",
|
|
80
81
|
"secretlint": "^11.2.5",
|
|
81
82
|
"semver": "^7.7.3",
|
package/src/i18n.lib.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// i18n module for hive-mind.
|
|
2
2
|
// - Translation files live in src/locales/<locale>.lino and are stored
|
|
3
|
-
// in Links Notation, parsed via lino-
|
|
3
|
+
// in Links Notation, parsed and resolved via lino-i18n.
|
|
4
4
|
// - Supported locales: en (default fallback), ru, zh, hi.
|
|
5
5
|
// - Two locale tracks: ui (user-facing strings) and work (AI prompts /
|
|
6
6
|
// tool preferred language). Both default to the value of --language.
|
|
@@ -9,23 +9,31 @@
|
|
|
9
9
|
// normalizeLocale, getUserLocale, setUserLocale, clearUserLocale,
|
|
10
10
|
// resolveLocaleFromTelegramCtx.
|
|
11
11
|
|
|
12
|
-
import { promises as fs } from 'fs';
|
|
13
12
|
import path from 'path';
|
|
14
13
|
import { fileURLToPath } from 'url';
|
|
15
|
-
import {
|
|
14
|
+
import { createI18n } from 'lino-i18n';
|
|
15
|
+
import { loadLocalesFromFile } from 'lino-i18n/loaders';
|
|
16
16
|
|
|
17
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
18
18
|
const __dirname = path.dirname(__filename);
|
|
19
19
|
|
|
20
20
|
const DEFAULT_LOCALE = 'en';
|
|
21
21
|
const SUPPORTED_LOCALES = ['en', 'ru', 'zh', 'hi'];
|
|
22
|
+
const LINO_COMPATIBILITY_ALIASES = ['collapseTail', 'parentLabel'];
|
|
22
23
|
|
|
23
24
|
const localeCache = new Map(); // locale -> { key: string }
|
|
24
25
|
const userLocales = new Map(); // userId/chatId -> locale (in-memory)
|
|
26
|
+
const localesDir = path.join(__dirname, 'locales');
|
|
25
27
|
|
|
26
28
|
let currentUiLocale = DEFAULT_LOCALE;
|
|
27
29
|
let currentWorkLocale = DEFAULT_LOCALE;
|
|
28
30
|
let fallbackLoaded = false;
|
|
31
|
+
let i18n = createI18n({
|
|
32
|
+
locales: {},
|
|
33
|
+
defaultLocale: DEFAULT_LOCALE,
|
|
34
|
+
fallback: [DEFAULT_LOCALE],
|
|
35
|
+
compatibilityAliases: LINO_COMPATIBILITY_ALIASES,
|
|
36
|
+
});
|
|
29
37
|
|
|
30
38
|
export function getSupportedLocales() {
|
|
31
39
|
return [...SUPPORTED_LOCALES];
|
|
@@ -46,31 +54,22 @@ export function detectLocale() {
|
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
async function readLocaleFile(locale) {
|
|
49
|
-
const localesDir = path.join(__dirname, 'locales');
|
|
50
57
|
const linoFile = path.join(localesDir, `${locale}.lino`);
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const parsed = parseIndented({ text });
|
|
67
|
-
// parsed: { id: <localeName>, obj: { key: value, ... } }
|
|
68
|
-
if (!parsed || !parsed.obj) return {};
|
|
69
|
-
const out = {};
|
|
70
|
-
for (const [k, v] of Object.entries(parsed.obj)) {
|
|
71
|
-
out[k] = typeof v === 'string' ? unescapeString(v) : String(v);
|
|
72
|
-
}
|
|
73
|
-
return out;
|
|
58
|
+
const loaded = await loadLocalesFromFile(linoFile, {
|
|
59
|
+
compatibilityAliases: LINO_COMPATIBILITY_ALIASES,
|
|
60
|
+
});
|
|
61
|
+
const match = loaded.find(catalogue => catalogue.locale === locale) || loaded[0];
|
|
62
|
+
return match?.translations || {};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function refreshI18nRuntime() {
|
|
66
|
+
i18n = createI18n({
|
|
67
|
+
locales: Object.fromEntries(localeCache.entries()),
|
|
68
|
+
defaultLocale: currentUiLocale,
|
|
69
|
+
fallback: [DEFAULT_LOCALE],
|
|
70
|
+
compatibilityAliases: LINO_COMPATIBILITY_ALIASES,
|
|
71
|
+
});
|
|
72
|
+
i18n.setLocale(currentUiLocale);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
export async function loadTranslations(locale) {
|
|
@@ -83,6 +82,7 @@ export async function loadTranslations(locale) {
|
|
|
83
82
|
translations = {};
|
|
84
83
|
}
|
|
85
84
|
localeCache.set(locale, translations);
|
|
85
|
+
refreshI18nRuntime();
|
|
86
86
|
|
|
87
87
|
// Always have the fallback (English) ready
|
|
88
88
|
if (!fallbackLoaded && locale !== DEFAULT_LOCALE) {
|
|
@@ -93,6 +93,7 @@ export async function loadTranslations(locale) {
|
|
|
93
93
|
localeCache.set(DEFAULT_LOCALE, {});
|
|
94
94
|
}
|
|
95
95
|
fallbackLoaded = true;
|
|
96
|
+
refreshI18nRuntime();
|
|
96
97
|
} else if (locale === DEFAULT_LOCALE) {
|
|
97
98
|
fallbackLoaded = true;
|
|
98
99
|
}
|
|
@@ -157,10 +158,8 @@ export function t(key, params = {}, options = {}) {
|
|
|
157
158
|
} else {
|
|
158
159
|
locale = currentUiLocale;
|
|
159
160
|
}
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
const value = main[key] ?? fallback[key] ?? key;
|
|
163
|
-
return applyParams(value, params);
|
|
161
|
+
const value = i18n.t(key, params, { ...options, locale });
|
|
162
|
+
return typeof value === 'string' ? value : applyParams(String(value), params);
|
|
164
163
|
}
|
|
165
164
|
|
|
166
165
|
// Convenience helper for work-language strings (AI prompts).
|
|
@@ -185,12 +184,16 @@ export function setLocale(locale) {
|
|
|
185
184
|
if (normalized) {
|
|
186
185
|
currentUiLocale = normalized;
|
|
187
186
|
currentWorkLocale = normalized;
|
|
187
|
+
i18n.setLocale(normalized);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
export function setUiLocale(locale) {
|
|
192
192
|
const normalized = normalizeLocale(locale);
|
|
193
|
-
if (normalized)
|
|
193
|
+
if (normalized) {
|
|
194
|
+
currentUiLocale = normalized;
|
|
195
|
+
i18n.setLocale(normalized);
|
|
196
|
+
}
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
export function setWorkLocale(locale) {
|