From b0af1bbfb68d9cdece4c15e246a4952ab18b67f5 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 2 Oct 2026 16:27:52 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20palette=20Ctrl+K=20=E2=80=94=20onglets?= =?UTF-8?q?=20Pages=20/=20=E2=9C=A8=20R=C3=A9ponses=20IA=20(v7.44.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added : - Onglets dans la palette (markup + CSS + wiring IIFE) : · Pages — comportement inchange (recherche /api/search + actions). · ✨ Réponses IA — POST /api/v2/search/ask (debounce 150 ms, CSRF via getCsrf(), gardes staleness onglet+requete) → answer_markdown rendu : echappement AVANT injection, [[fdpage:ID]] → lien citation (ids = chiffres, type = [a-z]+ — pas d'injection), **gras**, bloc « Sources » avec liens /pages/{id} · /db/{id} ; etats hint/chargement/erreur. - Gate E2E etendu : ouverture → clic onglet IA → reponse non-echappee. (probe : ask = 200 en 1,6s, 8 citations, provider actif) Reporte (backend absent) : onglet Fichiers — /api/search ne renvoie que pages/collections → endpoint a creer d'abord (ROADMAP, entree mise a jour). Notes : 401 transitoire sur le 1er ask d'un run E2E observe une fois (session fraiche), non reproductible ensuite — signale CHANGELOG. suite **1094/1094** · ruff OK · E2E **7/7** · docs a jour --- CHANGELOG.md | 23 ++++++++++++++ ROADMAP.md | 2 +- VERSION | 2 +- WORKLOAD.md | 2 +- app/main.py | 2 +- app/templates/base.html | 70 ++++++++++++++++++++++++++++++++++++++++- docs/openapi-v2.json | 2 +- e2e/smoke.spec.js | 19 +++++++++++ 8 files changed, 116 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c24db8..b641baa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog - FlowDeck +## v7.44.0 (2026-10-01) — Palette Ctrl+K : onglets Pages / ✨ Réponses IA + +### Added + +- **Palette `Ctrl+K` = 2 onglets** (markup + CSS + wiring dans l'IIFE) : + · **Pages** — comportement inchangé (recherche `/api/search` + actions). + · **✨ Réponses IA** — `POST /api/v2/search/ask` (debounce 150 ms, + CSRF via `getCsrf()`, gardes staleness onglet+requête) → rendu de + `answer_markdown` : **échappement AVANT injection**, `[[fdpage:ID]]` → + lien citation (ids = chiffres, type = `[a-z]+` — pas d'injection), + `**gras**`, bloc « Sources » avec liens `/pages/{id}` · `/db/{id}`. + États : hint / chargement / erreur. +- **Gate E2E étendu** (`gate A20 palette`) : ouverture → clic onglet IA → + réponse non-échaffée affichée (le backend tourne en extractif ou LLM — + probe : 200 en 1,6 s, 8 citations). +- **Reporté (backend absent)** : onglet `Fichiers` — `/api/search` ne + renvoie que `pages`/`collections` → endpoint à créer d'abord (ROADMAP). + +### Notes + +- Un 401 transitoire sur le 1er ask d'un run E2E a été observé (session + fraîche) — non reproductible ensuite ; à surveiller si ça revient. + ## v7.43.0 (2026-10-01) — 🎉 A20 TERMINÉ : Alpine en build CSP, `unsafe-eval` retiré ### Changed (la bascule A20 phase 3) diff --git a/ROADMAP.md b/ROADMAP.md index 0c5637b..fd3845a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -987,7 +987,7 @@ Détails livrés : - [x] **Migrations 25** — `semantic_embeddings`, `semantic_index_state`, colonne `pages.search_excluded` - [x] **Tests** — `tests/test_v69_search_ask.py` (**24 tests** : migration, chunk/overlap, déterminisme/norme, cosinus, index idempotent, exclusion, purge, rappel vectoriel partiel, hybride keyword/auth/400/pagination/isolation ACL/exclusion/collections, ask citations/auth/400/cache/ACL/rate-limit, index-status) - [x] **Version** — 6.9.0 (`VERSION` + `app/main.py`) · `ruff check` OK -- [ ] **UI** — palette `Ctrl+K` onglets `Pages / Fichiers / ✨ Réponses IA` (reporté : backend livré, frontend en follow-up) +- [x] **UI** — palette `Ctrl+K` : **onglets `Pages / ✨ Réponses IA`** livrés (v7.44.0) — onglet IA = `POST /api/v2/search/ask` (CSRF via `getCsrf()`, debounce 150 ms, échappement AVANT injection des liens `[[fdpage:ID]]` → citations cliquables + bloc « Sources ») ; gate E2E étendu (onglet cliqué → réponse non-échappée). **Reporté** : onglet `Fichiers` — aucun backend (`/api/search` ne renvoie que `pages`/`collections`) → à créer d'abord. ### v7.0.0 — Automations v2 + Workers ✅ (2026-09-28) > **Objectif** : automatiser au-delà du if-this-then-that + custom code sandboxé. diff --git a/VERSION b/VERSION index 414bc85..a1350b5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.43.0 +7.44.0 diff --git a/WORKLOAD.md b/WORKLOAD.md index 74d025f..8f3d2ff 100644 --- a/WORKLOAD.md +++ b/WORKLOAD.md @@ -1,6 +1,6 @@ # WORKLOAD — FlowDeck Notion Clone -> **Début**: 2026-07-08 | **Version**: v7.43.0 (**A20 TERMINÉ** : bascule Alpine CSP + unsafe-eval retiré de la CSP) | **Statut**: EN COURS 🔄 +> **Début**: 2026-07-08 | **Version**: v7.44.0 (UI palette : onglets Pages / ✨ Réponses IA — POST /api/v2/search/ask rendu + sources citées) | **Statut**: EN COURS 🔄 > **Cible**: parité Notion + intégration forge · **Follow-ups v7.3 livrés**: sidebar teamspaces, notif `page.updated`, charts `number` + dashboards multi-DB, unfurl forge, UI Settings → Audit — voir `ROADMAP.md § v7.3.0` ## Avancement Global diff --git a/app/main.py b/app/main.py index 4c4b1e4..bf84a59 100644 --- a/app/main.py +++ b/app/main.py @@ -185,7 +185,7 @@ async def lifespan(_app: FastAPI): app = FastAPI( title="FlowDeck", - version="7.43.0", + version="7.44.0", docs_url="/docs", redoc_url="/redoc", lifespan=lifespan, diff --git a/app/templates/base.html b/app/templates/base.html index 5705b38..dcc68cf 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2234,6 +2234,14 @@ .cmd-palette-overlay.open .cmd-palette{transform:translateY(0)} .cmd-palette-input{width:100%;box-sizing:border-box;padding:16px 18px;background:transparent;border:none;outline:none;color:var(--text,#fff);font-size:16px} .cmd-palette-input::placeholder{color:var(--text-dim,rgba(255,255,255,.4))} +.cmd-palette-tabs{display:flex;gap:6px;padding:10px 16px 0} +.cp-tab{background:none;border:1px solid var(--border,rgba(255,255,255,.12));color:var(--text-dim,rgba(255,255,255,.55));border-radius:999px;padding:4px 12px;font-size:12px;cursor:pointer} +.cp-tab.active{background:var(--bg-hover,#2a2a2a);color:var(--text,#eee);border-color:var(--accent,#2383e2)} +.cmd-palette-ai{padding:14px 18px;font-size:13.5px;line-height:1.55;white-space:pre-wrap;color:var(--text,#eee)} +.cmd-palette-ai .cp-cites{margin-top:10px;display:flex;flex-direction:column;gap:4px;font-size:12.5px;white-space:normal} +a.cp-cite{color:var(--accent,#529ffa);text-decoration:none} +a.cp-cite:hover{text-decoration:underline} +.cp-loading{color:var(--text-dim,rgba(255,255,255,.5))} .cmd-palette-list{overflow-y:auto;border-top:1px solid var(--border,rgba(255,255,255,.06))} .cmd-palette-group{display:flex;align-items:center;gap:8px;padding:10px 18px 4px;font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--text-dim,rgba(255,255,255,.4))} .cmd-palette-item{display:flex;align-items:center;gap:10px;padding:9px 18px;cursor:pointer;font-size:14px;color:var(--text,#fff)} @@ -2255,6 +2263,10 @@ +
+ + +