diff --git a/README.md b/README.md index 798f9be..483262f 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,13 @@ ## Технологии ### Frontend + - React 18 + TypeScript - Vite - CSS (без фреймворков) ### Backend + - Express.js (прокси-сервер) - DeepSeek API (модель deepseek-chat V3) diff --git a/package.json b/package.json index c5f4ac1..c5d3749 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "resekai", "private": true, - "version": "0.0.0", + "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", diff --git a/src/components/Footer.css b/src/components/Footer.css index acd8e1a..322be92 100644 --- a/src/components/Footer.css +++ b/src/components/Footer.css @@ -26,6 +26,14 @@ color: #888; } +.footer-version { + font-size: 0.75rem; + color: #555; + padding: 0.15rem 0.5rem; + background: rgba(255, 255, 255, 0.05); + border-radius: 4px; +} + .footer-copyright { font-size: 0.8rem; color: #555; diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index a2ea5f1..f0755ae 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -30,6 +30,7 @@ export function Footer() {
⚔️ ReSekai + v{__APP_VERSION__} © 2026
diff --git a/src/pages/GamePage.tsx b/src/pages/GamePage.tsx index b59c524..7cbdfd3 100644 --- a/src/pages/GamePage.tsx +++ b/src/pages/GamePage.tsx @@ -88,11 +88,11 @@ export default function GamePage() { const handleBeforeUnload = (e: BeforeUnloadEvent) => { if (hasUnsavedChangesRef.current || isLoading) { e.preventDefault(); - e.returnValue = ''; + e.returnValue = ""; } }; - window.addEventListener('beforeunload', handleBeforeUnload); - return () => window.removeEventListener('beforeunload', handleBeforeUnload); + window.addEventListener("beforeunload", handleBeforeUnload); + return () => window.removeEventListener("beforeunload", handleBeforeUnload); }, [isLoading]); // Throttled streaming update (every 50ms instead of every chunk) diff --git a/src/services/deepseek.ts b/src/services/deepseek.ts index c76aa52..c259d2e 100644 --- a/src/services/deepseek.ts +++ b/src/services/deepseek.ts @@ -271,7 +271,10 @@ ${story.plot}`; /** * Builds dynamic context (state + summary + rule reminders) */ -export function buildDynamicContext(session: GameSession, messageCount?: number): string { +export function buildDynamicContext( + session: GameSession, + messageCount?: number, +): string { const state = session.currentState; const summary = session.storySummary || "The story just began."; const keyEvents = session.keyEvents?.length @@ -279,13 +282,16 @@ export function buildDynamicContext(session: GameSession, messageCount?: number) : "No significant events yet."; // Add rule reminders after 10+ messages to prevent drift - const ruleReminder = (messageCount && messageCount >= 10) ? ` + const ruleReminder = + messageCount && messageCount >= 10 + ? ` === REMINDER === • Do NOT act for the player — only describe reactions and consequences • Do NOT ask "What do you do?" — end with atmosphere, not questions • Format dialogue: **"text"** (double asterisks = bold) -• React to player's words explicitly` : ''; +• React to player's words explicitly` + : ""; return ` === CURRENT STATE === @@ -327,7 +333,9 @@ export async function generateStoryResponse( const worldContext = buildWorldContext(story); // 3. Dynamic context (state + summary + rule reminders after 10+ messages) - const dynamicContext = session ? buildDynamicContext(session, chatHistory.length) : ""; + const dynamicContext = session + ? buildDynamicContext(session, chatHistory.length) + : ""; // 4. Last N messages (not the full history!) const recentMessages = chatHistory.slice(-RECENT_MESSAGES_COUNT); @@ -362,7 +370,9 @@ export async function generateStoryResponseStream( ): Promise { const styleRules = buildStyleRules(story, player); const worldContext = buildWorldContext(story); - const dynamicContext = session ? buildDynamicContext(session, chatHistory.length) : ""; + const dynamicContext = session + ? buildDynamicContext(session, chatHistory.length) + : ""; const recentMessages = chatHistory.slice(-RECENT_MESSAGES_COUNT); const systemPrompt = styleRules + "\n" + worldContext + "\n" + dynamicContext; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..dbb4c62 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,3 @@ +/// + +declare const __APP_VERSION__: string; diff --git a/vite.config.ts b/vite.config.ts index 8b0f57b..df04b69 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,13 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' +import { readFileSync } from 'fs' + +const pkg = JSON.parse(readFileSync('./package.json', 'utf-8')) // https://vite.dev/config/ export default defineConfig({ plugins: [react()], + define: { + __APP_VERSION__: JSON.stringify(pkg.version), + }, })