Files
chlova/CHANGELOG.md
T
Kantin-Petit 4f3c85901e feat(web): UI responsive mobile (header, barre chat, review) (v0.35.0)
Header flex-wrap + détails masqués sous sm ; barre chat input min-w-0 +
boutons compacts + label Envoyer masqué sous sm ; actions Review empilées
pleine largeur sur mobile. Build web vert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016w5jRe87MGdd6AMvXQcHNi
2026-06-23 16:06:56 +02:00

20 KiB

Changelog

Format Keep a Changelog, versioning SemVer. Tant que le projet est en 0.x, chaque mineur peut introduire des changements incompatibles. Chaque ligne renvoie à un commit dédié (un artefact = un commit).

[Unreleased]

[0.35.0] — 2026-06-23 — UI responsive (mobile)

Fixed

  • Header : flex-wrap + paddings/marges réduits sur petit écran, « · N outils » masqué sous sm (ne déborde plus).
  • Barre chat : input en min-w-0, boutons shrink-0 compactés (px-2.5 sm:px-3), label « Envoyer » masqué sous sm → tient sur mobile.
  • Review : actions Approuver/Refuser pleine largeur empilées sous sm.
  • Web : typecheck + build OK.

[0.34.2] — 2026-06-23 — bump Ollama 0.30.10 (modèles :cloud)

Fixed

  • ollama/ollama:0.6.80.30.10 : 0.6.8 refuse les modèles :cloud (HTTP 412 « requires a newer version of Ollama »). Bump dans docker-compose.prod.yml et docker-compose.yml.

Changed

  • .env.example : OLLAMA_MODEL → choisir un tag :cloud valide (ex. qwen3-coder:480b-cloud), note sur Ollama >= 0.30.

[0.34.1] — 2026-06-23 — stack chlova déployé (placeholders), notes runbook

Added

  • Stack chlova déployé en GitOps sur local (id 10) : ollama running, backend + mcp-portainer en attente des vraies valeurs (placeholders).
  • docs/deploy.md : note « stack pré-créé » (éditer les 7 vars → Update) et contrainte PORTAINER_MCP_AUTH_TOKEN ≥ 32 caractères (sinon le serveur MCP Portainer refuse de démarrer — constaté au déploiement).

[0.34.0] — 2026-06-23 — intégration réelle passerelle MCP Portainer

Fixed

  • Image MCP Portainer : portainer/portainer-mcp:0.6.0 (tag inexistant) → 2.42.6 (confirmé Docker Hub). Découvert au déploiement réel (pull 404).
  • Modèle d'auth de la passerelle MCP Portainer corrigé : le serveur HTTP (port 17717, endpoint /mcp) attend Authorization: Bearer <secret de passerelle> et X-Portainer-API-Key: <clé API restreinte>. Le backend n'envoyait que le Bearer.

Added

  • config.portainerApiKey (PORTAINER_API_KEY, SECRET) : clé API Portainer restreinte de chlova, envoyée en X-Portainer-API-Key — c'est elle qui cloisonne l'accès. PORTAINER_MCP_AUTH_TOKEN devient le secret de passerelle.
  • McpServerConfig.extraHeaders : headers additionnels par serveur MCP.

Changed

  • docker-compose.prod.yml : mcp-portainer reconfiguré (2.42.6, :17717, PORTAINER_MCP_ALLOWED_HOSTS, plaintext HTTP interne, PORTAINER_TLS_VERIFY=0, PORTAINER_READ_ONLY). socket-proxy supprimé (la passerelle parle à l'API Portainer, plus aucun socket Docker monté = surface réduite). MCP_PORTAINER_URL:17717/mcp. Backend reçoit PORTAINER_API_KEY.
  • .env.example + docs/deploy.md (§3a, tableau variables) mis à jour.
  • Typecheck vert, 78 tests verts.

[0.33.0] — 2026-06-23 — infra locale déployée (gitea + n8n-chlova)

Added

  • infra/gitea/docker-compose.yml : serveur git Gitea 1.26.4 sur l'hôte local (réseau proxy, git.pogoo.app), source du GitOps de CHLOVA. Déployé via Portainer (stack id 6, running).
  • infra/n8n-chlova/docker-compose.yml : n8n dédié à CHLOVA (2.20.8) sur local (n8n-chlova.pogoo.app), MCP natif interne http://n8n-chlova:5678. Déployé via Portainer (stack id 7, running healthy).

Changed

  • Topologie cible repliée sur un seul hôte (local) : tout sur le réseau proxy, joignable en interne par nom de conteneur.
  • docker-compose.prod.yml : MCP_N8N_URLn8n-chlova, PORTAINER_URL → interne http://portainer:9000 (même hôte), sidecar mcp-portainer ajouté au réseau proxy (pour joindre le serveur Portainer).
  • docs/deploy.md réécrit pour la topologie locale (DNS, gitea, push, users restreints, déploiement GitOps, vérif).

[0.32.0] — 2026-06-23 — prêt au déploiement (GitOps Portainer, Phase 1)

Added

  • infra/docker-compose.prod.yml : compose de PRODUCTION pour GitOps Portainer. Sans env_file (secrets via variables de stack), réseau Traefik réel proxy (external), certresolver letsencrypt, backend joint proxy pour atteindre n8n en interne. Cible : env vps-pogoo-002.
  • docs/deploy.md : runbook Phase 1 — dépôt git, génération secrets, users restreints chlova (Portainer + n8n, étapes UI), variables de stack, déploiement, vérification, rollback, bascule Phase 2.
  • config.assertHasSurface() : refuse de démarrer si aucune surface (Telegram OU API/UI) n'est configurée. 3 tests (11 au total dans config).

Changed

  • Surface Telegram rendue optionnelle (telegramBotToken optionnel ; index.ts ne démarre la surface que si le token est présent). Permet le déploiement UI-only voulu. .env.example documenté en conséquence.
  • Typecheck vert, 78 tests verts.

[0.31.0] — 2026-06-23 — app mobile (React Native / Expo)

Added

  • Package mobile/ : app Expo SDK 56 (expo-router) réutilisant l'API backend. Écrans Login (mdp + TOTP), Chat (+ TTS expo-speech), Review (approuver/refuser). JWT en expo-secure-store, thème dark HUD, EXPO_PUBLIC_API_BASE configurable. tsc --noEmit vert. STT mobile reporté (lib native) ; TTS OK.
  • README racine : entrées web/ et mobile/.

[0.30.0] — 2026-06-23 — polish UI

Added

  • Icônes Lucide (SVG) partout (chat, voix, review, nav) — fini le texte/emoji.
  • Contexte appdata : état backend (phase/outils) + assets en attente partagés ; header affiche phase·outils, badge de review dans la nav, refresh après décision.

Changed

  • Review consomme appdata (plus de fetch local). Build OK, 0 vuln.

[0.29.0] — 2026-06-23 — fin Phase 6 (voix v1)

Added

  • useSpeech : mode mains-libres + wake-word « CHLOVA » (extractCommand), écoute en boucle, micro en pause pendant le TTS (anti auto-écoute).
  • Chat : bouton "Libre" (mains-libres) ; en mains-libres les réponses sont lues d'office. Indicateur d'écoute. Build OK. (README web : section voix.)

[0.28.0] — 2026-06-23 — début Phase 6 (voix)

Added

  • web/src/useSpeech.ts : hook voix 100 % navigateur (Web Speech API), STT (push-to-talk, fr-FR) + TTS, dégrade proprement si non supporté. Zéro backend/GPU.
  • Chat : bouton micro (dicter → envoyer), bascule "Voix ON/OFF" (persistée) qui lit les réponses à voix haute. Pas d'emoji comme icône (texte). Build OK.

[0.27.0] — 2026-06-23 — fin Phase 5 (auto-extension v1)

Added

  • Outil local chlova.propose_asset (src/autoext/tool.ts) exposé à l'agent : propose un asset → write+commit+doc → need-review. Notion d'outil sanctionné (ToolSpec.sanctioned) autorisé par le gatekeeper mais audité.
  • Config CHLOVA_AUTOEXT_ENABLED (défaut false) + CHLOVA_REPO_ROOT. Câblage Phase 2 + flag. Prompt système Phase 2 mis à jour (palier honnête imposé).
  • Tests (2) : gatekeeper autorise un outil sanctionné ; tool propose. 75 tests.

Changed

  • .env.example + compose : flag autoext + montage dépôt (commenté). docs/need-review.md : section auto-extension. Compose revalidé, 0 vuln.

[0.26.0] — 2026-06-23

Added

  • src/autoext/git-committer.ts : GitCommitter — commits ciblés (jamais git add -A), auteur CHLOVA, renvoie le SHA.
  • src/autoext/auto-extension.ts : AutoExtensionService.propose — write+doc → commit+version → enregistre l'asset en need-review (privilégié = BLOQUÉ, aucun sursis) → alerte asset_created (version + commit + doc). N'exécute jamais l'asset.
  • Alerte asset_created. 3 tests (dépôt git temp). 73 tests, 0 vuln.

[0.25.0] — 2026-06-23 — début Phase 5 (auto-extension)

Added

  • src/autoext/artifact-writer.ts : écriture d'un asset auto-créé (artefact + doc générée depuis le gabarit), chemins sanitizés (anti-traversée), version semver validée. slugify, artifactRelPath, docRelPath, renderDoc, writeArtifact. 5 tests (dépôt temp).

[0.24.0] — 2026-06-23 — fin Phase 4 (UI v1 : chat + review)

Added

  • UI : vue Review (web/src/pages/Review.tsx) — liste des assets en attente, approuver / refuser (confirmation sur refus, palier coloré), refresh, 401→logout.
  • Backend sert le SPA same-origin (@fastify/static 9.1.3 + fallback routes client) si CHLOVA_WEB_ROOT présent ; config webRoot.

Changed

  • Dockerfile multi-stage : build web + API (contexte = racine dépôt), image embarque le SPA (/app/web, CHLOVA_WEB_ROOT par défaut). Compose : contexte .., dockerfile: orchestrator/Dockerfile, image chlova/backend:0.2.0. Compose revalidé. 65 tests, 0 vuln.

[0.23.0] — 2026-06-23

Added

  • UI : vue Chat (web/src/pages/Chat.tsx) — conversation avec l'agent via POST /api/chat, bulles user/assistant, état "réfléchit", auto-scroll, gestion d'erreur, déconnexion auto sur 401. Build OK.

[0.22.0] — 2026-06-23

Added

  • Package web/ : scaffold UI (React 19 + Vite 8 + Tailwind 4 + react-router 7, PWA). Tokens dark HUD "Jarvis-red" (docs/ui-design.md), client API (api.ts), contexte auth JWT (auth.tsx), shell + garde de route, écran Login (mdp + TOTP). Pages Chat/Review en stubs (v0.23/0.24). npm run build OK, 0 vuln.

[0.21.0] — 2026-06-23

Added

  • orchestrator/scripts/provision-auth.ts (+ npm run provision-auth) : génère hash mdp scrypt + secret TOTP + otpauth:// + JWT secret pour .env.
  • Compose : backend exposé via Traefik + TLS (réseau traefik-public externe, labels router/tls), CHLOVA_DOMAIN. Surface unique exposée.
  • .env.example : section API/UI (admin/hash/TOTP/JWT/web-origin/domaine).
  • docs/security.md : section surface exposée Phase 4 (login fort, rate-limit, CORS, fail-safe). Compose revalidé.

[0.20.0] — 2026-06-23

Added

  • src/api/routes.ts : API HTTP (registerApi) — POST /api/auth/login (rate-limit serré), JWT Bearer sur le reste, POST /api/chat, GET /api/review, POST /api/review/:id/{approve,refuse}, GET /api/state. CORS restreint + rate-limit global. Réutilise ChatService + ReviewService.
  • Config auth API (CHLOVA_ADMIN_USER/_PASSWORD_HASH/_TOTP_SECRET/_JWT_SECRET, CHLOVA_WEB_ORIGIN) + helper apiAuth() ; API activée seulement si configurée.
  • Câblage index.ts (API montée si auth présente). Deps @fastify/cors, @fastify/rate-limit épinglées. 5 tests API (inject). 65 tests, 0 vuln.

[0.19.0] — 2026-06-23 — début Phase 4 (UI : auth + service chat)

Added

  • src/api/auth.ts : auth surface exposée — mot de passe scrypt (node:crypto), TOTP 2FA (otplib), JWT HS256 (jose), login tout-ou-rien. 10 tests.
  • src/agent/chat-service.ts : ChatService (un tour d'agent par message), partagé par toutes les surfaces. Telegram refactoré pour l'utiliser.
  • Deps épinglées jose 6.2.3, otplib 13.4.1 (npm audit 0 vuln).

[0.18.0] — 2026-06-23 — fin Phase 3 (alertes)

Added

  • workflows-n8n/chlova-alerts.v1.0.0.json : workflow n8n webhook → mail (formate selon le type d'alerte). Exporté en JSON (le dépôt fait foi).
  • docs/assets/workflow-chlova-alerts.md : doc d'asset (rôle, IO, deps, sécurité, rollback) — palier privileged.

Changed

  • .env.example + compose : variable ALERT_WEBHOOK_URL (vide = log-only).
  • docs/need-review.md : section alertes marquée implémentée. Compose revalidé.

[0.17.0] — 2026-06-23

Added

  • Config ALERT_WEBHOOK_URL (optionnel, traité comme secret) → HttpAlertSender, sinon NullAlertSender.
  • Gatekeeper : hook onFirstProvisionalExec (alerte immédiate à la 1ʳᵉ exécution d'un asset PROVISOIRE) ; onBlockedAttempt route désormais vers une vraie alerte.
  • src/alerts/scheduler.ts : runAlertCycleOnce + startAlertScheduler (digest quotidien + rappel J-1). Câblé en Phase 2 (cron + alertes), arrêt propre.
  • Tests (3) : émission 1ʳᵉ exéc unique, cycle J-1 + digest.

[0.16.0] — 2026-06-23 — début Phase 3 (alertes)

Added

  • Module src/alerts/ : AlertEvent (blocked / first-exec / J-1 / digest sans secret), HttpAlertSender (POST webhook n8n, fail-soft) + NullAlertSender (log-only fail-safe), builders purs buildDailyDigest / selectExpiringSoon.
  • Tests alerts (6) : payload, fail-soft, digest, fenêtre J-1.

[0.15.1] — 2026-06-23

Changed

  • Fige le chemin de l'endpoint MCP natif n8n : MCP_N8N_URL = …/mcp-server/http (hôte interne préféré, URL publique TLS possible). Note egress (networks.md).

[0.15.0] — 2026-06-23

Changed

  • MCP n8n = natif (instance n8n ≥ 2.18.4) au lieu d'un conteneur dédié : suppression du service mcp-n8n du compose ; MCP_N8N_URL pointe vers l'endpoint MCP de l'instance n8n, auth par "MCP Access Token" (Bearer). MCP Portainer reste un sidecar officiel. Aucun changement de code (le registry parle déjà HTTP+Bearer). Docs (CLAUDE.md, architecture, networks) + .env.example mis à jour. Compose revalidé (services : ollama, socket-proxy, mcp-portainer, backend).

[0.14.0] — 2026-06-23 — fin Phase 2 (écriture + need-review)

Added

  • docs/need-review.md : documentation complète du cycle (états, sursis, gatekeeper, cron, review, gate de phase, rollback).

Changed

  • .env.example + infra/docker-compose.yml : variable CHLOVA_PHASE (défaut 1), note PORTAINER_READ_ONLY selon phase.
  • docs/risk-tiers.md, orchestrator/README.md : application par phase (P1 read-only / P2 gatekeeper). Compose revalidé.

[0.13.0] — 2026-06-23

Added

  • src/gatekeeper/review.ts : ReviewService (approuver/refuser/lister), runExpiryOnce + startExpiryCron (cron horaire PROVISOIRE→BLOQUÉ).
  • src/surfaces/commands.ts : commandes owner Telegram /pending, /approve, /refuse, /help (hors boucle agent — le LLM n'y a pas accès).
  • Câblage Phase 2 : review + cron démarrés, routage commande/agent dans Telegram, arrêt propre du cron. 10 tests (review + commandes + cron).

[0.12.0] — 2026-06-23

Added

  • registry.listAllTools() : expose tous les outils (mutants inclus) en Phase 2, contrôle d'exécution délégué au gatekeeper. Refactor collect() partagé.
  • buildSystemPrompt(phase) : prompt phase-aware (lecture seule vs écriture sous review), conserve le cadrage anti-prompt-injection.
  • Câblage index.ts par phase : Phase 1 = read-only + ReadOnlyGuard ; Phase 2 = tous outils + GatekeeperGuard sur AssetRepository (hook d'alerte sur asset bloqué), /health reflète la phase, fermeture propre du repo.

[0.11.0] — 2026-06-23

Added

  • src/gatekeeper/gatekeeper.ts : service Gatekeeper (vérifie le statut AVANT chaque exécution) + GatekeeperGuard. Privilégié inconnu → enregistré BLOQUÉ, refusé jusqu'à review, hook d'alerte onBlockedAttempt ; approuvé → exécutable
    • incrément du compteur. Lecture seule → autorisée sans asset.
  • Gate de phase CHLOVA_PHASE (défaut 1, fail-safe) dans la config.
  • Tests gatekeeper service (5) + phase config (2).

Changed

  • assertReadOnlyPhase devient phase-aware : Phase 1 exige read-only ; Phase 2 autorise PORTAINER_READ_ONLY=false.

[0.10.0] — 2026-06-23 — début Phase 2 (écriture + need-review)

Added

  • src/gatekeeper/repository.ts : AssetRepository SQLite (node:sqlite, zéro dépendance native) — schema table assets, CRUD, listByStatus, incrementExec, setRiskTier (anti-escalade), expireProvisional (cron PROVISOIRE→BLOQUÉ).
  • Tests repository (6) : persistance, anti-escalade, expiration du sursis.

Changed

  • Node 24 (sqlite natif stable) : engines, base Dockerfile node:24.13, @types/node 24, copie tsconfig.build.json dans l'image. npm audit 0 vuln.

[0.9.0] — 2026-06-23 — fin Phase 1 (cerveau lecture seule)

Added

  • src/gatekeeper/assets.ts : interfaces du cycle "need review" posées pour la Phase 2 (table Asset, sursis 7 j réversible / blocage immédiat privilégié, assertNoEscalation anti-escalade, canExecute). Non câblé au runtime P1.
  • Tests Vitest (22) : readonly-filter (fail-safe + tiers), gatekeeper (Guard read-only, sursis par palier, invariant anti-escalade, canExecute), config (fail-closed, verrou lecture seule, masquage des secrets).

Changed

  • Split TS config : tsconfig.json (typecheck+tests, noEmit) / tsconfig.build.json (emit dist/, rootDir src).

[0.8.0] — 2026-06-23

Added

  • src/surfaces/telegram.ts : surface Telegram long-polling (zéro port publié), allowlist d'IDs obligatoire, backoff sur erreur.
  • src/gatekeeper/guard.ts : ReadOnlyGuard (barrière n°2, défense en profondeur) — n'autorise que reversible+readOnly.
  • src/agent/system-prompt.ts : cadrage anti-prompt-injection (données ≠ instructions).
  • src/index.ts : câblage complet Phase 1 (MCP read-only → cerveau → Telegram), arrêt propre SIGTERM/SIGINT. npm run build vert.

[0.7.0] — 2026-06-23

Added

  • src/mcp/readonly-filter.ts : barrière lecture seule — n'expose que les outils readOnlyHint === true (fail-safe : absence d'annotation ⇒ écarté) ; déduit le palier de risque (jamais déclaré par le LLM).
  • src/mcp/registry.ts : connexion MCP HTTP authentifiée (n8n + Portainer), liste + filtre les outils read-only en ToolHandle, sérialise les résultats.

Changed

  • tsconfig : retrait de exactOptionalPropertyTypes (interop SDK MCP) ; reste strict (strict, noUncheckedIndexedAccess, noImplicitOverride).

[0.6.0] — 2026-06-23

Added

  • Client Ollama /api/chat (src/llm/ollama.ts) : modèles cloud via proxy, auth Bearer, timeout, tool-calling, erreurs sans fuite de secret.
  • Boucle agent (src/agent/loop.ts + types.ts) : comprendre → outil → observer → répondre, garde-fou anti-boucle, audit par appel, Guard injecté (abstraction prête pour le gatekeeper Phase 2). ToolHandle indépendant de MCP.

[0.5.0] — 2026-06-23 — début Phase 1 (cerveau lecture seule)

Added

  • Squelette orchestrateur TS (Node 22, ESM strict, Fastify) : config.ts fail-closed (zod, verrou assertReadOnlyPhase, redactedConfig), audit/log.ts (pino + journal d'exécutions), index.ts (bootstrap + healthcheck interne), Dockerfile multi-stage (base épinglée, user non-root), vitest.config.ts, orchestrator/README.md.
  • Dépendances épinglées, npm audit à 0 vulnérabilité.

[0.4.0] — 2026-06-23 — fin Phase 0 (socle)

Added

  • infra/docker-compose.yml : stack CHLOVA — Ollama (proxy cloud, interne + egress, aucun port publié), socket-proxy (lecture seule), MCP n8n + MCP Portainer (read-only), backend (seule surface, aucun port publié en P1). Images à tags épinglés (digests à confirmer avant déploiement réel), réseaux chlova-internal (internal) / chlova-egress. Config validée (compose config).

[0.3.0] — 2026-06-23

Added

  • Socle sécurité : docs/security.md (modèle de menace prompt-injection + défenses par couche + invariants testés), infra/networks.md (réseaux interne vs egress, ports, egress filtré ollama.com), infra/socket-proxy/README.md (filtrage des endpoints Docker, lecture seule P1).
  • .gitattributes : normalisation LF (scripts/compose en LF strict).

[0.2.0] — 2026-06-23

Added

  • Conventions versioning/doc : docs/versioning.md (SemVer, un-artefact-un-commit, pinning images, export workflows n8n), docs/asset-template.md (gabarit doc), docs/risk-tiers.md (réversible vs privilégié, invariant anti-escalade), docs/architecture.md (schéma + invariants + composants).

Changed

  • .gitignore : ignore .claude/settings.local.json (réglages locaux).

[0.1.0] — 2026-06-23

Added

  • Scaffold du dépôt : CLAUDE.md (architecture + règles non négociables), README.md, CHANGELOG.md, .env.example, .gitignore.
  • Squelette d'arborescence : docs/, infra/, orchestrator/, workflows-n8n/.