mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 04:15:48 -06:00
bbbd70542b
* feat(sessions): recover offline device placements * chore(protocol): refresh session placement models * perf(ui): lazy-load session placement recovery * test(ui): remove dropdown timing assertion * test(ui): await committed cloud recovery route * fix(sessions): complete explicit abandonment locally * fix(sessions): fence lists by runner availability * fix(ui): preserve canonical session freshness * fix(sessions): preserve recovery contracts after rebase * test(ui): await durable cloud recovery entry * test(gateway): complete current runner fixtures * fix(gateway): publish runner availability edges * fix(ui): preserve shared session freshness * fix(ui): preserve canonical sidebar session state * fix(sessions): preserve abandoned partials and run-owned replies * fix(sessions): resume durable abandonment retries * test(gateway): compose provisioning replay with runner availability * fix(sessions): publish recovered move transitions
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import type { Plugin } from "vite";
|
|
import {
|
|
loadControlUiTranslationMemory,
|
|
materializeControlUiLocaleCatalog,
|
|
mergeControlUiTranslationMaps,
|
|
} from "../../scripts/lib/control-ui-i18n-catalog.ts";
|
|
import { CONTROL_UI_LOCALE_ENTRIES } from "../../scripts/lib/control-ui-i18n-config.ts";
|
|
import { flattenTranslations } from "../../scripts/lib/control-ui-i18n-sync-plan.ts";
|
|
import { registerActivityEnglish } from "../src/i18n/locales/en-activity.ts";
|
|
import { registerSessionPlacementEnglish } from "../src/i18n/locales/en-session-placement.ts";
|
|
import { en } from "../src/i18n/locales/en.ts";
|
|
|
|
const localeModulePrefix = "virtual:openclaw-control-ui-locale/";
|
|
const resolvedLocaleModulePrefix = `\0${localeModulePrefix}`;
|
|
// Vitest rewrites new URL(relative, import.meta.url) to browser self.location.
|
|
const i18nAssetsDir = path.resolve(
|
|
path.dirname(fileURLToPath(import.meta.url)),
|
|
"../src/i18n/.i18n",
|
|
);
|
|
const locales = new Set(CONTROL_UI_LOCALE_ENTRIES.map(({ locale }) => locale));
|
|
const sourceCatalog = mergeControlUiTranslationMaps(
|
|
en,
|
|
registerActivityEnglish.catalog,
|
|
registerSessionPlacementEnglish.catalog,
|
|
);
|
|
|
|
export function controlUiLocaleModulesPlugin(): Plugin {
|
|
return {
|
|
name: "control-ui-locale-modules",
|
|
enforce: "pre",
|
|
resolveId(id) {
|
|
if (id.startsWith(localeModulePrefix) && locales.has(id.slice(localeModulePrefix.length))) {
|
|
return `\0${id}`;
|
|
}
|
|
return null;
|
|
},
|
|
load(id) {
|
|
if (!id.startsWith(resolvedLocaleModulePrefix)) {
|
|
return null;
|
|
}
|
|
const locale = id.slice(resolvedLocaleModulePrefix.length);
|
|
if (!locales.has(locale)) {
|
|
return null;
|
|
}
|
|
const memoryPath = path.join(i18nAssetsDir, `${locale}.tm.jsonl`);
|
|
this.addWatchFile(memoryPath);
|
|
const memory = loadControlUiTranslationMemory(memoryPath);
|
|
if (memory.size === 0) {
|
|
throw new Error(`Control UI ${locale} translation memory is missing or empty`);
|
|
}
|
|
const catalog = materializeControlUiLocaleCatalog(flattenTranslations(sourceCatalog), memory);
|
|
return `export default ${JSON.stringify(catalog)};`;
|
|
},
|
|
};
|
|
}
|