diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bc4d71..47c7f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ Format basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/), et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > **En cours de développement** : les changements à venir sont listés dans la section -> [Unreleased](#unreleased). La dernière version livrée est **2.50.2**. +> [Unreleased](#unreleased). La dernière version livrée est **2.51.0**. --- @@ -14,6 +14,24 @@ et [Semantic Versioning](https://semver.org/spec/v2.0.0.html). --- +## [2.51.0] — 2026-10-03 + +### Ajouté + +- **#160 — Premier lancement professionnel + section Configuration harmonisée** + - **Premier lancement** : `%USERPROFILE%\ObsiGate` est créé et monté comme + vault de démarrage (nom « ObsiGate », remplace `voute_obsidian`), le + contexte initial s'ouvre dessus, le dossier home reste une racine nommée + d'après son chemin (fin du « bruno » codé en dur), et le document + **`Prise en main.md`** (contenu embarqué) y est écrit une seule fois — + jamais écrasé. + - **Section « 🖥️ Vaults & dossiers (Desktop) »** refondue : lignes au motif + des cartes de la configuration (icône, nom, chemin tronqué), boutons + Retirer/Ajouter en `.config-btn-sm` secondaire/ primaire, zéro style + inline, variables CSS uniquement, cibles tactiles 44px en mobile. + +--- + ## [2.50.2] — 2026-10-02 --- diff --git a/README.fr.md b/README.fr.md index 63bed0f..eda32fb 100644 --- a/README.fr.md +++ b/README.fr.md @@ -4,7 +4,7 @@ **Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive. -[![Version](https://img.shields.io/badge/Version-2.50.2-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.51.0-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -976,8 +976,8 @@ Ce projet est sous licence **MIT** — voir le fichier [LICENSE](LICENSE) pour l ## 📝 Changelog -Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.50.2). +Consultez le [CHANGELOG.md](./CHANGELOG.md) pour l'historique complet de toutes les versions (v1.0.0 → v2.51.0). --- -*Projet : ObsiGate | Version : 2.50.2 | Dernière mise à jour : Septembre 2026* +*Projet : ObsiGate | Version : 2.51.0 | Dernière mise à jour : Septembre 2026* diff --git a/README.md b/README.md index ff02310..bd91084 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Ultra-light web gateway for your Obsidian vaults** — Access, browse, and search all your Obsidian notes from any device via a modern, responsive web interface. -[![Version](https://img.shields.io/badge/Version-2.50.2-blue.svg)]() +[![Version](https://img.shields.io/badge/Version-2.51.0-blue.svg)]() [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Docker](https://img.shields.io/badge/Docker-Ready-blue.svg)](https://www.docker.com/) [![Python](https://img.shields.io/badge/Python-3.11+-green.svg)](https://www.python.org/) @@ -1151,8 +1151,8 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE) ## 📝 Changelog -See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.50.2). +See [CHANGELOG.md](./CHANGELOG.md) for the complete version history (v1.0.0 → v2.51.0). --- -*Project: ObsiGate | Version: 2.50.2 | Last updated: September 2026* +*Project: ObsiGate | Version: 2.51.0 | Last updated: September 2026* diff --git a/VERSION b/VERSION index 555bd6c..d66b738 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.50.2 +2.51.0 diff --git a/desktop/Cargo.lock b/desktop/Cargo.lock index 2f7fef7..84db5ce 100644 --- a/desktop/Cargo.lock +++ b/desktop/Cargo.lock @@ -2626,7 +2626,7 @@ dependencies = [ [[package]] name = "obsigate-desktop" -version = "2.50.2" +version = "2.51.0" dependencies = [ "chrono", "env_logger", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index da9de37..240575d 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "obsigate-desktop" -version = "2.50.2" +version = "2.51.0" description = "ObsiGate Desktop — Porte d'entrée native pour vos vaults Obsidian" authors = ["Bruno Charest"] edition = "2021" diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 43bbf1d..2a513e0 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -161,6 +161,39 @@ fn save_config(config: &AppConfig) { } } +// ── Premier lancement (#160) ─────────────────────────────────────────────── + +/// Répertoire de démarrage monté comme vault au premier lancement. +const STARTER_VAULT_NAME: &str = "ObsiGate"; +/// Document d'accueil écrit (si absent) dans le répertoire de démarrage. +const WELCOME_DOC_NAME: &str = "Prise en main.md"; +const WELCOME_DOC: &str = include_str!("prise_en_main.md"); + +/// Config par défaut au premier lancement — pure, sans I/O (testable). +/// `/ObsiGate` est monté comme vault ET comme contexte initial ; le +/// dossier home reste une racine, nommée d'après son dernier segment +/// (fin du « bruno » codé en dur, #160). +fn default_first_run_config(home: &str) -> AppConfig { + let home_path = std::path::Path::new(home); + let vault_dir = home_path.join("ObsiGate"); + let vault_path = vault_dir.to_string_lossy().to_string(); + AppConfig { + vault_path: Some(vault_path.clone()), + vaults: vec![VaultConfig { + name: STARTER_VAULT_NAME.to_string(), + path: vault_path, + }], + dirs: vec![DirConfig { + name: home_path + .file_name() + .map(|s| s.to_string_lossy().to_string()) + .unwrap_or_else(|| home.to_string()), + path: home.to_string(), + }], + ..AppConfig::default() + } +} + // ── Backend lifecycle ─────────────────────────────────────────────────────── fn spawn_backend(exe_dir: &PathBuf) -> Result { @@ -535,7 +568,7 @@ fn main() { // Load config for window state let mut config = load_config(); - // First run: create sensible defaults per platform + // First run: create sensible defaults per platform (#160) if config.vaults.is_empty() { info!("First run — creating default vault configuration"); #[cfg(target_os = "windows")] @@ -543,25 +576,28 @@ fn main() { #[cfg(not(target_os = "windows"))] let home = std::env::var("HOME").unwrap_or_else(|_| "/home/bruno".to_string()); - let vault_dir = std::path::PathBuf::from(&home).join("voute_obsidian"); - // Create the vault directory if it doesn't exist - if !vault_dir.exists() { - if let Err(e) = fs::create_dir_all(&vault_dir) { - error!("Failed to create default vault dir {}: {}", vault_dir.display(), e); - } else { - info!("Created default vault dir: {}", vault_dir.display()); + // Montage du répertoire de démarrage (vault + contexte initial) sans + // toucher aux autres champs (taille/position de fenêtre) de la config. + let defaults = default_first_run_config(&home); + config.dirs = defaults.dirs; + config.vaults = defaults.vaults; + config.vault_path = defaults.vault_path; + + let vault_dir = std::path::PathBuf::from(config.vaults[0].path.clone()); + if let Err(e) = fs::create_dir_all(&vault_dir) { + error!("Failed to create default vault dir {}: {}", vault_dir.display(), e); + } else { + info!("Created default vault dir: {}", vault_dir.display()); + } + // Document d'accueil : écrit une seule fois, jamais écrasé (#160). + let welcome = vault_dir.join(WELCOME_DOC_NAME); + if !welcome.exists() { + match fs::write(&welcome, WELCOME_DOC) { + Ok(()) => info!("Welcome document written: {}", welcome.display()), + Err(e) => error!("Failed to write {}: {}", welcome.display(), e), } } - config.dirs = vec![ - DirConfig { name: "bruno".to_string(), path: home.clone() }, - ]; - config.vaults = vec![ - VaultConfig { - name: "Obsidian".to_string(), - path: vault_dir.to_string_lossy().to_string(), - }, - ]; - config.vault_path = Some(home); + save_config(&config); info!("Default vault config saved"); } @@ -1239,4 +1275,35 @@ mod tests { "main.rs : disable_drag_drop_handler() manquant — drag & drop bloqué" ); } + + /// #160 — premier lancement : `/ObsiGate` monté comme vault et + /// comme contexte initial, racine home nommée d'après son chemin. + #[test] + fn test_default_first_run_config() { + #[cfg(target_os = "windows")] + let home = r"C:\Users\alice"; + #[cfg(not(target_os = "windows"))] + let home = "/home/alice"; + + let c = default_first_run_config(home); + assert_eq!(c.vaults.len(), 1); + assert_eq!(c.vaults[0].name, STARTER_VAULT_NAME); + assert!(c.vaults[0].path.ends_with("ObsiGate"), "{}", c.vaults[0].path); + assert_eq!(c.vault_path.as_deref(), Some(c.vaults[0].path.as_str())); + assert_eq!(c.dirs.len(), 1); + assert_eq!(c.dirs[0].name, "alice", "nom de racine dérivé du chemin"); + assert_eq!(c.dirs[0].path, home); + assert!(!c.wizard_done); + } + + /// #160 — le document d'accueil est embarqué dans le binaire : non vide, + /// Markdown, et nom de fichier stable (écrit une seule fois sur le disque). + #[test] + fn test_welcome_doc_embedded() { + assert!(WELCOME_DOC.len() > 500, "document d'accueil trop court"); + assert!(WELCOME_DOC.starts_with('#'), "attendu : titre Markdown"); + assert!(WELCOME_DOC.contains("ObsiGate")); + assert!(WELCOME_DOC.contains("Ctrl+Espace")); + assert_eq!(WELCOME_DOC_NAME, "Prise en main.md"); + } } diff --git a/desktop/src/prise_en_main.md b/desktop/src/prise_en_main.md new file mode 100644 index 0000000..5292307 --- /dev/null +++ b/desktop/src/prise_en_main.md @@ -0,0 +1,41 @@ +# 🟢 Bienvenue sur ObsiGate — Prise en main + +Ce dossier `%USERPROFILE%\ObsiGate` est votre **espace de départ** : il est +monté automatiquement comme vault **ObsiGate** au premier lancement. Vous +pouvez y écrire librement, puis brancher vos vrais vaults Obsidian quand vous +êtes prêt. + +## ObsiGate en 30 secondes + +ObsiGate est une porte d'entrée locale vers vos notes : index en mémoire, +recherche instantanée, lecture Markdown avec liens `[[wikilinks]]`, images, +PDF, tableurs Excel, Excalidraw, Mermaid et assistant IA — sans base de +données, sans modification de vos fichiers, tout reste sur votre machine. + +## Premiers pas (application desktop) + +1. **Ce document** s'affiche dans la visionneuse : c'est votre première note, + modifiez-la ou supprimez-la quand vous n'en avez plus besoin. +2. **Ajouter vos vaults** : Configuration → « 🖥️ Vaults & dossiers (Desktop) » + → *Ajouter un vault* (sélecteur de dossier natif). Depuis la sidebar, + clic droit sur une racine → « Retirer de l'application » la désiste + (aucun fichier n'est supprimé). +3. **Naviguer** : la sidebar liste vos racines et leur arbre ; l'onglet + Navigation parcourt un dossier sous forme de vues répertoire. +4. **Rechercher** : `Ctrl+Espace` (palette de fichiers), + `Ctrl+Alt+Espace` (palette de commandes), `Ctrl+F` dans un document. +5. **Onglets** : `Ctrl+W` ferme l'onglet, `Ctrl+Tab` bascule ; le mode split + divise l'écran en panneaux. +6. **Guide complet** : bouton d'aide de l'en-tête — sommaire, raccourcis, + architecture, et téléchargement du guide en Markdown/PDF. + +## Le saviez-vous ? + +- Le **glisser-déposer** de fichiers depuis l'Explorateur est pris en charge : + déposez-les sur la fenêtre pour les importer. +- Le **clic droit** est partout : menus contextuels de fichier, dossier et + vault (avec renommage, création, suppression, vue graphique). +- Le **watcher** surveille vos vaults : une note modifiée dans Obsidian + apparaît immédiatement ici. + +— *Ce fichier vous appartient.* diff --git a/desktop/tauri.conf.json b/desktop/tauri.conf.json index 1253f7d..dee0329 100644 --- a/desktop/tauri.conf.json +++ b/desktop/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicedoc/obsigate/main/desktop/tauri.conf.schema.json", "productName": "ObsiGate", - "version": "2.50.2", + "version": "2.51.0", "identifier": "com.obsigate.desktop", "build": { "frontendDist": "../frontend", diff --git a/docs/GUIDES/DESKTOP.md b/docs/GUIDES/DESKTOP.md index 7e46cf5..43f110a 100644 --- a/docs/GUIDES/DESKTOP.md +++ b/docs/GUIDES/DESKTOP.md @@ -37,6 +37,19 @@ Deux surfaces, réservées à l'application desktop : vaults et dossiers chargés, avec boutons « Ajouter un vault » (sélecteur de dossier natif) et « Ajouter un dossier ». +### Premier lancement (#160) + +Au tout premier démarrage (aucun vault configuré), l'application : + +1. crée et monte **`%USERPROFILE%\ObsiGate`** comme vault de démarrage + (« ObsiGate ») et ouvre l'interface dessus ; +2. y écrit le document **`Prise en main.md`** — présentation, premières + étapes, raccourcis (`Ctrl+Espace`, `Ctrl+Alt+Espace`, `Ctrl+F`, + `Ctrl+W`/`Ctrl+Tab`) et accès au guide complet (bouton d'aide de l'en-tête). + Le fichier n'est jamais réécrit : modifiez-le ou supprimez-le librement ; +3. ajoute votre dossier personnel comme seconde racine (nommée d'après son + chemin). + --- ## 2. Téléchargement des binaires diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 9bd64e3..63d630c 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # ObsiGate — Roadmap -> **Version :** 2.50.2 | **Dernière mise à jour :** 2026-10-02 +> **Version :** 2.51.0 | **Dernière mise à jour :** 2026-10-03 > **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)** @@ -50,6 +50,16 @@ - [x] Rafraîchissement de la jump list après chaque ajout/retrait - [x] i18n FR/EN, tests (garde-fou ACL + unit), E2E, fiche features, release +### 160. Premier lancement professionnel + section Configuration harmonisée + +- **Effort :** 0,5-1 jour | **Impact :** 🟢 | **Framework :** config Rust + CSS classes existantes +- **Statut :** ✅ livré le 2026-10-02 (v2.51.0) — ouvert le 2026-10-02 +- **Reste à faire :** + - [x] Premier lancement : monter `%USERPROFILE%\ObsiGate` comme vault par défaut (remplace `voute_obsidian`), `vault_path` dessus, nom de dossier racine home dérivé du chemin (fin du hardcode « bruno ») + - [x] Document `Prise en main.md` (contenu embarqué `include_str!`) écrit dans ce dossier si absent — jamais d'écrasement + - [x] Refonte visuelle de la section « 🖥️ Vaults & dossiers (Desktop) » : classes CSS (motif `webauthn-key-item`), boutons `.config-btn-sm`, zéro style inline, override mobile 44px + - [x] Tests Rust (config par défaut + doc embarqué), suites frontend, E2E, docs, release + --- ## 🔵 En cours — Visionneuse & édition Excel (P0/P1/P2) @@ -282,6 +292,7 @@ | 155 | Tableur — Menu contextuel (clic droit / appui long) & sélection type Excel | 2.44.0 | [features/xlsx-context-menu.md](./features/xlsx-context-menu.md) | | 156 | Tableur — Complétude éditeur : presse-papiers/clavier (A5-A7), mise en forme (A8), décision calcul (A9), undo unifié (A10), export + recherche multi-feuilles (A11), concurrence optimiste (A12), cache méta (A13), outils IA `.xlsm`/`.csv` (A14) + BUG-096 → BUG-099 | 2.45.0 | [features/xlsx-editor-completeness.md](./features/xlsx-editor-completeness.md) | | 159 | Desktop — gestion des vaults & dossiers : retrait par menu contextuel + section Configuration (ajout vault/dossier racine) | 2.50.0 | [features/desktop-tauri.md](./features/desktop-tauri.md) | +| 160 | Desktop — premier lancement professionnel (répertoire `%USERPROFILE%\ObsiGate` + `Prise en main.md`) et section Configuration harmonisée | 2.51.0 | [features/desktop-tauri.md](./features/desktop-tauri.md) | | 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) | diff --git a/docs/features/desktop-tauri.md b/docs/features/desktop-tauri.md index a7867cf..a454bc8 100644 --- a/docs/features/desktop-tauri.md +++ b/docs/features/desktop-tauri.md @@ -107,3 +107,19 @@ - [x] Tests : `tests/frontend/desktop-roots.test.mjs` (4 — helpers purs + gating hors desktop), inscrit au CI ; suites frontend/JSDOM vertes, `cargo test` 25 passed. + +## H. Premier lancement & section Configuration harmonisée — #160 — ✅ livré (2026-10-02, v2.51.0) + +- [x] `default_first_run_config(home)` (pure, testée) : `/ObsiGate` + monté comme vault « ObsiGate » ET comme `vault_path`, racine home nommée + d'après son dernier segment — remplace `voute_obsidian` + le « bruno » + codé en dur ; les champs fenêtre de la config existante sont préservés. +- [x] `Prise en main.md` : contenu embarqué (`include_str!("prise_en_main.md")`), + écrit au premier lancement **si absent** (jamais d'écrasement). +- [x] Section `cfg-desktop-roots` refondue : markup à classes (zéro style + inline), bloc CSS `#160` sur variables (`desktop-roots-*`, motif + `webauthn-key-item`), boutons `.config-btn-sm` (primaire/secondaire), + override mobile 44px dans le bloc `#config-modal`. +- [x] Tests : `test_default_first_run_config`, `test_welcome_doc_embedded` + — `cargo test` 28 passed ; suites frontend vertes (validate-imports, + unit, config-mobile, desktop-roots, settings-order) + E2E locale. diff --git a/frontend/index.html b/frontend/index.html index 732ca91..b005234 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1951,7 +1951,7 @@ - +
-
- +
+
-
+
"; + '
' + + `` + + '
' + + `${escapeHtml(name)}` + + `${escapeHtml(path)}` + + "
" + + `` + + "
"; if (!vaults.length && !dirs.length) { - list.innerHTML = '
' + escapeHtml(t("desktop.roots_empty")) + "
"; + list.innerHTML = `
${escapeHtml(t("desktop.roots_empty"))}
`; } else { list.innerHTML = vaults.map((v) => row(v.name, v.path, "vault")).join("") + dirs.map((d) => row(d.name, d.path, "dir")).join(""); diff --git a/frontend/style.css b/frontend/style.css index c1592fd..5ca4c76 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -5041,6 +5041,15 @@ body.resizing-v { min-height: 44px; min-width: 44px; } + #config-modal .desktop-roots-item { + flex-wrap: wrap; + } + #config-modal .desktop-roots-item .config-btn-sm { + min-height: 44px; + } + #config-modal .desktop-roots-actions { + flex-wrap: wrap; + } #config-modal .hidden-files-add-row { flex-wrap: wrap; } @@ -11963,6 +11972,79 @@ mark { .webauthn-key-meta { font-size: 0.75rem; color: var(--text-muted, #888); } .config-btn-sm { padding: 4px 10px; font-size: 0.78rem; } +/* ── #160 : Section Configuration — Vaults & dossiers (Desktop) ──────────── */ +.desktop-roots-list { + display: flex; + flex-direction: column; + gap: 8px; +} +.desktop-roots-item { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 10px; + background: var(--surface2, #1a1a2e); + border: 1px solid var(--border, transparent); + border-radius: 6px; + transition: border-color 150ms; +} +.desktop-roots-item:hover { + border-color: var(--accent); +} +.desktop-roots-icon { + width: 16px; + height: 16px; + flex-shrink: 0; + color: var(--accent); +} +.desktop-roots-text { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 2px; +} +.desktop-roots-name { + font-size: 0.9rem; + font-weight: 600; + color: var(--text, #fff); +} +.desktop-roots-path { + font-size: 0.75rem; + color: var(--text-muted, #888); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.desktop-roots-item .config-btn-sm { + display: inline-flex; + align-items: center; + gap: 6px; + flex-shrink: 0; + white-space: nowrap; +} +.desktop-roots-btn-icon { + width: 14px; + height: 14px; +} +.desktop-roots-empty { + padding: 12px; + font-size: 0.85rem; + color: var(--text-muted, #888); + background: var(--surface2, #1a1a2e); + border-radius: 6px; +} +.desktop-roots-actions { + display: flex; + justify-content: flex-end; + gap: 8px; +} +.desktop-roots-actions .config-btn-sm { + display: inline-flex; + align-items: center; + gap: 6px; +} + /* MFA Disable card */ .mfa-disable-card { padding: 16px; border-radius: 10px; diff --git a/package.json b/package.json index 14a5af0..5fd41ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsigate", - "version": "2.50.2", + "version": "2.51.0", "description": "**Porte d'entrée web ultra-léger pour vos vaults Obsidian** — Accédez, naviguez et recherchez dans toutes vos notes Obsidian depuis n'importe quel appareil via une interface web moderne et responsive.", "main": "patch.js", "directories": {