feat(ui): redesign voice cockpit with clinical companion drawer, Svelte 5 migration, and Gemini 3.8 voice

- Re-architect VoiceSession into full-bleed studio cockpit with overlay slide-over companion drawer
- Eliminate width squishing defect on LiveInsightPanel and add native dark/light theme support
- Integrate authentic Google Gemini 3.8 Flash TTS with Fenrir persona and fallback audio pipeline
- Implement comprehensive Playwright E2E visual regression suite across Desktop, iPad, and iPhone (21 tests, 45 snapshots)
- Migrate core application to Svelte 5 runes (, , ) with reactive stores
- Maintain .NET 8 Azure Functions serverless endpoints and clean build hygiene
This commit is contained in:
jpremill committed 2026-09-29 23:35:05 -04:00
1 parent c82b112624
commit 1feea40684
148 files changed
+11230 -1706

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
import { describe, test, expect } from 'vitest';
import { SCENARIOS, CBT_GLOSSARY } from '../constants';
import { validateScenario } from '../scripts/validate-scenarios';
describe('CBT Clinical Scenarios Catalog', () => {
test('should contain exactly 14 pre-calibrated default scenarios', () => {
expect(SCENARIOS.length).toBe(14);
});
test('every scenario should pass strict schema validation with zero errors', () => {
for (const scenario of SCENARIOS) {
const result = validateScenario(scenario);
expect(result.isValid).toBe(true);
expect(result.errors.length).toBe(0);
}
});
test('every scenario should have an assigned character name and non-empty initial message', () => {
for (const scenario of SCENARIOS) {
expect(scenario.characterName && scenario.characterName.trim().length > 0).toBe(true);
expect(scenario.initialMessage && scenario.initialMessage.trim().length > 0).toBe(true);
expect(scenario.systemInstruction.includes('INTERNAL CBT LOGIC')).toBe(true);
}
});
test('CBT glossary should contain valid definitions for all categories', () => {
expect(CBT_GLOSSARY.length).toBeGreaterThanOrEqual(18);
for (const entry of CBT_GLOSSARY) {
expect(entry.term && entry.term.trim().length > 0).toBe(true);
expect(entry.definition && entry.definition.trim().length > 0).toBe(true);
expect(['Distortion', 'Technique', 'Concept'].includes(entry.category)).toBe(true);
}
});
});