feat(global): implement main phase

This commit is contained in:
h
2026-01-05 17:49:03 +01:00
parent a5bddc4e6e
commit cdc494ad79
111 changed files with 5481 additions and 10 deletions

View 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
View 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);
}

View 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;

View 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
View 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;
};
}