fix(version): BUG-047 la version suit chaque livraison (source unique VERSION + bump SemVer automatique)
VERSION (racine) devient la source unique de verite MAJEUR.MINEUR.CORRECTIF, incrementee a chaque commit par le hook prepare-commit-msg (BREAKING -> majeur, feat -> mineur, sinon correctif) ; post-commit rattache les fichiers derives au commit et cree le tag vX.Y.Z, publie au push (push.followTags). Tous les derives sont resynchronises : package.json, desktop Tauri, README.md/README.fr.md, docs/ROADMAP.md, CHANGELOG.md. Backend, image Docker et desktop lisent le meme fichier (plus de numero code en dur). Outils : scripts/bump_version.py, scripts/install-hooks.sh. Tests : tests/test_version.py (46, garde-fou de coherence globale).
This commit is contained in:
@@ -17,8 +17,9 @@ la checklist du §5 n'est pas entièrement verte, **CI compris**.
|
||||
|
||||
| Fichier | Rôle | Quand le mettre à jour |
|
||||
|---|---|---|
|
||||
| [`VERSION`](../VERSION) (racine) | **Version livrée** — source unique de vérité (SemVer `MAJEUR.MINEUR.CORRECTIF`) | Automatiquement à chaque commit (hook `.githooks/prepare-commit-msg`) |
|
||||
| [`docs/ROADMAP.md`](./ROADMAP.md) | Travail **à venir** (🔵 En cours + ⚪ Backlog) + index du complété | Au début (statut) et à la fin (index) |
|
||||
| [`CHANGELOG.md`](../CHANGELOG.md) | Historique officiel par version (Keep a Changelog) | À chaque livraison, dans `[Unreleased]` |
|
||||
| [`CHANGELOG.md`](../CHANGELOG.md) | Historique officiel par version (Keep a Changelog) | À chaque livraison : écrire dans `[Unreleased]` (publié en `[X.Y.Z] — date` par le bump) |
|
||||
| [`docs/features/<slug>.md`](./features/) | **Conception / spec détaillée** d'une grosse feature | Quand l'item est livré |
|
||||
| [`docs/archive/COMPLETED_v1-v2.md`](./archive/COMPLETED_v1-v2.md) | Détail des items courts livrés | Quand l'item est livré |
|
||||
| [`docs/ISSUES_TODOLIST.md`](./ISSUES_TODOLIST.md) | Registre des **bugs / TODO** | À chaque bug (statut + correctif/commit) |
|
||||
@@ -52,8 +53,11 @@ la checklist du §5 n'est pas entièrement verte, **CI compris**.
|
||||
4. **Vérifier en local** — exécuter les commandes du §6.
|
||||
5. **Documenter** — CHANGELOG `[Unreleased]`, Roadmap / ISSUES, fiche feature ou archive, guide
|
||||
utilisateur + i18n FR/EN, README si besoin, OpenAPI si API.
|
||||
6. **Commit** — message conventionnel (`feat:`, `fix:`…) référençant `#NN` / `BUG-NNN`.
|
||||
7. **Push** puis **vérifier le CI vert** (jobs `lint`, `test`, `security`, `build`, `e2e`).
|
||||
6. **Commit** — message conventionnel (`feat:`, `fix:`…) référençant `#NN` / `BUG-NNN` : le
|
||||
préfixe détermine l'incrément SemVer de `VERSION` (MAJEUR / MINEUR / CORRECTIF), appliqué
|
||||
automatiquement par le hook `.githooks/prepare-commit-msg`.
|
||||
7. **Push** puis **vérifier le CI vert** (jobs `lint`, `test`, `security`, `build`, `e2e`) ; le
|
||||
tag `vX.Y.Z` de la version livrée est publié avec la branche (`push.followTags`).
|
||||
8. **Clôturer** — statut `🟢 corrigé` / index `✅` posé par l'IA ; l'utilisateur valide (`✅ vérifié`).
|
||||
|
||||
---
|
||||
@@ -74,6 +78,7 @@ la checklist du §5 n'est pas entièrement verte, **CI compris**.
|
||||
- [ ] E2E Playwright si flow UI critique touché
|
||||
|
||||
### Documentation
|
||||
- [ ] `VERSION` incrémenté et dérivés synchronisés (automatique via le hook ; `tests/test_version.py` vert)
|
||||
- [ ] `CHANGELOG.md` → `[Unreleased]` (section Ajouté / Modifié / Corrigé)
|
||||
- [ ] `docs/ROADMAP.md` → statut mis à jour + ligne dans l'index « Complété »
|
||||
- [ ] Fiche `docs/features/<slug>.md` **ou** `docs/archive/` si l'item est livré
|
||||
@@ -113,9 +118,22 @@ npx playwright test
|
||||
|
||||
## 7. Versionnement & release
|
||||
|
||||
- **SemVer** `MAJOR.MINOR.PATCH` ; tags Git `vX.Y.Z` ; source de vérité = `CHANGELOG.md`.
|
||||
- Lors d'une publication : déplacer `[Unreleased]` vers `[X.Y.Z] — date`, tagger, builder et
|
||||
publier (procédure détaillée dans [DEVELOPMENT_AND_RELEASES.md](./DEVELOPMENT_AND_RELEASES.md)).
|
||||
- **Source unique de vérité : le fichier [`VERSION`](../VERSION)** (racine du dépôt), au format
|
||||
`MAJEUR.MINEUR.CORRECTIF` (SemVer). Il est incrémenté **automatiquement à chaque commit** par
|
||||
le hook versionné `.githooks/prepare-commit-msg` — `!:` / `BREAKING CHANGE` → **MAJEUR**, `feat` →
|
||||
**MINEUR**, tout le reste → **CORRECTIF** — puis tagué `vX.Y.Z` par `.githooks/post-commit`
|
||||
(tag publié au push grâce à `push.followTags`). Installation une fois par clone :
|
||||
`scripts/install-hooks.sh`.
|
||||
- Le même commit resynchronise les dérivés : `package.json`, desktop Tauri (`tauri.conf.json`,
|
||||
`Cargo.toml`, `Cargo.lock`), `README.md`/`README.fr.md`, `docs/ROADMAP.md`, et publie la
|
||||
section `[Unreleased]` du `CHANGELOG.md` en `[X.Y.Z] — date`.
|
||||
- Le backend (`backend/version.py`), l'image Docker (`COPY VERSION`) et le desktop Tauri lisent
|
||||
ce fichier : la version affichée par l'UI (`/api/health` → header, boîte À propos) suit donc
|
||||
chaque livraison.
|
||||
- **Garde-fou** : `tests/test_version.py::TestRepoVersionAlignment` échoue dès qu'un dérivé
|
||||
diverge de `VERSION` (numéro codé en dur, CHANGELOG sans section, README non resynchronisé).
|
||||
- Bump manuel si besoin : `scripts/bump_version.py --dry-run|--minor|--set X.Y.Z|--push`.
|
||||
Commit sans incrément (cas exceptionnel) : `SKIP_VERSION_BUMP=1 git commit …`.
|
||||
- **Ne jamais** réécrire une version déjà publiée dans le CHANGELOG.
|
||||
|
||||
---
|
||||
|
||||
@@ -164,40 +164,67 @@ Document produit (URLs construites vers les assets de la release) :
|
||||
|
||||
---
|
||||
|
||||
## 3. Commit, Push & Tagging Git
|
||||
## 3. Version, Commit & Push
|
||||
|
||||
Une fois les modifications testées et validées :
|
||||
### Source unique de vérité : `VERSION`
|
||||
|
||||
1. **Commit et Push du code source** :
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: préparation release v2.0.0"
|
||||
git push origin main
|
||||
```
|
||||
*Ceci déclenchera la vérification CI standard sur Gitea (lint, tests unitaires, build Docker).*
|
||||
Le fichier **`VERSION`** à la racine du dépôt contient la version livrée au format
|
||||
`MAJEUR.MINEUR.CORRECTIF`. C'est la **seule** source : elle est incrémentée à chaque
|
||||
commit et tout le reste en découle.
|
||||
|
||||
2. **Création du Tag de Version** :
|
||||
```bash
|
||||
git tag -a v2.0.0 -m "Release v2.0.0"
|
||||
git push origin v2.0.0
|
||||
```
|
||||
| Dérivé | Contenu |
|
||||
|---|---|
|
||||
| `backend/version.py` | lit `VERSION` (priorité : `OBSIGATE_VERSION` > `./VERSION` > `backend/VERSION` > tag git) et l'expose via `/api/health` |
|
||||
| `Dockerfile` | `COPY VERSION ./VERSION` — plus aucun numéro codé en dur dans l'image |
|
||||
| `build.sh` / CI | affichent la version lue dans `VERSION` |
|
||||
| `desktop/build.rs` | injecte `VERSION` dans `GIT_VERSION` (repli `git describe`) |
|
||||
| `package.json`, `desktop/tauri.conf.json`, `desktop/Cargo.{toml,lock}`, `README.md`, `README.fr.md`, `docs/ROADMAP.md`, `CHANGELOG.md` | resynchronisés automatiquement à chaque incrément |
|
||||
|
||||
### Bump automatisé (recommandé)
|
||||
### Incrément automatique (hooks git versionnés)
|
||||
|
||||
`scripts/bump_version.sh` calcule la prochaine version depuis les commits
|
||||
(Conventional Commits), **synchronise la version desktop**
|
||||
(`tauri.conf.json`, `Cargo.toml`, `Cargo.lock`), crée un commit de release puis
|
||||
le tag :
|
||||
`scripts/install-hooks.sh` (une seule fois par clone) pose `core.hooksPath=.githooks`
|
||||
et `push.followTags=true`. Ensuite, chaque commit incrémente la version selon son
|
||||
message (Conventional Commits) :
|
||||
|
||||
| Message de commit | Incrément |
|
||||
|---|---|
|
||||
| `!:` ou `BREAKING CHANGE:` | MAJEUR — `x.0.0` |
|
||||
| `feat:` / `feat(scope):` | MINEUR — `x.y.0` |
|
||||
| `fix:`, `perf:`, `docs:`, … | CORRECTIF — `x.y.z` |
|
||||
|
||||
`.githooks/prepare-commit-msg` incrémente `VERSION`, resynchronise les fichiers dérivés
|
||||
et publie la section `[Unreleased]` du CHANGELOG en `[X.Y.Z] — date`. `.githooks/post-commit`
|
||||
rattache ces fichiers au commit qui vient d'être créé (git fige l'arbre avant
|
||||
`prepare-commit-msg` : un `git add` à cet instant ne serait repris qu'au commit suivant —
|
||||
d'où un `--amend` immédiat, le commit n'étant pas encore poussé) puis crée le tag `vX.Y.Z`,
|
||||
publié automatiquement au push (`push.followTags`). Aucun incrément pour un merge, un
|
||||
revert, un `chore(release)` ou un `--amend`.
|
||||
|
||||
Livraison type :
|
||||
|
||||
```bash
|
||||
scripts/bump_version.sh --dry-run # prévisualiser la prochaine version
|
||||
scripts/bump_version.sh # bump + commit + tag (local)
|
||||
scripts/bump_version.sh --push # idem + push branche & tag
|
||||
git add <chemins explicites> # pas de `git add -A` (test_vault = brouillon utilisateur)
|
||||
git commit -m "fix(ai): BUG-047 …" # → VERSION incrémentée + tag vX.Y.Z créé
|
||||
git push origin main # → branche + tag publiés
|
||||
```
|
||||
|
||||
Contournement ponctuel (commit sans incrément) : `SKIP_VERSION_BUMP=1 git commit …`.
|
||||
|
||||
### Bump manuel / outillage
|
||||
|
||||
```bash
|
||||
scripts/bump_version.py --print-version # version courante
|
||||
scripts/bump_version.py --dry-run # prochaine version, sans rien écrire
|
||||
scripts/bump_version.py --minor # incrément forcé + resynchronisation
|
||||
scripts/bump_version.py --set 3.0.0 # version imposée
|
||||
scripts/bump_version.py --major --commit --tag --push
|
||||
scripts/bump_version.sh … # même outil (wrapper historique)
|
||||
```
|
||||
|
||||
> La version desktop doit être synchronisée avec le tag pour que l'updater Tauri
|
||||
> détecte les mises à jour (`latest.json` reprend la version de
|
||||
> `tauri.conf.json`). `--no-files` conserve l'ancien comportement (tag seul).
|
||||
> détecte les mises à jour (`latest.json` reprend la version de `tauri.conf.json`) :
|
||||
> l'incrément automatique s'en charge.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
- **Projet** : ObsiGate — Porte d'entrée web pour vaults Obsidian
|
||||
- **Stack** : Python 3.11+ (backend FastAPI) · JavaScript/Vanilla (frontend) · Tauri/Rust (desktop)
|
||||
- **Dernière mise à jour** : 2026-09-15
|
||||
- **Dernière mise à jour** : 2026-09-16
|
||||
|
||||
---
|
||||
|
||||
@@ -156,6 +156,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
||||
| *BUG-044* | [🟡 IMPORTANT] Capacités des modèles IA erronées : aucun modèle Mistral n'est détecté « Vision capable » (et des modèles texte sont annoncés « Embeddings ») | 🟢 corrigé | P1 | ⚙️ backend + 🔌 api | IA | `backend/model_capabilities.py`, `backend/provider_capabilities.py`, `backend/main.py`, `backend/ai_routes.py` | `curl -H "Authorization: Bearer $MISTRAL_API_KEY" https://api.mistral.ai/v1/models` puis `GET /api/ai/model-capabilities?provider=mistral&model=mistral-small-latest` | Nouveau calque **déclaratif** (`backend/provider_capabilities.py`) : les capacités publiées par le fournisseur (Mistral `capabilities`, OpenRouter `architecture`) sont lues et mises en cache par `GET /api/config/ai-models` ; elles **priment** sur la table statique, qui ne comble plus que les drapeaux non déclarés (et sert de repli hors ligne / sans clé). Table statique corrigée : familles vision Mistral (`ministral`, `magistral`, `mistral-small`, `mistral-medium`, `mistral-vibe-cli`, `labs-leanstral`), `mistral-ocr` = vision sans chat, défaut fournisseur Mistral sans `embeddings`. Tests : `tests/test_provider_capabilities.py`, `tests/test_model_capabilities.py::TestMistralFamilies`, `tests/test_ai_models.py::TestDeclaredCapabilities` | Le panneau de modèle par défaut et la bulle ⓘ n'affichaient **aucun** Mistral vision alors que l'API en déclare 28 ; seul le motif `pixtral` (retiré de l'API) matchait. Effet secondaire corrigé : `mistral-large-latest` / `codestral-latest` étaient annoncés « Embeddings » (défaut fournisseur). La porte vision de l'assistant (`bookslm_routes.py`) accepte désormais les images avec un modèle Mistral vision |
|
||||
| *BUG-045* | [🟡 IMPORTANT] Éditeur « Editer » : deux barres de défilement superposées sur les documents longs | 🟢 corrigé | P1 | 📱 frontend | Éditeur | `frontend/style.css` | Ouvrir un fichier long (ex. IT/Docker Guide.md), cliquer Editer, mesurer `#editor-body` et `.cm-scroller` | `.editor-body-cm` gardait `overflow:auto` et un `.cm-editor{height:100%}` sous la rangée barre d'outils IA → le corps (toolbar+éditeur) ET le scroller CodeMirror débordaient simultanément. L'override global legacy `.cm-scroller{min-height:100%;overflow-y:auto!important}` aggravait. Passé en flex column : corps `overflow:hidden`, toolbar `flex:0 0 auto`, `.cm-editor` `flex:1 1 auto; height:auto`, seul le scroller défile ; override legacy retiré. Test : `tests/frontend/editor-inline.test.mjs` (+1) ; vérifié Playwright sur l'instance de test (un seul conteneur scrollable). |
|
||||
| *BUG-046* | [🔴 BLOQUANT] Assistant IA : « Échec de l'action : [object Object] » à l'application d'un ajout de texte au document courant | 🟢 corrigé | P0 | 📱 frontend + ⚙️ backend | IA | `frontend/js/bookslm.js`, `backend/bookslm.py`, `backend/bookslm_routes.py` | Mode agent : demander d'ajouter du texte au document ouvert puis cliquer « Appliquer » | Trois causes : (1) continuation de confirmation avec `payload:null` → second « Appliquer » sans `message` → 422 ; (2) `new Error(detail)` sur un `detail` tableau d'objets FastAPI → « [object Object] » ; (3) prompt documents/directory sans nom de vault → le modèle inventait `"vault":"test"` → échec silencieux de l'outil. Nouveau `_responseError()` (aplatit tableau/objet), payload porté à la continuation, bloc « Ces documents appartiennent au vault « X » » + consigne outils d'écriture (`build_system_prompt(vault_name=...)`). `SW_VERSION` v20. Tests : `tests/test_bookslm.py::test_vault_name_guidance`, `tests/frontend/ai.test.mjs` (+2). |
|
||||
| *BUG-047* | [🔴 BLOQUANT] La version affichée par l'application ne suit pas les livraisons : 66 commits livrés depuis v2.2.1 et l'UI/API restent bloquées sur `2.2.1` (et les numéros codés en dur divergent : `package.json` 1.0.0, desktop Tauri 2.0.0, `Dockerfile` 2.2.1, README 1.7.0) | 🟢 corrigé | P0 | ⚙️ build + 📄 docs | IA | `VERSION` (nouveau), `scripts/bump_version.py` (nouveau), `.githooks/prepare-commit-msg` + `.githooks/post-commit` (nouveaux), `scripts/install-hooks.sh` (nouveau), `backend/version.py`, `Dockerfile`, `docker-compose.yml`, `build.sh`, `.gitea/workflows/ci.yml`, `desktop/build.rs`, `tests/test_version.py` (nouveau) | `git tag -l \| tail -1` puis `python scripts/bump_version.py --print-version` ; `curl -s http://localhost:2020/api/health \| jq .version` | Le numéro provenait du **dernier tag git** et aucun tag n'était créé aux livraisons (`bump_version.sh` jamais appelé) → version figée, plus quatre numéros codés en dur ailleurs. Corrigé : **`VERSION` (racine) = source unique de vérité**, incrémentée automatiquement à chaque commit par le hook versionné `prepare-commit-msg` (SemVer : `!:`/`BREAKING CHANGE` → MAJEUR, `feat` → MINEUR, sinon CORRECTIF), tag `vX.Y.Z` créé par `post-commit` et publié au push (`push.followTags`) ; `bump_version.py` resynchronise `package.json`, desktop Tauri, ROADMAP, READMEs et fait la rotation du CHANGELOG dans le même commit ; backend, image Docker (`COPY VERSION`) et desktop lisent ce fichier. Contournement ponctuel : `SKIP_VERSION_BUMP=1`. | Garde-fou : `tests/test_version.py::TestRepoVersionAlignment` échoue dès qu'un dérivé diverge de `VERSION`. Vérifié : pytest complet vert, ruff/mypy 0, `/api/health` → `2.3.0` sur l'instance de test. |
|
||||
| | | | | | | | | | | |
|
||||
|
||||
### TODOs techniques (améliorations / nouvelles tâches)
|
||||
@@ -199,6 +200,7 @@ Avant de corriger quoi que ce soit, un agent IA doit :
|
||||
| 2026-09-14 | BUG-043, #82 | Correction | `frontend/js/ai.js`, `frontend/js/bookslm.js`, `frontend/js/config.js`, `tests/frontend/ai.test.mjs`, `docs/features/ai-provider-picker.md` | La liste des fournisseurs de la barre latérale de l'assistant suit désormais la configuration du projet : nouveau `refreshAIPickers()` (`ai.js`) qui reconstruit chaque picker monté dans son emplacement `.ai-picker-slot` (host conservé dans la barre de l'assistant, montage par `replaceChildren`), appelé après `saveAIKeys()` et `deleteAIKey()` (`config.js`) ; slot préservé même sans fournisseur configuré (le premier fournisseur ajouté s'y monte) ; sélection persistée d'un fournisseur non configuré purgée de `obsigate_ai_picker` (retour au défaut, modèle effacé). Vérifié : tests frontend 66/66 (IA) + 9 suites JSDOM vertes, validate-imports 36 modules, pytest 963 passed / 6 skipped, ruff OK, et vérification en navigateur (Playwright) sur l'instance de test : ajout de `nvidia` → fournisseur visible sans rechargement, retrait → disparition + sélection réinitialisée (`{"provider":null,"model":null}`), un seul montage du picker dans son host. CI Gitea verte (lint, test, security, build, e2e). |
|
||||
| 2026-09-15 | BUG-044 | Correction | `backend/provider_capabilities.py` (nouveau), `backend/model_capabilities.py`, `backend/main.py`, `backend/ai_routes.py`, `tests/test_provider_capabilities.py` (nouveau), `tests/test_model_capabilities.py`, `tests/test_ai_models.py`, `docs/features/ai-provider-picker.md`, `CHANGELOG.md` | BUG-044 : les capacités des modèles IA sont désormais lues chez le fournisseur quand il les publie (Mistral `capabilities`, OpenRouter `architecture`, détection par forme du payload), mises en cache par `GET /api/config/ai-models` (aucune requête supplémentaire) et prioritaires sur la table statique qui ne comble plus que les drapeaux non déclarés (repli hors ligne / sans clé). Table statique corrigée : familles vision Mistral (`ministral`, `magistral`, `mistral-small`, `mistral-medium`, `mistral-vibe-cli`, `labs-leanstral`), `mistral-ocr` = vision sans chat, défaut fournisseur Mistral sans `embeddings` (mistral-large / codestral n'étaient plus des « embedders »). Vérifié : diagnostic live avant/après sur l'API Mistral (28 modèles vision déclarés, **0** détectés avant → **28** après, 0 écart dans les deux sens), pytest 1007 passed / 6 skipped, ruff 0 (backend), mypy 0 (68 fichiers), tests frontend (unit 9/9, IA 66/66, validate-imports 37 modules), et vérification sur l'instance de test reconstruite (`obsigate-test`, http://localhost:2020) via les deux endpoints du panneau : `mistral-small/medium-latest`, `ministral-8b-latest`, `magistral-small-latest` → `chat,vision` ; `mistral-ocr-latest` → `vision` seul ; `mistral-large-latest`/`codestral-latest` → `chat` ; `mistral-embed` → `embeddings` seul ; `deepseek-chat` (fournisseur muet) inchangé. | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
| 2026-09-16 | BUG-045, BUG-046 | Correction | `frontend/style.css`, `frontend/js/bookslm.js`, `backend/bookslm.py`, `backend/bookslm_routes.py`, `frontend/sw.js`, `tests/test_bookslm.py`, `tests/frontend/ai.test.mjs`, `tests/frontend/editor-inline.test.mjs`, `CHANGELOG.md` | BUG-045 : fin de la double barre de défilement de l'éditeur « Editer » — `#editor-body` en flex column `overflow:hidden`, `.cm-editor` `flex:1 1 auto`, seul le scroller CodeMirror défile ; suppression de l'override global `.cm-scroller` (min-height/overflow-y !important). BUG-046 : « Échec de l'action : [object Object] » à l'application d'un ajout de texte au document courant — (1) `_responseError()` aplatit le `detail` 422 (tableau d'objets FastAPI) en message lisible, (2) la continuation de confirmation hérite du payload d'origine (le second « Appliquer » ne POSTe plus sans `message`), (3) le prompt documents/dossier nomme le vault et enjoint les outils d'écriture d'utiliser ce nom exact (le modèle inventait `"vault":"test"` → échec silencieux). `SW_VERSION` v20. Vérifié : pytest 1038 passed / 6 skipped, ruff 0 (backend), tests frontend IA 84/84, editor-inline 25/25, validate-imports 38 modules ; reproduction et validation Playwright sur l'instance de test (un seul conteneur scrollable après correctif). | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
| 2026-09-16 | BUG-047 | Correction + build | `VERSION` (nouveau), `scripts/bump_version.py` (nouveau), `.githooks/prepare-commit-msg` + `.githooks/post-commit` (nouveaux), `scripts/install-hooks.sh` (nouveau), `scripts/bump_version.sh`, `backend/version.py`, `Dockerfile`, `docker-compose.yml`, `build.sh`, `.gitea/workflows/ci.yml`, `desktop/build.rs`, `package.json`, `README.md`, `README.fr.md`, `docs/ROADMAP.md`, `docs/DELIVERY_WORKFLOW.md`, `docs/DEVELOPMENT_AND_RELEASES.md`, `tests/test_version.py` (nouveau) | **Version alignée de bout en bout.** Cause : la version affichée venait du dernier **tag git** et aucun tag n'était créé aux livraisons → 66 commits livrés mais UI/API figées sur `2.2.1` ; quatre autres numéros codés en dur dérivaient (`package.json` 1.0.0, desktop 2.0.0, `Dockerfile` 2.2.1, README 1.7.0). Nouveau modèle : **`VERSION` (racine) = source unique de vérité** (`MAJEUR.MINEUR.CORRECTIF`), incrémentée **automatiquement au commit** par le hook versionné `prepare-commit-msg` (SemVer depuis le message : `!:`/`BREAKING CHANGE` → MAJEUR, `feat` → MINEUR, sinon CORRECTIF ; aucun bump pour merge/revert/`chore(release)`/amend) qui resynchronise `package.json`, desktop Tauri, ROADMAP, READMEs et publie la section `[Unreleased]` du CHANGELOG en `[X.Y.Z] — date` ; `post-commit` rattache ces fichiers au commit qui vient d'être créé (amend immédiat, le commit n'étant pas encore poussé) puis crée le tag `vX.Y.Z`, publié au push (`push.followTags`). `bump_version.py` (avec `--dry-run`, `--set`, `--major|--minor|--patch`, `--print-version`) reste utilisable à la main ; `scripts/install-hooks.sh` installe les hooks. Côté build : Docker `COPY VERSION` (plus d'`ARG VERSION` ni d'env compose codés en dur), `build.sh` et CI lisent `VERSION`, `desktop/build.rs` aussi. Vérifié : `tests/test_version.py` (46 tests, dont le garde-fou `TestRepoVersionAlignment` : VERSION ↔ package.json ↔ desktop ↔ CHANGELOG ↔ ROADMAP ↔ READMEs ↔ pipeline sans numéro codé en dur), pytest complet, ruff/mypy 0, `/api/health` → `2.3.0` sur l'instance de test reconstruite. | 🟢 corrigé (en attente vérif utilisateur) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+61
-2
@@ -1,6 +1,6 @@
|
||||
# ObsiGate — Roadmap
|
||||
|
||||
> **Version :** 2.3.0-dev | **Dernière mise à jour :** 2026-09-15
|
||||
> **Version :** 2.3.0 | **Dernière mise à jour :** 2026-09-16
|
||||
> **Ce fichier ne contient que le travail à venir** (🔵 En cours + ⚪ Backlog) et un index compact
|
||||
> vers les fonctionnalités livrées.
|
||||
> - **Méthode de livraison à appliquer pour toute tâche : [DELIVERY_WORKFLOW.md](./DELIVERY_WORKFLOW.md)**
|
||||
@@ -94,6 +94,63 @@
|
||||
- [ ] Transverse : `tenacity` (backoff), cache SQLite des résultats web avec TTL, secrets via Infisical
|
||||
- [ ] Chaque outil : libellé `labels.py` + clés i18n `ai.step.*` FR/EN + tests (httpx mocké)
|
||||
|
||||
### 94. Assistant IA — Bouton de soumission arrondi et icône renouvelée
|
||||
|
||||
- **Effort :** 0,5 jour | **Impact :** 🟢 | **Zone :** frontend (`style.css`, `bookslm.js`)
|
||||
- **Description :** remplacer le bouton de soumission du panneau Assistant IA par un bouton rond
|
||||
et changer l'icône avion (`✈`) par une icône plus moderne (par ex. flèche vers le haut ou
|
||||
icône séduisante).
|
||||
- **Sous-tâches :**
|
||||
- [ ] Remplacer l'icône avion par une icône alternatif (flèche, paper plane stylisée, etc.)
|
||||
- [ ] Rendre le bouton de soumission circulaire (taille fixe, border-radius 50%)
|
||||
- [ ] Ajuster le positionnement (aligné en bas à droite de la zone de saisie)
|
||||
- [ ] i18n FR/EN + tests frontend
|
||||
|
||||
### 95. Assistant IA — Historique permanent des conversations (persistance côté backend)
|
||||
|
||||
- **Effort :** 2-3 jours | **Impact :** 🟡 | **Zone :** backend + frontend
|
||||
- **Description :** rendre la gestion de l'historique des conversations avec l'assistant IA
|
||||
permanente en persistant les échanges côté backend (et non uniquement en session/navigateur).
|
||||
L'historique doit survivre aux rechargements de page et être consultable à tout moment.
|
||||
- **Sous-tâches :**
|
||||
- [ ] Persister les conversations dans un stockage backend (SQLite ou JSON chiffré)
|
||||
- [ ] API CRUD pour les conversations (liste, récupération, suppression)
|
||||
- [ ] Synchroniser l'historique côté frontend au chargement du panneau IA
|
||||
- [ ] Nettoyage automatique de l'historique (rétention configurable, purge des anciennes)
|
||||
- [ ] Tests unitaires backend + tests frontend
|
||||
|
||||
### 96. Assistant IA — Accès rapide à l'historique depuis le panneau de navigation
|
||||
|
||||
- **Effort :** 1 jour | **Impact :** 🟡 | **Zone :** frontend (`nav.js`, `bookslm.js`)
|
||||
- **Description :** ajouter un icône dédié dans le panneau de navigation gauche (à côté de
|
||||
Vaultes, Tags, Récent, Sauvegarde) permettant d'ouvrir directement la liste des
|
||||
conversations de l'historique de l'assistant IA.
|
||||
- **Sous-tâches :**
|
||||
- [ ] Ajouter l'icône « Historique IA » dans la sidebar de navigation
|
||||
- [ ] Au clic : afficher un panneau latéral avec la liste chronologique des conversations
|
||||
- [ ] Sélection d'une conversation → ouverture dans le panneau Assistant IA
|
||||
- [ ] Indicateur visuel (badge) si de nouvelles conversations sont présentes
|
||||
- [ ] i18n FR/EN + tests frontend
|
||||
|
||||
### 97. Assistant IA — Panneau « + » extensible (fichiers, Deep Research, contextes, skills, etc.)
|
||||
|
||||
- **Effort :** 2-3 jours | **Impact :** 🟡 | **Zone :** frontend (`bookslm.js`, `style.css`)
|
||||
- **Description :** remplacer le bouton « Attach an image » par un bouton « + » qui ouvre
|
||||
un panneau d'extensions contenant diverses actions : téléverser des fichiers, Deep Research,
|
||||
ajouter des contextes, ajouter des skills, recherche sur Internet, intégration Canva, et
|
||||
d'autres options à venir. Ce panneau est extensible et modulaire.
|
||||
- **Sous-tâches :**
|
||||
- [ ] Remplacer le bouton « Attach an image » par un bouton « + » (icône universelle)
|
||||
- [ ] Panneau overlay / dropdown listant les options disponibles
|
||||
- [ ] Téléverser des fichiers (drag & drop + sélecteur)
|
||||
- [ ] Deep Research (lancement d'une recherche approfondie via les outils IA)
|
||||
- [ ] Ajouter contextes (fichiers, répertoires, URL)
|
||||
- [ ] Ajouter skills (catalogue de skills disponibles)
|
||||
- [ ] Recherche sur Internet (accès direct à `web_search`)
|
||||
- [ ] Intégration Canva (ou outil externe similaire)
|
||||
- [ ] Architecture modulaire : chaque option est un plugin/extensible facilement
|
||||
- [ ] i18n FR/EN + tests frontend
|
||||
|
||||
---
|
||||
|
||||
## ⚪ Backlog — Sécurité, architecture & performance (P0/P1)
|
||||
@@ -151,6 +208,7 @@
|
||||
|
||||
| # | Domaine / fonctionnalité | Version | Détails |
|
||||
|---|---|---|---|
|
||||
| BUG-047 | Versionnage — source unique `VERSION` + bump SemVer automatique au commit (hooks + tag) | 2.3.0 | [DEVELOPMENT_AND_RELEASES.md](./DEVELOPMENT_AND_RELEASES.md) |
|
||||
| 90 | Barre d'actions du document — regroupement fonctionnel + spacers | 2.3.0 | [archive](./archive/COMPLETED_v1-v2.md) |
|
||||
| 89 | Drag & drop complet de fichiers/dossiers & intégration Assistant IA | 2.3.0 | [features/drag-and-drop-ai.md](./features/drag-and-drop-ai.md) |
|
||||
| 1–8 | Fondations (FastAPI, TF-IDF + stemming, watchdog, SPA, sécurité, path traversal, gzip, PWA) | 1.0.0→1.4.0 | [archive](./archive/COMPLETED_v1-v2.md) |
|
||||
@@ -200,8 +258,9 @@
|
||||
| 🔵 P2 restant | #77 Desktop : signature de code (non retenue), 6 tests E2E **manuels** ([protocole](./DESKTOP_E2E_CHECKLIST.md)) | ~0,5-1 jour |
|
||||
| ⚪ P4 restant | #73 Sync (6-8j) | 6-8 jours |
|
||||
| ⚪ P2 restant | #92 Assistant IA — écosystème d'outils phase 2 (web étendu, sources connectées, documents) | 3-5 jours |
|
||||
| ⚪ P2 restant | #94–97 Assistant IA — améliorations UI (soumission, historique, navigation, panneau +) | ~6-7 jours |
|
||||
| ⚪ P0/P1 restant | #85-87 Refonte architecturale, performance, CI/CD (issues BUG-035 → BUG-040) | ~15-23 jours |
|
||||
| **Total restant** | **7 items + finitions** | **~31-47 jours** |
|
||||
| **Total restant** | **11 items + finitions** | **~37-54 jours** |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user