feat(ai): sidebar epuree, suivi visuel des requetes et correctif menu @ (BUG-012, #82)
CI / lint (push) Successful in 1m9s
CI / security (push) Successful in 44s
CI / test (push) Successful in 2m29s
CI / build (push) Successful in 39s
CI / e2e (push) Successful in 10m39s

BUG-012: le menu @ est toujours rendu et _mentionVault() retombe sur le vault de contexte puis le premier vault disponible. #82: suppression des intitules Fournisseur & modele / Fournisseur:, description du contexte General en info-bulle, placeholder retire, bouton Envoyer en emoji, indicateur d'activite (envoi/reception/outils/confirmation/succes/echec), SW_VERSION v5.
This commit is contained in:
2026-09-12 14:21:33 -04:00
parent eea2108ac2
commit ee4c273d73
10 changed files with 190 additions and 28 deletions
+46
View File
@@ -1024,6 +1024,52 @@ async function main() {
localStorage.clear();
});
// ── 42b. Assistant activity indicator (#82) ──
await test("activity indicator reflects the request workflow", () => {
const b = new BooksLM();
b._panel = b._render();
document.body.appendChild(b._panel);
const el = b._panel.querySelector(".bookslm-activity");
assert.ok(el, "activity element present");
assert.ok(el.classList.contains("hidden"), "hidden initially");
b._setActivity("working", "Envoi…");
assert.ok(!el.classList.contains("hidden"), "shown while working");
assert.ok(el.classList.contains("working"));
assert.equal(el.querySelector(".bookslm-activity-text").textContent, "Envoi…");
b._setActivity("error", "Échec");
assert.ok(el.classList.contains("error"));
b._setActivity("idle");
assert.ok(el.classList.contains("hidden"), "hidden when idle");
b._panel.remove();
});
await test("mention menu falls back to an available vault", async () => {
localStorage.clear();
const stateMod = await import(pathToFileURL(path.join(JS_DIR, "state.js")).href);
const prev = stateMod.state.allVaults;
stateMod.state.allVaults = [{ name: "FallbackVault" }];
let lastUrl = "";
globalThis.fetch = async (url) => {
lastUrl = String(url);
if (lastUrl.includes("/files")) {
return { ok: true, status: 200, json: async () => ({ files: [{ path: "a.md" }] }) };
}
return { ok: true, status: 200, json: async () => ({}) };
};
const b = new BooksLM();
b._panel = b._render();
document.body.appendChild(b._panel);
b._mode = MODE.GENERAL;
b._vault = null;
await b._showMentionMenu("");
const menu = b._panel.querySelector(".bookslm-mention-menu");
assert.ok(!menu.classList.contains("hidden"), "empty-query menu is shown");
assert.ok(lastUrl.includes("FallbackVault"), "uses the fallback vault");
stateMod.state.allVaults = prev;
b._panel.remove();
localStorage.clear();
});
// ── Summary ──
console.log(`\n${passCount}/${testCount} tests passed`);
if (passCount !== testCount) {