Skip to content

Frontend Web (frontend/) ​

Le frontend Web de WeKnora est une application monopage (SPA) basée sur Vue 3 + TypeScript + Vite, comprenant toutes les interfaces interactives pour la gestion de la base de connaissances, les dialogues avec les agents, la collaboration organisationnelle et les paramètres du système. Le même code sert simultanément trois formes :

  1. Déploiement Web standard : Les produits construits par Vite sont hébergés par un conteneur nginx, avec /api proxy inverse vers le backend ;
  2. Intégration Web (Embed) : Entrée légère indépendante frontend/embed.html + frontend/src/embed-main.ts, pour permettre aux sites tiers d'intégrer la conversation de l'agent via iframe / fenêtre flottante ;
  3. Bureau (Wails) : Communication côté Go avec le processus de bureau via la liaison générée automatiquement sous frontend/src/wailsjs/, supportant les fonctionnalités de bureau telles que la zone de glisser-déposer --wails-draggable et la synchronisation du thème clair/sombre de la fenêtre.

Aperçu de la pile technologique ​

Selon frontend/package.json (version 0.8.3) :

CatégorieSélectionVersionDescription
FrameworkVue^3.5.34API de composition, style <script setup>
LangageTypeScript~6.0.3vue-tsc pour la vérification des types (npm run type-check)
Outil de buildVite^7.3.5Plugins : @vitejs/plugin-vue, @vitejs/plugin-vue-jsx
Bibliothèque de composants UITDesign (tdesign-vue-next)^1.19.2Compatible avec tdesign-icons-vue-next 0.4.4 (version verrouillée par overrides)
Gestion d'étatPinia^3.0.4Tous les stores sont situés dans frontend/src/stores/
RouteurVue Router^4.5.0createWebHistory, voir frontend/src/router/index.ts
Multilinguevue-i18n^11.4.2zh-CN / en-US / ru-RU / ko-KR / ja-JP
HTTPaxios^1.16.0Instance unifiée dans frontend/src/utils/request.ts
SSE flux@microsoft/fetch-event-source^2.0.1Chat stream, voir frontend/src/api/chat/streame.ts
Rendu Markdownmarked / marked-katex-extension / katex / highlight.js / mermaid—Réponses enrichies (formules, code, diagrammes)
Sécuritédompurify^3.4.11Désinfection v-html (frontend/src/utils/markdownDomPurify.ts)
Aperçu documentsdocx-preview / @vue-office/pptx / xlsx / papaparse—Aperçu Word / PPT / Excel / CSV
Longues listesvue-virtual-scroller2.0.0-beta.8Défilement virtuel des messages
StyleLess + variables CSSless ^4.6.4Thème dans frontend/src/assets/theme/theme.css

Détails de dépendance à noter :

  • xlsx : version SheetJS figée 0.20.2 dans package-lock.json (intégrité complète) ; build hors ligne = cache npm préparé ;
  • frontend/pnpm-workspace.yaml : pas de sous-paquet workspace, seulement la liste blanche allowBuilds (@vue-office/pptx, esbuild, vue-demi) ;
  • overrides / resolutions : lightningcss désactivé, versions unifiées pour esbuild et serialize-javascript.

Structure du module ​

Aperçu du contenu ​

ContenuResponsabilité
frontend/src/main.tsEntrée principale SPA : installer TDesign / Pinia / Router / i18n, initialiser le thème et les polices, enregistrer la protection hors ligne des icônes TDesign (installTDesignIconOfflineGuard, éviter les requêtes à l'exécution tdesign.gtimg.com), attendre router.isReady() avant de monter pour éviter le clignotement de l'écran initial
frontend/src/embed-main.tsEntrée intégrée : application Vue indépendante avec routage indépendant (uniquement /embed/:channelId), montage #embed-app, utilisation de i18n indépendante (src/i18n/embed.ts)
frontend/src/views/Composants au niveau des pages, classés par domaine métier (voir tableau de routage ci-dessous)
frontend/src/components/Composants communs inter-pages (bulle de message, masque de téléchargement, panneau de commandes, etc.)
frontend/src/stores/État Pinia (voir tableau store ci-dessous)
frontend/src/api/Encapsulation API backend (voir tableau des modules API ci-dessous)
frontend/src/composables/Fonctions compositionnelles : thème, polices, gestion du flux de chat, couche de citation, pont Embed, etc.
frontend/src/hooks/Hooks métier (ex. useKnowledgeBase)
frontend/src/utils/Axios, pipeline markdown, DOMPurify, affichage outils Agent, etc.
frontend/src/i18n/Configuration vue-i18n et packs de langues
frontend/src/assets/theme/Variables CSS thème clair / sombre
frontend/src/wailsjs/Bindings Wails générés (ne pas modifier)
frontend/src/directives/, types/, config/Directives, types, configuration
frontend/public/Statiques : weknora-widget.js, config.js (runtime), icônes TDesign hors ligne

Liste des routes de page ​

Les routes sont définies à frontend/src/router/index.ts, utilisées à createWebHistory, tous les composants de page sont importés dynamiquement (chargement paresseux par paquetage selon la route).

Routes principales ​

CheminNomComposantFonction
/—RedirectionRediriger vers /platform/knowledge-bases
/loginloginsrc/views/auth/Login.vuePage de connexion (incluant OIDC, changement de langue, arrière-plan animé)
/registerregisterByInvitesrc/views/auth/Login.vuePage de destination pour l'inscription par invitation — réutilise le composant Login, détecter ?token=xxx à l'affichage pour passer en mode inscription par invitation
/onboarding/workspaceworkspaceOnboardingsrc/views/auth/WorkspaceOnboarding.vuePage d'orientation de l'espace de travail pour les utilisateurs sans locataire (créer ou attendre une invitation), nécessite une connexion mais ne requiert pas de locataire existant
/joinjoinOrganizationRedirectionLien d'invitation pour rejoindre l'organisation, transformer ?code= en paramètre invite_code et passer à /platform/organizations
/knowledgeBasehomesrc/views/knowledge/KnowledgeBase.vueDétails de la base de connaissances (chemin principal hérité)
/platformPlatformsrc/views/platform/index.vueLayout principal (menu, router-outlet, modale paramètres, drag-and-drop upload), défaut → liste des bases
/platform/dev/markdownmarkdownTestsrc/views/dev/MarkdownTestPage.vueRégression visuelle Markdown, dev uniquement (import.meta.env.DEV)

/platform Sous-routeur ​

CheminNomComposantFonctionnalité
/platform/knowledge-basesknowledgeBaseListsrc/views/knowledge/KnowledgeBaseList.vueListe des bases de connaissances : barre latérale de l'espace (Tout / Le Mien / Par Organisation / Favoris / Récents), liste de cartes, entrée de création ; prend en charge le tri par date de mise à jour / date de création / nom (components/ResourceSortControl.vue, applicable également à la liste des agents intelligents)
/platform/knowledge-bases/:kbIdknowledgeBaseDetailsrc/views/knowledge/KnowledgeBase.vueDétails de la base de connaissances : liste des documents (peut être triée par date de mise à jour / date de création / nom de fichier, le tri est effectué côté serveur, tri par défaut : date de création décroissante), téléchargement, état de l'analyse, entrée de session, Wiki, etc.
/platform/agentsagentListsrc/views/agent/AgentList.vueListe et gestion des agents intelligents (Agent), l'édition se fait via AgentEditorModal.vue ; nécessite la capacité de déploiement agents
/platform/toolbox/:section?toolboxsrc/views/toolbox/Toolbox.vueBoîte à outils : skills, mcp, browserconnection — voir § Boîte à outils
/platform/artifactsartifactLibrarysrc/views/artifacts/ArtifactLibrary.vueFichiers produits par les agents ; capacité settings.sandbox
/platform/creatChatglobalCreatChatsrc/views/creatChat/creatChat.vueNouvelle page de conversation : poser des questions recommandées, choisir la base de connaissances/Agent/modèle avant de lancer la session
/platform/knowledge-bases/:kbId/creatChatkbCreatChatsrc/views/creatChat/creatChat.vueLancer une nouvelle conversation à partir du contexte d’une certaine base de connaissances (même composant)
/platform/chat/:chatidchatsrc/views/chat/index.vuePage de session : flux de messages (rendu en flux SSE, écran squelette, défilement virtuel), panneau de références, aperçu des pièces jointes
/platform/organizationsorganizationListsrc/views/organization/OrganizationList.vueListe des organisations : créer/rejoindre une organisation, gestion des membres et des ressources partagées (en lien avec OrganizationSettingsModal.vue) ; nécessite la capacité de déploiement organizations, la version Lite est toujours masquée. Lors de l’ajout de membres, rechercher précisément par ID complet de l’espace, plus de recherche approximative par nom d’espace
/platform/settingssettingssrc/views/settings/Settings.vueCentre des paramètres (mode plein écran modale), partitions voir ci-dessous « Partitions et visibilité du centre des paramètres »
/platform/tenant—RedirectionAncien chemin → /platform/settings
/platform/knowledge-search—RedirectionRecherche globale legacy → liste KB + panneau ⌘K (?cmdk=)
/platform/integrations—Redirection→ /platform/settings?section=integration-im (l'ancien ?tab= sera unifié en integration-<tab> ; vue dans src/views/integrations/)
/platform/system, /platform/system/settings, /platform/system/adminssystemSettings / systemAdminsRedirectionAncien chemin de gestion système → /platform/settings?section=system-global, nécessite requiresSystemAdmin (vue dans src/views/system/ : SystemSettings.vue, SystemAuditLog.vue, PlatformAPIKeys.vue, etc.)
/platform/system/queuessystemQueuesRedirection→ /platform/settings?section=runtime-queues (file d'attente des tâches à l'exécution src/views/system/RuntimeQueues.vue)

Entrée indépendante : page intégrée ​

/embed/:channelId n'appartient pas à la route principale du SPA, mais constitue une entrée indépendante composée de frontend/embed.html + frontend/src/embed-main.ts (nginx et le serveur de développement Vite redirigeront tous les /embed/* vers embed.html), le composant est src/views/embed/EmbedPage.vue (avec le support de EmbedChatView.vue / EmbedChatCore.vue / EmbedBotMessage.vue, etc.), utilisant le token Embed pour l'authentification, destiné à être intégré dans un iframe de sites tiers.

Sections et visibilité du centre de réglages ​

Settings.vue Présenter toutes les sections en sept groupes, localiser avec ?section= :

GroupePartition (valeur section)
Comptegeneral (préférences personnelles), userprofile, mymemory (mémoire personnelle), envvars (variables personnelles)
Espacetenant (informations spatiales), members (membres), chathistory, memory (mémoire spatiale)
Modèle et exécutionmodels, ollama, weknoracloud
Intégration de publicationintegration-im, integration-embed, integration-api, integration-mcpserver, integration-cli, integration-chrome, integration-claw
Données et extensionsvectorstore, parser, storage, sandbox, websearch
Gestion du systèmesystem-global, runtime-queues, platform-api-keys, system-audit-log
Plateformesystem (informations sur la version)

L'onglet intégré publié est enregistré par frontend/src/config/integrations.ts de INTEGRATION_TABS / INTEGRATION_PREVIEW_ITEMS, la valeur de la partition est uniformisée à integration-<tab> ; l'ancien /platform/integrations?tab=<tab> sera normalisé dans la partition correspondante.

Depuis la version v0.8.2, les compétences, les services MCP et la connexion au navigateur ne sont plus configurés par section, mais déplacés dans Boîte à outils. Les anciens signets /platform/settings?section=skills|mcp|browserconnection seront redirigés par le gardien de route vers /platform/toolbox/<section> (skills conservera le paramètre sandboxId).

La visibilité est déterminée par trois ensembles de règles, et le front-end ne fait qu'afficher de manière convergente, c'est le gardien de route back-end qui est l'autorité :

  • Seuil des rôles dans l'espace : frontend/src/config/settingsAccess.ts de SETTINGS_SECTION_MIN_ROLE fixe le rôle minimum pour chaque zone. general / models / system / userprofile / tenant / members / mymemory / envvars sont viewer et plus (lecture seule visible), ollama, weknoracloud, websearch, chathistory, memory, vectorstore, parser, storage, sandbox nécessitent admin ; pour la publication intégrée, integration-api nécessite owner (INTEGRATION_TAB_MIN_ROLE). Il existe aussi SETTINGS_MANAGEMENT_SHORTCUT_MIN_ROLE : dans le menu de l'avatar, les raccourcis étiquetés « Gestion » ont un seuil plus élevé (gestion des membres nécessite owner, gestion des modèles nécessite admin), afin d’éviter de faire passer des pages en lecture seule pour des entrées de gestion.
  • Capacité de déploiement : SETTINGS_SECTION_CAPABILITY / INTEGRATION_TAB_CAPABILITY dans deploymentCapabilities.ts mappent les sections sur GET /api/v1/system/capabilities ; si supported: false, l’entrée est masquée (voir § navigation et capacités).
  • Administrateurs système : sections system-global, runtime-queues, platform-api-keys, system-audit-log visibles seulement pour SystemAdmin — voir Auth et locataires.

Boîte à outils ​

Le « Boîte à outils » du menu de gauche (/platform/toolbox/:section?, src/views/toolbox/Toolbox.vue) gère de manière centralisée les outils disponibles pour l'agent, les onglets sont définis dans frontend/src/config/toolbox.ts de TOOLBOX_ITEMS :

Onglet (section)ContenuCondition de visibilité
skillsGestion des compétences (réutilise SkillSettings.vue), peut inclure la configuration du sandbox pour ?sandboxId=À partir de admin, et le déploiement prend en charge settings.sandbox
mcpService MCP (réutilise McpSettings.vue)À partir de admin, et le déploiement prend en charge settings.mcp
browserconnectionConnexion au navigateur (réutilise BrowserConnectionSettings.vue), affiche l'état de la connexion sur l'ongletÀ partir de viewer

Les onglets conservent le rôle et le seuil de capacité de déploiement de la partition des paramètres d'origine (canAccessToolboxSection) ; lorsque l'espace actuel ne contient aucun onglet visible, un état vide est affiché. Lorsqu'un élément du menu de la barre latérale est survolé, les outils disponibles sont prévisualisés, et l'état de la connexion du navigateur est également affiché dans la barre latérale. L'utilisation de la connexion du navigateur est expliquée dans Navigateur local.

Boîte à outils : skills, services MCP et connexion navigateur sur une seule page
Boîte à outils : skills, services MCP et connexion navigateur sur une seule page

Sections de la fenêtre contextuelle d'édition de la base de connaissances ​

De nombreuses configurations ne se trouvent pas dans le centre de paramètres, mais dans la fenêtre contextuelle d'édition de la base de connaissances (KnowledgeBaseEditorModal.vue), car elles s'appliquent par base. Les sections de la barre latérale sont organisées en cinq groupes, dont trois n'apparaissent que lors de l'« édition d'une base de connaissances existante » :

GroupePartition (key)Remarques
Basebasic, modelsNom, type, modèle de dialogue / vecteur / résumé
Traitementparser, multimodal, asr, chunkingMoteur d'analyse et en-tête de première ligne, compréhension des images, transcription vocale, paramètres de segmentation
DonnéesvectorStore, storage, faqfaq uniquement bibliothèque de type FAQ ; vectorStore ne peut pas être modifié après liaison
IntégrationdatasourceMode édition uniquement, Feishu / Lark (base de connaissances et cloud), Notion, Confluence, Yuque, documents DingTalk, Tencent IMA, RSS / Atom, GitLab, etc. La synchronisation se configure ici, pas dans les paramètres globaux (définition du connecteur voir views/knowledge/settings/DataSourceEditorDialog.vue)
Gestiongraph, advanced, share, activityGraphique de connaissances, options avancées, partage à l'organisation, flux d'activité ; les deux derniers sont uniquement en mode édition

Panneau de commande global (⌘K / Ctrl+K) ​

components/GlobalCommandPalette.vue est la deuxième principale voie de navigation en dehors de la barre latérale :

  • Rechercher dans la base de connaissances, les documents et les conversations, avec la possibilité de restreindre la portée à une certaine base de connaissances (scope chip) avant de rechercher ;
  • Afficher les recherches récentes et les actions rapides (créer une base, télécharger, créer une nouvelle conversation, etc.) lorsqu’il n’y a pas de contenu ;
  • L’entrée en haut à droite ouvre le tiroir des paramètres de recherche (views/settings/RetrievalSettings.vue). C’est l’endroit pour ajuster TopK, le seuil vectoriel/de mots-clés et les paramètres de réordonnancement — il n’est pas dans le centre de paramètres, et si vous ne le trouvez pas, c’est ici.

Garde de navigation ​

Chaîne dans frontend/src/router/index.ts :

  1. Callback OIDC : hash oidc_result= / oidc_error= → laisser App.vue traiter ;
  2. Signets boîte à outils : /platform/settings?section=skills|mcp|browserconnection → /platform/toolbox/<section> ;
  3. Deep link Lite / bureau : après reload, restaurer le sous-chemin /platform depuis sessionStorage ;
  4. Session : si déconnecté, tenter getCurrentUser() avec weknora_token (memberships à jour) ;
  5. Auto-login bureau : sinon une fois autoSetup() via Wails GetAutoSetupToken() + en-tête X-WeKnora-Desktop-Token (v0.8.2+, natif uniquement) ;
  6. Locataire : connecté sans espace → /onboarding/workspace ;
  7. Capacités : meta.requiredCapability non supportée → message puis liste KB (échec de détection = laisser passer) ;
  8. SystemAdmin : requiresSystemAdmin → redirection si non admin (UI seulement ; le serveur impose aussi).

Gestion d'état (Pinia) ​

Stores sous frontend/src/stores/ :

FichierID / Type de StoreResponsabilités
stores/auth.tsuseAuthStoreCœur de l'authentification : user / token / refreshToken / tenant / memberships / vérification des rôles (hasRole, isSystemAdmin), marqueur du mode Lite ; lors de la déconnexion, nettoyer en cascade le cache au niveau de l'espace des autres stores et recharger les préférences utilisateur (thème / police)
stores/chatResources.tsuseChatResourcesStoreCache des ressources au niveau de l'espace (TTL 60s) : base de connaissances, Agent, modèles, liste des fournisseurs de recherche Web, pour réutilisation par le chat / le sélecteur de nouvelles conversations
stores/editorResources.tsuseEditorResourcesStoreCache éditeur / paramètres (TTL 60s) : stockage, prompts, parseur, MCP, skills, presets Agent, retrieval
stores/commandPalette.tsuseCommandPaletteStorePanneau ⌘K : recherche et recherches récentes scoping (user, tenant)
stores/organization.tsuseOrganizationStoreCollaboration organisationnelle : liste d'organisations, membres, partage de bases de connaissances/Agent, demandes d'adhésion et approbation, promotion de rôle, etc.
stores/organizationState.tsModule de fonctions puresUpsert / fusion de la liste d'organisations, impact de l'approbation d'adhésion sur le nombre de membres et autres logiques pures (tests unitaires associés organizationState.test.ts)
stores/settings.tsStore de paramètresConfiguration de la session et de l'Agent : base de connaissances/fichiers/étiquettes/MCP/Compétences/Outils sélectionnés, configuration du modèle, configuration Ollama, activation de la recherche Web, etc.
stores/settingsStorage.tsModule de fonctions puresLecture de la persistance des paramètres (clé WeKnora_settings), clonage et correction du mode Agent intégré (test associé settingsStorage.test.mjs)
stores/menu.tsuseMenuStoreMenu gauche et titres i18n
stores/knowledge.tsknowledgeStoreListe légère des cartes KB
stores/ui.tsuseUIStoreÉtat global de l'interface utilisateur : fenêtres modales de paramètres, fenêtre modale d'édition de la base de connaissances, éditeur de documents manuel, basculement et paramètres de la barre latérale repliable
stores/uploadConfirm.tsStore de confirmation de téléchargementÉtat de la boîte de dialogue de confirmation des paramètres avant le téléchargement / importation via URL / saisie manuelle / re-analyse
stores/versionedRequest.tsModule de fonction purecreateVersionedRequestCoordinator : Coordinateur de requêtes mises en cache avec numéro de version, empêchant les anciennes réponses d’écraser les nouvelles écritures (avec versionedRequest.test.ts)
stores/deploymentCapabilities.tsuseDeploymentCapabilitiesStoreInstantané des capacités de déploiement (GET /api/v1/system/capabilities), utilisé par les gardes de route, la barre latérale, les paramètres et la boîte à outils pour déterminer si l’entrée doit s’afficher
stores/modelProviders.tsuseModelProvidersStoreCache de l'annuaire des fournisseurs de modèles (GET /api/v1/models/providers, chargé selon le type de modèle), l'éditeur de modèles et les cartes de modèles lisent unifiées les informations des fournisseurs à partir d’ici
stores/uploadTasks.ts (+ queue/core/state)useUploadTasksStoreUpload KB : concurrence, annulation, progression analyse, panneau flottant
stores/browserConnection.tsuseBrowserConnectionStoreConnexion navigateur local (boîte à outils / barre latérale)
stores/sessionActivity.tsuseSessionActivityStoreSessions en cours dans la barre latérale

Encapsulation API (frontend/src/api/) ​

Requêtes ​

  • Axios : frontend/src/utils/request.ts, baseURL via getApiBaseUrl() et BASE_URL Vite ; timeout 30 s ; postUpload avec timeout adapté à la taille (uploadTimeoutMs, min 5 min).
  • Requête : Authorization, Accept-Language, X-Request-ID, X-Tenant-ID (token Embed préservé).
  • Réponse : 2xx → data ; 401 → refresh single-flight (utils/authRefresh.ts) ; endpoints publics (PUBLIC_AUTH_PATHS) sans redirect login ; embed jamais vers /login.
  • $httpStatus : sur JSON WithStatus<T> (ex. création user 201 vs 200 idempotent), non énumérable.
  • SSE : api/chat/streame.ts + useChatStreamHandler.ts ; 401 stream partage le refresh axios.

Liste des modules ​

ModuleResponsabilités
api/auth/Connexion, inscription, OIDC, autoSetup (uniquement pour le bureau natif, avec X-WeKnora-Desktop-Token fourni par Wails), reprise de session getCurrentUser
api/tenant/ (index / members / invitations / audit-log)Informations sur le locataire (espace de travail), gestion des membres, invitations, journal d'audit
api/organization/CRUD sur l'organisation, membres, bases de connaissances/Agents partagés, demandes d'adhésion
api/knowledge-base/CRUD sur les bases de connaissances et gestion des fichiers/entrées de connaissances
api/chat/ (index / streame / steer / temporary-attachments)CRUD sur les sessions, génération de titres, questions-réponses en flux SSE, ajout de messages aux tours des agents en cours d'exécution (steer), pièces jointes temporaires
api/artifacts.tsListe et suppression des produits (/api/v1/artifacts)
api/memory.ts / api/env-vars.tsMémoire d'espace / personnelle, variables personnelles
api/mcp-endpoint.tsPoints de terminaison MCP intégrés
api/chat-history.tsHistorique de chat
api/agent/CRUD Agent, presets, placeholders (Quick Answer / Smart Reasoning)
api/model/Modèles
api/retrieval.tsRetrieval tenant
api/vector-store.ts / storage-backend.ts / chunker/Vector store, stockage, chunker
api/datasource/Sources de données
api/embed/Canaux embed
api/initialization/Initialisation système
api/system/Infos système, stockage, prompts, parseur
api/mcp-service.ts / api/skill/MCP et skills
api/web-search.ts / web-search-provider.tsRecherche web
api/wiki/Wiki
api/message-suggestion.tsQuestions suggérées
api/user-favorites.tsFavoris KB / Agent

L'état d'attente de la timeline de dialogue ​

La progression visualisée du pipeline RAG (views/chat/components/RagPipelineProgress.vue) connaît un silence entre « toutes les étapes visibles terminées » et « le modèle génère le premier caractère ». Cette pause est décrite par utils/rag-pipeline-state.ts :

  • getRagPipelineWaitKind() Détermination du type d'attente : seules les étapes de recherche réellement terminées sont appelées model (génération de réponse en cours) ; pour les questions-réponses purement en pièces jointes, les tours sans étapes de recherche reçoivent une preparing neutre, et non l'absence totale de retour ;
  • createRagWaitController() Responsable de l'affichage des détails : délai RAG_WAIT_REVEAL_DELAY_MS (250 ms) avant affichage, pour éviter un clignotement lorsque le modèle répond très rapidement ; dépassement de RAG_WAIT_STALL_DELAY_MS (60 s) pour passer à l'état « stagnation » — lorsque la connexion SSE est interrompue, l'arrière-plan n'enverra plus is_completed, sans cette limite la barre de progression afficherait toujours « presque prêt » ;
  • Les changements d'état sont annoncés via une zone permanente aria-live, les utilisateurs de lecteurs d'écran ne manqueront pas la lecture lorsque le nœud est entièrement remplacé.

Multilingue (i18n) ​

Implémenté en frontend/src/i18n/index.ts, basé sur vue-i18n (le modèle de composition de legacy: false, globalInjection: true) :

  • Langues prises en charge (frontend/src/i18n/locales/) :
    • zh-CN (chinois simplifié, par défaut et fallback)
    • en-US (anglais)
    • ru-RU (russe)
    • ko-KR (coréen)
    • ja-JP (japonais)
  • La sélection de la langue est persistée dans la clé locale de localStorage ; l'intercepteur axios écrit la langue actuelle dans l'en-tête de requête Accept-Language, permettant au backend de retourner le contenu localisé.
  • Certaines traductions contiennent des balises <strong> intégrées (rendu v-html après désinfection par DOMPurify), avec warnHtmlMessage: false configuré pour désactiver l'alerte HTML de vue-i18n.
  • i18n indépendant pour l'embed : la page embarquée côté visiteur utilise un frontend/src/i18n/embed.ts séparé (chargé par embed-main.ts), le texte « Web Embed » côté gestion reste dans le paquet de langue principal ; frontend/src/i18n/locales/embed/index.ts réexporte uniformément l'assistant de normalisation de langue (supporte la synchronisation de la langue embed à partir des paramètres URL).
  • Outils d'audit et de découpage : les paquets de langue sont volumineux et peuvent accumuler des clés mortes non référencées ou des nouvelles clés non traduites, donc trois scripts accompagnent (frontend/package.json) :
CommandeFonction
npm run check-i18nExécuter src/i18n/localeKeyAudit.test.ts, vérifier que les ensembles de clés de chaque paquet de langue sont cohérents et qu'aucune référence n'est manquante
npm run scan-i18n-gapsScanner les clés réellement utilisées dans le code source et les comparer avec le paquet de langue, signaler les clés non définies et non utilisées
npm run regenerate-i18n-localesRégénérer le paquet de langue réduit selon les résultats du scan

Le nom de l'action du journal d'audit utilise un registre séparé (i18n/auditActionRegistry.ts + auditActionLocaleDefaults.ts). Lors de l'ajout d'une action d'audit, il suffit d'ajouter une entrée dans le registre pour éviter que l'outil de découpage ne les supprime en les considérant comme des clés mortes non référencées.

Thème et apparence ​

  • Mode thème : frontend/src/composables/useTheme.ts fournit light | dark | system trois états. Le mode actif se définit en configurant l'attribut theme-mode sur document.documentElement ; le mode system écoute les requêtes médias prefers-color-scheme et suit automatiquement.
  • Variables CSS : frontend/src/assets/theme/theme.css définit deux ensembles de variables, :root[theme-mode="light"] et :root[theme-mode="dark"], selon le système de tokens TDesign (--td-brand-color-*, --td-bg-color-*, --td-text-color-*, police/arrondi/ombre, etc.), avec la couleur de la marque en vert ; les styles des composants utilisent systématiquement les variables pour un changement de thème en un clic.
  • Persistation des préférences : les préférences de thème et de police sont stockées via frontend/src/composables/preferenceStorage.ts dans localStorage sous l'espace de noms de l'id utilisateur ; elles sont rechargées par reloadThemeFromStorage() / reloadFontFromStorage() lors de la connexion/déconnexion/changement de compte (déclenché dans stores/auth.ts).
  • Police : frontend/src/composables/useFont.ts gère la sélection de la police dans l'interface, main.ts au démarrage + initTheme() + initFont().
  • Synchronisation sur desktop : syncWailsNativeChrome() dans useTheme.ts appelle le runtime Wails via WindowSetDarkTheme / WindowSetLightTheme / WindowSetBackgroundColour, pour que la couleur de fond de la fenêtre native corresponde au thème web, réduisant le flash blanc lors du rafraîchissement.

Construction et déploiement ​

Développement et construction (vite.config.ts) ​

frontend/vite.config.ts :

  • Double entrée : rollupOptions.input pour index.html et embed.html ; dev : plugin embedHtmlDevFallback() réécrit /embed/:channelId vers /embed.html.
  • Code splitting : manualChunks → vendor-mermaid, vendor-markdown, vendor-highlight ; embed filtre les chunks chat lourds au preload.
  • Versions : __FRONTEND_VERSION__ et __FRONTEND_COMMIT__ injectés au build.
  • Serveur de dev : ports 5173 / 4173 ; proxy /api, /files, /mcp/ vers VITE_DEV_PROXY_TARGET (défaut http://localhost:8080) ; WS 180 s, MCP 1 h.
  • Alias : @ → frontend/src ; correction entrée @vue-office/pptx.
  • Scripts : npm run dev / build / preview / type-check / test.

Production de l'image (Dockerfile + nginx) ​

frontend/Dockerfile:

  • Depuis v0.8.2, construction en deux étapes : le digest verrouillé node:24-bookworm-slim est exécuté avec $BUILDPLATFORM + npm run build, puis dist/ est copié dans la couche d'exécution. Pendant la construction, il n'est plus nécessaire d'installer Node / npm sur l'hôte, ni de générer préalablement dist/ (scripts/build_frontend_dist.sh reste utilisé pour Lite / packaging de bureau) ;
  • L'image de base de la couche d'exécution est fixée au digest verrouillé nginx:1.30.3-alpine (le commentaire interdit expressément de revenir à un tag flottant — les versions Alpine 3.24+ mises à jour ne peuvent pas démarrer sur un ancien noyau CentOS 7, ce qui avait causé des dysfonctionnements en v0.7.0) ;
  • nginx.conf est placé comme modèle dans /etc/nginx/templates/default.conf.template ; /api/, /mcp/ et les paramètres proxy partagés avec le téléchargement de compétences se trouvent dans nginx-api-proxy.conf (copiés tels quels dans /etc/nginx/api-proxy.conf), les fragments http se trouvent dans nginx-http.conf (en supprimant le format de journalisation api_no_query de la chaîne de requête). Le port 80 est exposé, l'entrée est docker-entrypoint.sh.

Paramètres de construction de l'image :

NomTypeValeur par défautDescription
NPM_REGISTRYbuild-argvidenpm ci Source de l'image à utiliser, vide utilisera la source par défaut de npm
NODE_MAX_OLD_SPACE_SIZEbuild-arg4096Limite maximale du tas Node à l'étape de construction (MB), pour éviter un OOM lors de la construction avec Vite
VITE_FRONTEND_COMMITbuild-argunknownCommit front-end injecté dans la page ; déclaré après npm ci, le modifier n'invalidera pas le cache des dépendances

frontend/docker-entrypoint.sh (Injection de configuration d'exécution) :

  1. Générer /usr/share/nginx/html/config.js, écrire MAX_FILE_SIZE_MB, MAX_SKILL_BUNDLE_SIZE_MB et DEFAULT_LOCALE dans window.__RUNTIME_CONFIG__ pour lecture à l'exécution côté front-end ;
  2. Utiliser envsubst pour rendre le modèle nginx ;
  3. Lancer nginx sur le front-end.
NomTypeValeur par défautDescription
MAX_FILE_SIZE_MBEntier (MB)50Limite du corps de toutes les requêtes et limite de téléchargement côté front
MAX_SKILL_BUNDLE_SIZE_MBEntier (MB)256Ne s'applique qu'à la route de téléchargement ZIP des compétences ; si inférieur à MAX_FILE_SIZE_MB, il est élevé à cette valeur, maximum 512
DEFAULT_LOCALEChaîneVideLangue de l'interface par défaut, seules les valeurs zh-CN / en-US / ru-RU / ko-KR / ja-JP sont autorisées, les autres valeurs sont rejetées
APP_HOSTChaîneappNom d'hôte backend
APP_PORTEntier8080Port du backend
APP_SCHEMEChaînehttpProtocole backend, pour un backend HTTPS distant, peut être défini sur https

frontend/nginx.conf — comportements clés :

  • Fallback SPA : try_files → index.html, index.html en no-cache ; /assets/* hashés cache 1 an immutable ;
  • Proxy API : /api/ et /files vers le backend ; SSE sans buffering, timeouts 3600 s, 3 retries upstream ;
  • MCP /mcp/ : même proxy que /api/ ; clients externes via le domaine du site ;
  • WebSocket : sandbox terminal/desktop et extension BrowserSkill ; logs sans query string ; /api/v1/local-browser/internal → 404 ;
  • Upload skills : /api/v1/skills/catalog et /api/v1/sandbox-configs/<id>/skills avec MAX_SKILL_BUNDLE_SIZE ;
  • Lien /r/ : proxy backend pour images IM (voir Intégration IM) ;
  • Embed /embed/* : embed.html + politique /_embed-frame-policy ; /weknora-widget.js pour sites tiers ;
  • gzip et en-têtes de sécurité par location (add_header non hérité).

Association avec le bureau (Wails) ​

frontend/src/wailsjs/ est le code de liaison généré automatiquement par le framework Wails (en-tête du fichier indiqué "automatically generated. DO NOT EDIT") :

  • wailsjs/go/main/App.d.ts / App.js : mises à jour, URLs API, HTTP desktop, GetAutoSetupToken pour auto-setup ;
  • wailsjs/runtime/ : contrôle fenêtre ; en navigateur, appels no-op via try/catch (useTheme.ts).

Le contenu de la fenêtre de l'application de bureau est ce code frontend ; la connexion automatique sur le bureau, la restauration des liens profonds et la zone de titre déplaçable marquée --wails-draggable sont tous des adaptations préparées pour le format de bureau.

Configurer la navigation et les capacités de déploiement ​

Configurer les entrées par groupe de tâches, la publication intégrée comprend des pages d’accès IM, intégration web, API, serveur MCP, CLI, extension Chrome, Claw Skill, etc. ; la configuration du bac à sable, les variables personnelles et l’espace / mémoire personnelle ont chacun une interface de gestion dans le centre de paramètres ; les compétences, les services MCP et la connexion au navigateur se trouvent dans la boîte à outils. Réutiliser integrations.ts, toolbox.ts, settingsAccess.ts et le regroupement barre latérale.

GET /api/v1/system/capabilities renvoie edition et supported / reason. Le front masque les entrées selon le même instantané (route, menu, paramètres, boîte à outils) ; échec de détection ou backend ancien → visible par défaut ; organizations masqué en Lite ; sandbox docker/host seulement si supported: true. Le backend reste autoritaire. Voir API système.

Documentation issue de WeKnora v0.9.0 · MIT License