Polish Novya UI with brand colors, first-load skeletons, and session transition overlay.

Keep chat pinned to the latest message while AI thinks or streams, and align buttons/inputs with the logo teal/blue focus treatment.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ar.badiei
2026-09-09 01:31:24 +03:30
co-authored by Cursor
parent 4ac0c16665
commit 8016b8f45e
56 changed files with 1874 additions and 529 deletions
@@ -0,0 +1,74 @@
import { buildAiCoachSessionContext } from '../src/modules/ai/sessionContext.ts';
import { getSessionByOrder } from '../src/modules/sessions/catalog.ts';
import {
processCoachAssistantResponse,
looksLikeFinalPostTestHandoff,
COACH_SESSION_COMPLETE_OPEN,
COACH_SESSION_COMPLETE_CLOSE,
} from '../src/modules/ai/sessionCompletion.ts';
const s11 = getSessionByOrder(11);
if (!s11) throw new Error('no s11');
const ctx = buildAiCoachSessionContext(s11);
const samples = [
'دوره آموزشی شما تمام شد. حالا پس‌آزمون را در اپ انجام دهید.',
'جلسات تموم شد؛ نوبت پس‌آزمون است.',
'مرور تمام شد. لطفا پس‌آزمون را انجام دهید.',
'فقط یک جمله معمولی بدون اشاره.',
];
let failed = 0;
for (const t of samples) {
const handoff = looksLikeFinalPostTestHandoff(t);
const expect = t !== samples[3];
if (handoff !== expect) {
failed += 1;
console.error('handoff mismatch', { t, handoff, expect });
}
}
const text = 'مرور جلسات تمام شد. حالا پس‌آزمون را در برنامه انجام دهید.';
const r = processCoachAssistantResponse(text, ctx, { userTurnCount: 4, alreadyCompleted: false });
if (!r.validation?.valid || r.signal?.sessionOrder !== 11 || r.signal?.readyForNextSession !== false) {
failed += 1;
console.error('synthetic completion failed', r.validation, r.signal);
}
const badSignal = {
sessionComplete: true,
sessionId: 'wrong',
sessionOrder: 11,
reason: 'x',
coveredTopics: ['نامرتبط'],
completedExercises: [],
userConfirmed: true,
readyForNextSession: true,
};
// Without handoff text, a bad marker must NOT finish the course.
const badNoHandoff = processCoachAssistantResponse(
`ادامه مرور\n${COACH_SESSION_COMPLETE_OPEN}\n${JSON.stringify(badSignal)}\n${COACH_SESSION_COMPLETE_CLOSE}`,
ctx,
{ userTurnCount: 3, alreadyCompleted: false },
);
if (badNoHandoff.validation?.valid) {
failed += 1;
console.error('bad marker without handoff should not validate', badNoHandoff.validation);
}
const bad = processCoachAssistantResponse(
`دوره تمام شد. حالا پس‌آزمون را در برنامه انجام دهید.\n${COACH_SESSION_COMPLETE_OPEN}\n${JSON.stringify(badSignal)}\n${COACH_SESSION_COMPLETE_CLOSE}`,
ctx,
{ userTurnCount: 3, alreadyCompleted: false },
);
if (!bad.validation?.valid || bad.signal?.sessionId !== ctx.sessionId || bad.signal?.readyForNextSession !== false) {
failed += 1;
console.error('repair with handoff failed', bad.validation, bad.signal);
}
if (failed > 0) {
console.error(`FAILED ${failed}`);
process.exit(1);
}
console.log('session-11 completion recovery OK');