Merge origin/main into deferred OpenCode restart branch.

Resolve skills store conflicts by keeping repository-local directory
resolution from main and deferred-restart handling from this branch.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-08-03 09:26:57 +00:00
co-authored by Serhii Dziupin
72 changed files with 7793 additions and 128 deletions
+20
View File
@@ -209,12 +209,32 @@ const JA_MESSAGES: BootstrapMessages = {
loadingData: (providersText, agentsText) => `データを読み込み中 (${providersText}, ${agentsText})…`,
};
const DE_MESSAGES: BootstrapMessages = {
startingApi: 'OpenCode API wird gestartet…',
initializing: 'Initialisierung…',
connecting: 'Verbindung wird hergestellt…',
connected: 'Verbunden!',
connectionError: 'Verbindungsfehler',
disconnected: 'Verbindung getrennt',
reconnecting: 'Verbindung wird wiederhergestellt…',
initialDataLoadFailed: 'OpenCode ist verbunden, aber die Anfangsdaten konnten nicht geladen werden.',
cliNotFound: 'OpenCode CLI wurde nicht gefunden. Installieren Sie es zuerst.',
providersReady: '✓ Anbieter',
providersLoading: '… Anbieter',
agentsReady: '✓ Agents',
agentsLoading: '… Agents',
startingDevServer: (hostLabel) => `Webview-Entwicklungsserver wird gestartet (${hostLabel})...`,
waitingDevServer: (hostLabel, attempt) => `Warten auf den Webview-Entwicklungsserver (${hostLabel})... Versuch ${attempt}`,
loadingData: (providersText, agentsText) => `Daten werden geladen (${providersText}, ${agentsText})…`,
};
export const getBootstrapMessages = (locale: Locale): BootstrapMessages => {
return BOOTSTRAP_MESSAGES[locale];
};
const BOOTSTRAP_MESSAGES: Record<Locale, BootstrapMessages> = {
en: EN_MESSAGES,
de: DE_MESSAGES,
fr: FR_MESSAGES,
'zh-CN': ZH_CN_MESSAGES,
'zh-TW': ZH_TW_MESSAGES,
+1
View File
@@ -3,6 +3,7 @@ import type { Locale } from './runtime';
const INTL_LOCALE_BY_LOCALE: Record<Locale, string> = {
en: 'en-US',
de: 'de-DE',
fr: 'fr-FR',
'zh-CN': 'zh-CN',
'zh-TW': 'zh-TW',
@@ -2,6 +2,7 @@ import { describe, expect, test } from 'bun:test';
import { dict as enDict } from './messages/en';
import { dict as esDict } from './messages/es';
import { dict as deDict } from './messages/de';
import { dict as frDict } from './messages/fr';
import { dict as jaDict } from './messages/ja';
import { dict as koDict } from './messages/ko';
@@ -13,6 +14,7 @@ import { dict as zhTwDict } from './messages/zh-TW';
const localeDictionaries = {
en: enDict,
de: deDict,
fr: frDict,
es: esDict,
ja: jaDict,
@@ -35,6 +37,7 @@ describe('i18n dictionaries', () => {
test('all locales expose language label keys', () => {
for (const [, dictionary] of Object.entries(localeDictionaries)) {
expect(dictionary['common.language.german']).toBeTruthy();
expect(dictionary['common.language.french']).toBeTruthy();
expect(dictionary['common.language.japanese']).toBeTruthy();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -14,6 +14,7 @@ export const dict = {
'common.loading': 'Loading...',
'common.unavailable': 'Unavailable',
'common.language.english': 'English',
'common.language.german': 'German',
'common.language.french': 'French',
'common.language.simplifiedChinese': 'Chinese (Simplified)',
'common.language.traditionalChinese': 'Chinese (Traditional)',
+1
View File
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
"common.loading": "Cargando...",
"common.unavailable": "No disponible",
"common.language.english": "Inglés",
"common.language.german": "Alemán",
"common.language.french": "Francés",
"common.language.simplifiedChinese": "Chino (simplificado)",
"common.language.traditionalChinese": "Chino (tradicional)",
+1
View File
@@ -14,6 +14,7 @@ export const dict = {
'common.loading': 'Chargement...',
'common.unavailable': 'Indisponible',
'common.language.english': 'Anglais',
'common.language.german': 'Allemand',
'common.language.french': 'Français',
'common.language.simplifiedChinese': 'Chinois (simplifié)',
'common.language.traditionalChinese': 'Chinois (traditionnel)',
+1
View File
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
'common.loading': '読み込み中...',
'common.unavailable': '利用できません',
'common.language.english': '英語',
'common.language.german': 'ドイツ語',
'common.language.french': 'フランス語',
'common.language.simplifiedChinese': '中国語(簡体字)',
'common.language.traditionalChinese': '中国語(繁体字)',
+1
View File
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
'common.loading': '로딩 중...',
'common.unavailable': '사용할 수 없음',
'common.language.english': '영어',
'common.language.german': '독일어',
'common.language.french': '프랑스어',
'common.language.simplifiedChinese': '중국어(간체)',
'common.language.traditionalChinese': '중국어(번체)',
+1
View File
@@ -16,6 +16,7 @@ export const dict: Record<I18nKey, string> = {
'common.loading': 'Ładowanie...',
'common.unavailable': 'Niedostępne',
'common.language.english': 'Angielski',
'common.language.german': 'Niemiecki',
'common.language.french': 'Francuski',
'common.language.simplifiedChinese': 'Chiński (Uproszczony)',
'common.language.traditionalChinese': 'Chiński (Tradycyjny)',
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
"common.loading": "Carregando...",
"common.unavailable": "Indisponível",
"common.language.english": "Inglês",
"common.language.german": "Alemão",
"common.language.french": "Francês",
"common.language.simplifiedChinese": "Chinês (simplificado)",
"common.language.traditionalChinese": "Chinês (tradicional)",
+1
View File
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
"common.loading": "Завантаження...",
"common.unavailable": "Недоступно",
"common.language.english": "англійська",
"common.language.german": "Німецька",
"common.language.french": "Французька",
"common.language.simplifiedChinese": "Китайська (спрощена)",
"common.language.traditionalChinese": "Китайська (традиційна)",
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
'common.loading': '加载中...',
'common.unavailable': '不可用',
'common.language.english': 'English',
'common.language.german': '德语',
'common.language.french': '法语',
'common.language.simplifiedChinese': '简体中文',
'common.language.traditionalChinese': '繁体中文',
@@ -15,6 +15,7 @@ export const dict: Record<I18nKey, string> = {
'common.loading': '載入中...',
'common.unavailable': '無法使用',
'common.language.english': 'English',
'common.language.german': '德語',
'common.language.french': '法語',
'common.language.simplifiedChinese': '簡體中文',
'common.language.traditionalChinese': '繁體中文',
+7 -3
View File
@@ -1,10 +1,10 @@
export type Locale = 'en' | 'fr' | 'zh-CN' | 'zh-TW' | 'uk' | 'es' | 'pt-BR' | 'ko' | 'pl' | 'ja';
export type Locale = 'en' | 'de' | 'fr' | 'zh-CN' | 'zh-TW' | 'uk' | 'es' | 'pt-BR' | 'ko' | 'pl' | 'ja';
export const LOCALES = ['en', 'fr', 'zh-CN', 'zh-TW', 'uk', 'es', 'pt-BR', 'ko', 'pl', 'ja'] as const satisfies readonly Locale[];
export const LOCALES = ['en', 'de', 'fr', 'zh-CN', 'zh-TW', 'uk', 'es', 'pt-BR', 'ko', 'pl', 'ja'] as const satisfies readonly Locale[];
export const DEFAULT_LOCALE: Locale = 'en';
export const LOCALE_LABEL_KEYS: Record<Locale, 'common.language.english' | 'common.language.french' | 'common.language.simplifiedChinese' | 'common.language.traditionalChinese' | 'common.language.ukrainian' | 'common.language.spanish' | 'common.language.brazilianPortuguese' | 'common.language.korean' | 'common.language.polish' | 'common.language.japanese'> = {
export const LOCALE_LABEL_KEYS: Record<Locale, 'common.language.english' | 'common.language.french' | 'common.language.simplifiedChinese' | 'common.language.traditionalChinese' | 'common.language.ukrainian' | 'common.language.spanish' | 'common.language.brazilianPortuguese' | 'common.language.korean' | 'common.language.polish' | 'common.language.german' | 'common.language.japanese'> = {
en: 'common.language.english',
fr: 'common.language.french',
'zh-CN': 'common.language.simplifiedChinese',
@@ -14,6 +14,7 @@ export const LOCALE_LABEL_KEYS: Record<Locale, 'common.language.english' | 'comm
'pt-BR': 'common.language.brazilianPortuguese',
ko: 'common.language.korean',
pl: 'common.language.polish',
de: 'common.language.german',
ja: 'common.language.japanese',
};
@@ -59,6 +60,9 @@ export function normalizeLocale(value: string | undefined | null): Locale {
if (normalized === 'ja' || normalized.startsWith('ja-')) {
return 'ja';
}
if (normalized === 'de' || normalized.startsWith('de-')) {
return 'de';
}
if (normalized === 'pl' || normalized.startsWith('pl-')) {
return 'pl';
}
+5 -3
View File
@@ -42,9 +42,11 @@ async function loadDictionary(locale: Locale): Promise<I18nDictionary> {
? await import('./messages/ko') as { dict: I18nDictionary }
: locale === 'pl'
? await import('./messages/pl') as { dict: I18nDictionary }
: locale === 'ja'
? await import('./messages/ja') as { dict: I18nDictionary }
: { dict: enDict };
: locale === 'de'
? await import('./messages/de') as { dict: I18nDictionary }
: locale === 'ja'
? await import('./messages/ja') as { dict: I18nDictionary }
: { dict: enDict };
dictionaries.set(locale, mod.dict);
return mod.dict;
}