feat(global): implement main phase
This commit is contained in:
43
src/lib/i18n/context.svelte.ts
Normal file
43
src/lib/i18n/context.svelte.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { getContext, setContext } from 'svelte';
|
||||
import type { Language, Translations } from './types';
|
||||
import en from './translations/en';
|
||||
import ru from './translations/ru';
|
||||
|
||||
const I18N_KEY = Symbol('i18n');
|
||||
|
||||
const translations: Record<Language, Translations> = { en, ru };
|
||||
|
||||
export interface I18nContext {
|
||||
lang: Language;
|
||||
t: Translations;
|
||||
setLanguage: (lang: Language) => void;
|
||||
}
|
||||
|
||||
export function createI18nContext(initialLang: Language = 'ru'): I18nContext {
|
||||
let lang = $state<Language>(initialLang);
|
||||
const t = $derived(translations[lang]);
|
||||
|
||||
function setLanguage(newLang: Language) {
|
||||
if (newLang === 'en' || newLang === 'ru') {
|
||||
lang = newLang;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
get lang() {
|
||||
return lang;
|
||||
},
|
||||
get t() {
|
||||
return t;
|
||||
},
|
||||
setLanguage
|
||||
};
|
||||
}
|
||||
|
||||
export function setI18nContext(ctx: I18nContext) {
|
||||
setContext(I18N_KEY, ctx);
|
||||
}
|
||||
|
||||
export function getI18n(): I18nContext {
|
||||
return getContext<I18nContext>(I18N_KEY);
|
||||
}
|
||||
23
src/lib/i18n/index.ts
Normal file
23
src/lib/i18n/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Type exports
|
||||
export type { Language, Translations, PromptPreset, PersonalityData } from './types';
|
||||
|
||||
// Context exports (from svelte.ts file for runes support)
|
||||
export { createI18nContext, setI18nContext, getI18n, type I18nContext } from './context.svelte';
|
||||
|
||||
// Translation data
|
||||
import en from './translations/en';
|
||||
import ru from './translations/ru';
|
||||
import type { Language, Translations } from './types';
|
||||
|
||||
const translations: Record<Language, Translations> = { en, ru };
|
||||
|
||||
export const languages: Language[] = ['ru', 'en'];
|
||||
export const defaultLanguage: Language = 'ru';
|
||||
|
||||
export function getTranslations(lang: Language): Translations {
|
||||
return translations[lang] || translations[defaultLanguage];
|
||||
}
|
||||
|
||||
export function isValidLanguage(lang: string): lang is Language {
|
||||
return languages.includes(lang as Language);
|
||||
}
|
||||
91
src/lib/i18n/translations/en.ts
Normal file
91
src/lib/i18n/translations/en.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type { Translations } from '../types';
|
||||
|
||||
const en: Translations = {
|
||||
meta: {
|
||||
title: 'Chief Beaver Officer',
|
||||
description: 'AI agent for life management through Obsidian. Action cures fear.'
|
||||
},
|
||||
header: {
|
||||
logo: 'Chief Beaver Officer'
|
||||
},
|
||||
hero: {
|
||||
titleLine1: 'Your LifeOS',
|
||||
titleLine2: 'manager.',
|
||||
subtitle: 'AI agent, Obsidian, planning, tasks, decisions, mindset.',
|
||||
philosophy: 'Action cures fear. Build, we\'ll think for you.'
|
||||
},
|
||||
fakeObsidian: {
|
||||
sectionTitle: 'Explore the structure',
|
||||
sectionSubtitle: 'Your second brain. Your rules.',
|
||||
emptyState: 'Select a file to view',
|
||||
caption: 'We don\'t give you files to download. Explore, understand, build your own.'
|
||||
},
|
||||
promptBuilder: {
|
||||
sectionTitle: 'Get your Chief Beaver Officer',
|
||||
sectionSubtitle: 'Import into Raycast or any interface',
|
||||
openInRaycast: 'Open in Raycast',
|
||||
copyPrompt: 'Copy prompt',
|
||||
copied: 'Copied!',
|
||||
setupTitle: 'Recommended: Semantic Notes Vault MCP',
|
||||
setupDescription: 'Install via BRAT: aaronsb/obsidian-mcp-plugin. This connects manager to your vault.',
|
||||
presets: [
|
||||
{
|
||||
id: 'pro',
|
||||
name: 'Chief Beaver Pro',
|
||||
description: 'Gemini 3 Pro (High) for Raycast, choose reasoning manually',
|
||||
icon: 'beaver',
|
||||
model: 'google-gemini-3-pro',
|
||||
reasoning_effort: 'high'
|
||||
},
|
||||
{
|
||||
id: 'flash',
|
||||
name: 'Chief Beaver Flash',
|
||||
description: 'Gemini 3 Flash (Minimal) for Raycast',
|
||||
icon: 'zap',
|
||||
model: 'google-gemini-3-flash',
|
||||
reasoning_effort: 'minimal'
|
||||
},
|
||||
{
|
||||
id: 'copy',
|
||||
name: 'Copy Prompt',
|
||||
description: 'Use in any AI client',
|
||||
icon: 'clipboard',
|
||||
model: '',
|
||||
reasoning_effort: 'minimal'
|
||||
}
|
||||
]
|
||||
},
|
||||
personalityCards: {
|
||||
sectionTitle: 'Recommended models',
|
||||
sectionSubtitle: 'Different tools for different tasks',
|
||||
gemini: {
|
||||
name: 'Gemini 3 Pro/Flash',
|
||||
tagline: 'For personal',
|
||||
traits: [
|
||||
'Daily planning',
|
||||
'Life decisions',
|
||||
'Emotional support',
|
||||
'Journaling prompts',
|
||||
'Your life coach'
|
||||
],
|
||||
color: 'aurora-2'
|
||||
},
|
||||
claude: {
|
||||
name: 'Claude Opus 4.5',
|
||||
tagline: 'For work',
|
||||
traits: [
|
||||
'Code review',
|
||||
'Technical writing',
|
||||
'Research & analysis',
|
||||
'Project planning',
|
||||
'Your senior colleague'
|
||||
],
|
||||
color: 'aurora-3'
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
builtBy: 'h@kotikot.com'
|
||||
}
|
||||
};
|
||||
|
||||
export default en;
|
||||
91
src/lib/i18n/translations/ru.ts
Normal file
91
src/lib/i18n/translations/ru.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type { Translations } from '../types';
|
||||
|
||||
const ru: Translations = {
|
||||
meta: {
|
||||
title: 'Chief Beaver Officer',
|
||||
description: 'AI-агент для управления жизнью через Obsidian. Action cures fear.'
|
||||
},
|
||||
header: {
|
||||
logo: 'Chief Beaver Officer'
|
||||
},
|
||||
hero: {
|
||||
titleLine1: 'Менеджер твоей',
|
||||
titleLine2: 'ЖизньOS.',
|
||||
subtitle: 'AI-агент, Obsidian, планирование, задачи, решения, майндсет.',
|
||||
philosophy: 'Action cures fear. Build, we\'ll think for you.'
|
||||
},
|
||||
fakeObsidian: {
|
||||
sectionTitle: 'Исследуй структуру',
|
||||
sectionSubtitle: 'Твой второй мозг. Твои правила.',
|
||||
emptyState: 'Выбери файл для просмотра',
|
||||
caption: 'Мы не даём скачать готовое. Изучи, пойми, построй своё.'
|
||||
},
|
||||
promptBuilder: {
|
||||
sectionTitle: 'Получи своего Менеджера Бобрения',
|
||||
sectionSubtitle: 'Импортируй в Raycast или любой интерфейс',
|
||||
openInRaycast: 'Открыть в Raycast',
|
||||
copyPrompt: 'Скопировать промпт',
|
||||
copied: 'Скопировано!',
|
||||
setupTitle: 'Рекомендую Semantic Notes Vault MCP',
|
||||
setupDescription: 'Установи через BRAT: aaronsb/obsidian-mcp-plugin. Это подключит менеджера к твоему vault.',
|
||||
presets: [
|
||||
{
|
||||
id: 'pro',
|
||||
name: 'Менеджер Pro',
|
||||
description: 'Gemini 3 Pro (High) для Raycast, выбери reasoning вручную',
|
||||
icon: 'beaver',
|
||||
model: 'google-gemini-3-pro',
|
||||
reasoning_effort: 'high'
|
||||
},
|
||||
{
|
||||
id: 'flash',
|
||||
name: 'Менеджер Flash',
|
||||
description: 'Gemini 3 Flash (Minimal) для Raycast',
|
||||
icon: 'zap',
|
||||
model: 'google-gemini-3-flash',
|
||||
reasoning_effort: 'minimal'
|
||||
},
|
||||
{
|
||||
id: 'copy',
|
||||
name: 'Скопировать промпт',
|
||||
description: 'Используй в любом AI-клиенте',
|
||||
icon: 'clipboard',
|
||||
model: '',
|
||||
reasoning_effort: 'minimal'
|
||||
}
|
||||
]
|
||||
},
|
||||
personalityCards: {
|
||||
sectionTitle: 'Рекомендованные модели',
|
||||
sectionSubtitle: 'Разные инструменты для разных задач',
|
||||
gemini: {
|
||||
name: 'Gemini 3 Pro/Flash',
|
||||
tagline: 'Для личного',
|
||||
traits: [
|
||||
'Планирование дня',
|
||||
'Жизненные решения',
|
||||
'Эмоциональная поддержка',
|
||||
'Journaling промпты',
|
||||
'Твой life coach'
|
||||
],
|
||||
color: 'aurora-2'
|
||||
},
|
||||
claude: {
|
||||
name: 'Claude Opus 4.5',
|
||||
tagline: 'Для работы',
|
||||
traits: [
|
||||
'Code review',
|
||||
'Техническое письмо',
|
||||
'Исследования',
|
||||
'Планирование проектов',
|
||||
'Твой senior коллега'
|
||||
],
|
||||
color: 'aurora-3'
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
builtBy: 'h@kotikot.com'
|
||||
}
|
||||
};
|
||||
|
||||
export default ru;
|
||||
58
src/lib/i18n/types.ts
Normal file
58
src/lib/i18n/types.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
export type Language = 'en' | 'ru';
|
||||
|
||||
export interface PromptPreset {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
model: string;
|
||||
reasoning_effort: 'high' | 'minimal';
|
||||
}
|
||||
|
||||
export interface PersonalityData {
|
||||
name: string;
|
||||
tagline: string;
|
||||
traits: string[];
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface Translations {
|
||||
meta: {
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
header: {
|
||||
logo: string;
|
||||
};
|
||||
hero: {
|
||||
titleLine1: string;
|
||||
titleLine2: string;
|
||||
subtitle: string;
|
||||
philosophy: string;
|
||||
};
|
||||
fakeObsidian: {
|
||||
sectionTitle: string;
|
||||
sectionSubtitle: string;
|
||||
emptyState: string;
|
||||
caption: string;
|
||||
};
|
||||
promptBuilder: {
|
||||
sectionTitle: string;
|
||||
sectionSubtitle: string;
|
||||
openInRaycast: string;
|
||||
copyPrompt: string;
|
||||
copied: string;
|
||||
setupTitle: string;
|
||||
setupDescription: string;
|
||||
presets: PromptPreset[];
|
||||
};
|
||||
personalityCards: {
|
||||
sectionTitle: string;
|
||||
sectionSubtitle: string;
|
||||
gemini: PersonalityData;
|
||||
claude: PersonalityData;
|
||||
};
|
||||
footer: {
|
||||
builtBy: string;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user