feat: offline in-browser "Ask MSOS" assistant (no API, zero cost)

A privacy-friendly help widget that answers visitor questions from the
site's own content and links to the full page — runs 100% in the browser,
no API, no server, no per-token cost.

- tools/build_search_index.py: parses every EN/MK/SI page into ~720
  heading-level chunks per language -> assistant/index-<lang>.json
  (lazy-loaded only when the chat is opened; gzips to ~80 KB).
- assistant.js: dependency-free BM25 search + multilingual stopword
  filtering + a curated short-answer layer for common questions, plus an
  accessible chat widget (role=dialog, keyboard, aria). CSP-safe (self only).
- assistant.css: scoped .msa-* styles in the site's teal palette;
  responsive (full-screen panel on mobile).
- Injected on 208 pages (blog WIP excluded; picks it up when that lands).

Verified in a headless browser across EN/MK/SI: curated answers, search
fallback with correct ranking (rare terms win), correct deep links,
Cyrillic + Slovene diacritics, and zero console errors. Curated MK/SI
answers are machine-drafted — proofread before launch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
popovskikandClaude Opus 4.8 committed 2026-08-04 01:29:22 +02:00
1 parent cca6fd18aa
commit f7f297bd65
214 files changed
+876

No files matched your search

+2
View File
@@ -422,5 +422,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -607,5 +607,7 @@
<script src="../../main.js"></script>
<script src="../../member-form.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -314,5 +314,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -529,5 +529,7 @@
</footer>
<!-- END_FOOTER -->
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -382,5 +382,7 @@
</footer>
<!-- END_FOOTER -->
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -391,5 +391,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -397,5 +397,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -364,5 +364,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -397,5 +397,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -389,5 +389,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -379,5 +379,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -376,5 +376,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -381,5 +381,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -364,5 +364,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -377,5 +377,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -367,5 +367,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -398,5 +398,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -383,5 +383,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -354,5 +354,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -533,5 +533,7 @@
<!-- END_FOOTER -->
<script src="../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -289,5 +289,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -406,5 +406,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -469,5 +469,7 @@
<script src="../../main.js"></script>
<script src="../../news-filter.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -295,5 +295,7 @@
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -357,5 +357,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -378,5 +378,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -320,5 +320,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -331,5 +331,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -427,5 +427,7 @@
<!-- Поврзување до главната JS-датотека -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -383,5 +383,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -404,5 +404,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -403,5 +403,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -367,5 +367,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -360,5 +360,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -346,5 +346,7 @@
<!-- END_FOOTER -->
<script src="../../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -358,5 +358,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -355,5 +355,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -356,5 +356,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -353,5 +353,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -371,5 +371,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -383,5 +383,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -374,5 +374,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -399,5 +399,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -348,5 +348,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -366,5 +366,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -409,5 +409,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -513,5 +513,7 @@
<script src="../../main.js"></script>
<script src="../../student-guide.js"></script>
<script src="../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -360,5 +360,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -432,5 +432,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -261,5 +261,7 @@
<script src="../../../main.js"></script>
<script src="../../../my-route.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -387,5 +387,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -404,5 +404,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -349,5 +349,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -358,5 +358,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -398,5 +398,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -398,5 +398,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -368,5 +368,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -356,5 +356,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -393,5 +393,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -410,5 +410,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -377,5 +377,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -351,5 +351,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -383,5 +383,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -353,5 +353,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -380,5 +380,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -347,5 +347,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
@@ -418,5 +418,7 @@
<script src="../../../main.js"></script>
<script src="../../../guide-feedback.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -423,5 +423,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>
+2
View File
@@ -503,5 +503,7 @@
<!-- END_FOOTER -->
<script src="../../main.js"></script>
<link rel="stylesheet" href="/assistant.css">
<script src="/assistant.js" defer></script>
</body>
</html>