@nightkatana/kronosys-app 1.0.0-beta.2 → 1.0.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +28 -1
  2. package/app/api/action/route.ts +39 -3
  3. package/app/api/action-logs/route.ts +24 -0
  4. package/app/api/backup/route.ts +1 -1
  5. package/app/api/restore/route.ts +145 -0
  6. package/app/changelog/page.tsx +71 -4
  7. package/app/globals.css +127 -0
  8. package/app/guide/page.tsx +61 -15
  9. package/app/implementation/page.tsx +700 -0
  10. package/app/layout.tsx +14 -3
  11. package/app/licenses/page.tsx +99 -37
  12. package/app/logs/page.tsx +258 -0
  13. package/app/manifest.ts +5 -5
  14. package/app/page.tsx +784 -229
  15. package/app/reporting/page.tsx +1266 -474
  16. package/app/settings/page.tsx +252 -18
  17. package/bin/kronosys.mjs +140 -15
  18. package/components/KronosysPayloadProvider.tsx +2 -0
  19. package/components/RouteTransition.tsx +18 -0
  20. package/components/dashboard/AppShellCommandCenterPlaceholder.tsx +17 -0
  21. package/components/dashboard/AppShellHeaderSessionMeta.tsx +210 -0
  22. package/components/dashboard/AppShellHeaderWallClock.tsx +54 -0
  23. package/components/dashboard/AppShellLiveSessionDrawer.tsx +154 -38
  24. package/components/dashboard/AppShellRouteNav.tsx +323 -48
  25. package/components/dashboard/DashboardPauseBackdrop.tsx +50 -0
  26. package/components/dashboard/DashboardSimpleModal.tsx +168 -25
  27. package/components/dashboard/DashboardTour.tsx +115 -29
  28. package/components/dashboard/GlobalPauseConfirmModal.tsx +183 -0
  29. package/components/dashboard/KronosysDatetimePopoverField.tsx +167 -122
  30. package/components/dashboard/KronosysTimePopoverField.tsx +54 -12
  31. package/components/dashboard/NewSessionScopeModal.tsx +211 -20
  32. package/components/dashboard/PlannedTaskBoundaryConflictWatcher.tsx +275 -0
  33. package/components/dashboard/ReportingTour.tsx +87 -21
  34. package/components/dashboard/SavedProjectPicker.tsx +16 -3
  35. package/components/dashboard/SelectedSessionSidebarBlock.tsx +512 -142
  36. package/components/dashboard/SessionListPanel.tsx +327 -44
  37. package/components/dashboard/SettingsTagsProjectsSection.tsx +1073 -264
  38. package/components/dashboard/SettingsTaskTemplatesSection.tsx +316 -0
  39. package/components/dashboard/SettingsTour.tsx +86 -21
  40. package/components/dashboard/TagPills.tsx +14 -1
  41. package/components/dashboard/TaskFocusPanel.tsx +1081 -478
  42. package/components/dashboard/TaskSessionLiveCard.tsx +650 -135
  43. package/components/dashboard/TaskTimelineGanttModal.tsx +601 -0
  44. package/components/dashboard/taskFieldStyles.ts +20 -4
  45. package/components/dashboard/useReportingInteractionState.ts +80 -0
  46. package/lib/appShellHeaderClasses.ts +13 -0
  47. package/lib/businessRulesMatrix.ts +210 -0
  48. package/lib/copyToClipboard.ts +43 -0
  49. package/lib/dashboardCopy.ts +494 -84
  50. package/lib/dashboardQuickSearch.ts +54 -2
  51. package/lib/dashboardTimeZone.ts +109 -0
  52. package/lib/formatAppShellWallClock.ts +66 -0
  53. package/lib/formatSessionNameTemplate.ts +141 -0
  54. package/lib/generatedUserChangelog.ts +177 -6
  55. package/lib/globalPausePreview.ts +292 -0
  56. package/lib/implementationNotes.ts +1188 -0
  57. package/lib/kronosysApi.ts +6 -0
  58. package/lib/kronosysDashboardModalGates.ts +24 -0
  59. package/lib/plannedBoundaryAttention.ts +9 -0
  60. package/lib/plannedBoundaryConflict.ts +23 -0
  61. package/lib/reportingAggregate.ts +517 -75
  62. package/lib/reportingMetricHelp.ts +8 -0
  63. package/lib/reportingStrings.ts +37 -3
  64. package/lib/sessionListMerge.ts +4 -0
  65. package/lib/sessionTaskSidebarStats.ts +182 -21
  66. package/lib/settingsCopy.ts +178 -4
  67. package/lib/taskParsing.ts +360 -103
  68. package/lib/taskTemplateDraft.ts +135 -0
  69. package/lib/taskTimelineGantt.ts +265 -0
  70. package/lib/temporalDisplayPlanned.ts +71 -0
  71. package/lib/userGuideCopy.ts +121 -47
  72. package/next.config.ts +7 -0
  73. package/package.json +12 -24
  74. package/server/actionDispatch.ts +1000 -77
  75. package/server/actionTaskSession.ts +337 -24
  76. package/server/db.ts +7 -15
  77. package/server/dbSchema.ts +24 -0
  78. package/server/defaultCfg.ts +5 -0
  79. package/server/gitlabTokenStore.ts +0 -12
  80. package/server/liveHistorySync.ts +53 -0
  81. package/server/mainTimerHydrate.ts +38 -2
  82. package/server/payloadStore.ts +33 -11
  83. package/server/sessionWallHydrate.ts +66 -3
  84. package/server/userActionLog.ts +126 -0
  85. package/sonar-project.properties +11 -0
  86. package/tsconfig.json +2 -1
  87. package/components/dashboard/IssuePickerModal.tsx +0 -168
  88. package/components/dashboard/ThemeToggle.test.tsx +0 -26
  89. package/lib/backupCsvExport.test.ts +0 -149
  90. package/lib/dashboardQuickSearchQuery.test.ts +0 -63
  91. package/lib/dataDir.test.ts +0 -87
  92. package/lib/formatIsoShort.test.ts +0 -46
  93. package/lib/kronoFocusRhythm.test.ts +0 -130
  94. package/lib/kronoFocusTimerUrgency.test.ts +0 -74
  95. package/lib/legacyKronoFocusStorageKeys.test.ts +0 -29
  96. package/lib/reportingAggregate.test.ts +0 -325
  97. package/lib/reportingNonFinalIndicators.test.ts +0 -157
  98. package/lib/reportingTagWeekBreakdown.test.ts +0 -141
  99. package/lib/reportingWeekLayout.test.ts +0 -239
  100. package/lib/sessionAssiduity.test.ts +0 -25
  101. package/lib/sessionEndWarnings.test.ts +0 -200
  102. package/lib/sessionListMerge.test.ts +0 -101
  103. package/lib/sessionTaskSidebarStats.test.ts +0 -24
  104. package/lib/taskParsing.test.ts +0 -153
  105. package/lib/usageProfile.test.ts +0 -84
  106. package/server/actionDispatch.test.ts +0 -723
  107. package/server/actionTaskSession.test.ts +0 -713
  108. package/server/kronoFocusHydrate.test.ts +0 -142
  109. package/server/kronoFocusMigrate.test.ts +0 -53
  110. package/server/mainTimerHydrate.test.ts +0 -65
  111. package/server/payloadStore.test.ts +0 -78
  112. package/server/sessionWallHydrate.test.ts +0 -46
@@ -50,7 +50,7 @@ function frBundle(): UserGuideBundle {
50
50
  searchNoResults: "Aucune rubrique ne correspond à votre recherche. Essayez un autre mot-clé ou effacez le filtre.",
51
51
  tocHeading: "Sur cette page",
52
52
  tocNavAria: "Sommaire du guide d’utilisation",
53
- lastUpdated: "Dernière mise à jour : avril 2026",
53
+ lastUpdated: "Dernière mise à jour : 12 mai 2026",
54
54
  sections: [
55
55
  {
56
56
  id: "ug-essence",
@@ -63,7 +63,7 @@ function frBundle(): UserGuideBundle {
63
63
  ],
64
64
  optionsTitle: "Trois « pièces » pour trois gestes",
65
65
  options: [
66
- "**Tableau de bord** — l’*atelier* (sessions, tâches, minuteur, raccourcis d’**étiquettes** / **@projets**).",
66
+ "**Tableau de bord** — l’*atelier* (sessions, tâches, minuteur, raccourcis **#étiquettes** / **@projets** travail / **!projets** personnels).",
67
67
  "**Rapports** — le *regard en hauteur* (période, thèmes, graphiques, sans refabriquer les chiffres).",
68
68
  "**Paramètres** — l’*arrière-boutique* (habitudes, raccordements, zone où l’on *efface* l’histoire *avec prudence*). [Ouvrir Paramètres](/settings#settings-usage-profile).",
69
69
  ],
@@ -71,7 +71,7 @@ function frBundle(): UserGuideBundle {
71
71
  steps: [
72
72
  "Ouvrez l’**accueil** (tableau de bord) : c’est ici que démarre l’**atelier**.",
73
73
  "Déclenchez **Nouvelle session** (ou laissez l’app en créer une *la première fois* qu’une tâche part).",
74
- "Décrivez un **coup de tâche** (titre) ; un **#mot** = étiquette, un **@nom** = *projet* (le formulaire *devine* souvent l’un et l’autre).",
74
+ "Décrivez un **coup de tâche** (titre) ; un **#mot** = étiquette ; **@nom** = *projet* de travail ; **!nom** = *projet personnel* (le formulaire *devine* souvent l’un et l’autre). Ajoutez au besoin une **note libre** sur la tâche et, côté session, une **note de session**.",
75
75
  "Appuyez sur **Démarrer** (ou lancez le **KronoFocus** *à côté*) pour **tenir** un *créneau*.",
76
76
  "Quand la journée le demande, ouvrez **Rapports** pour *voir* ce qui c’est *passé* dans la période — *sans* y passer la soirée en tableurs.",
77
77
  ],
@@ -84,57 +84,89 @@ function frBundle(): UserGuideBundle {
84
84
  "La **barre du haut** est *toujours* la même famille : mêmes outils, même **ton** (zinc, accents **violet**), pour ne pas recharger le cerveau *à chaque page*. L’icône **roue** mène à [Paramètres](/settings#settings-usage-profile) (raccourci **Alt+Shift+S** depuis le tableau de bord).",
85
85
  ],
86
86
  steps: [
87
- "En **tableau de bord** : l’icône **Livre** mène ici, puis **Rapports** (graphe), **Paramètres** (roue).",
88
- "Sur **les autres pages** : revenez à l’**accueil** (icône en **grille**), puis mêmes **Livre**, **Rapports**, **Paramètres** (et, sur **Licences** seule, l’icône **document**).",
87
+ "En **tableau de bord** : l’icône **Livre** mène ici, puis **Rapports** (graphe), **Paramètres** (roue) et **Implémentation** (code — inventaire des user stories).",
88
+ "Sur **les autres pages** : revenez à l’**accueil** (icône en **grille**), puis mêmes **Livre**, **Rapports**, **Paramètres**, **Implémentation** ; sur **Implémentation**, une icône **changelog** ouvre `/changelog` ; sur **Licences** seule, l’icône **document** s’ajoute.",
89
+ "Sur **Implémentation**, les lignes pourvues d’un **chevron** déploient une **précision** et un **exemple** (texte plus petit) sans allonger la liste principale.",
90
+ "Toujours en tableau de bord, un bouton **Gantt du jour** (grille) ouvre une frise globale avec les tâches de **toutes** les sessions pour la journée en cours.",
89
91
  "Le **bouton thème** bascule **clair / sombre** (le soir ou salle trop lumineuse).",
90
92
  "Le bouton **actualiser** redemande l’**état** au serveur (utile si quelqu’un/quelque chose a changé dehors *sans* recharger toute l’**app**).",
91
93
  "Ouvrez le **menu de langue** (FR / EN) ; la **préférence** peut se **mémoriser** côté moteur si c’est la configuration chez vous.",
92
94
  ],
93
95
  options: [
94
- "**Livre** = ce **guide** ; **graphe** = **Rapports** ; **roue** = **Paramètres** ; **fichier** = **Licences** (cette dernière **seule** sur l’icône document).",
96
+ "**Livre** = ce **guide** ; **graphe** = **Rapports** ; **roue** = **Paramètres** ; **grille** = **Gantt du jour** (tableau de bord) ; **code** = **Implémentation** (user stories ✓/✗) ; **changelog** = journal utilisateur (icône dédiée sur Implémentation) ; **fichier** = **Licences** (cette dernière **seule** sur l’icône document).",
95
97
  "Changer de **thème** ne modifie **pas** le **fond** de vos enregistrements — seulement le **confort** visuel (même **décor** d’écran d’une page à l’autre, pour ne pas se **perdre** entre les onglets)."
96
98
  ],
97
99
  },
98
100
  {
99
101
  id: "ug-layout",
100
102
  title: "Où travailler, où regarder, où régler — + juridique",
101
- searchIndex: "navigation tableaux bord rapports paramètres licences",
103
+ searchIndex: "navigation tableaux bord rapports paramètres licences horloge fuseau",
102
104
  paragraphs: [
103
105
  "Trois gestes, trois endroits : l’**atelier** (maintenant), les **Rapports** (retour sur une période), les **Paramètres** (coulisses, effacements sensibles, branchements). Puis **Licences**, la page d’honnêteté sur le code **open source** et les polices.",
104
106
  ],
105
107
  options: [
106
- "**Tableau de bord** — à gauche la **file des sessions** ; au centre les **tâches** (minuteurs, détail) ; à droite les raccourcis d’**étiquettes** et **@projets** pour ne pas retaper les mêmes mots. C’est l’usage **quotidien**.",
108
+ "**Tableau de bord** — à gauche la **file des sessions** ; au centre les **tâches** (minuteurs, détail) ; à droite les raccourcis d’**étiquettes** et de **projets** (**@** travail, **!** personnel) pour ne pas retaper les mêmes mots. C’est l’usage **quotidien**.",
107
109
  "**Rapports** — choisir une **plage de dates** et, si besoin, des **#étiquettes** ; lire résumés et graphiques. Une **visite guidée** est proposée la première fois sur l’écran.",
108
110
  "**Paramètres** — profil, collecte, planification, étiquettes avancées, **Git** ou miroir en **option** ; la **zone dangereuse** supprime l’historique (avec saisie de confirmation). [Sommaire des paramètres](/settings#settings-usage-profile) · [zone de danger](/settings#settings-danger-zone). N’y entrez **que** quand vous le **décidez**.",
109
- "**Licences** — textes MIT, logiciels tiers, polices ; icône **document** **uniquement** sur cette page."
111
+ "**Licences** — textes MIT, logiciels tiers, polices ; icône **document** **uniquement** sur cette page.",
112
+ "Une **horloge murale** (fuseau et format 12/24 h des paramètres **Tableau de bord web**) tourne en permanence dans la **barre d’outils** de l’en-tête, à gauche des icônes de navigation."
113
+ ],
114
+ },
115
+ {
116
+ id: "ug-convention-end-vs-pause",
117
+ title: "Convention : heure de fin et pause",
118
+ searchIndex:
119
+ "convention pause fin programmée échéance terminaison clôture minuteur pause globale différée mise en veille",
120
+ paragraphs: [
121
+ "Dans Kronosys, une **heure de fin** que vous **programmez** sur une **tâche** ou une **session** en cours définit une **terminaison** à cet instant — ce n’est **pas** une pause **reportée**, ni une mise en veille différée.",
122
+ "Pour **mettre en pause** le suivi (minuteur, murale, session), utilisez les **actions de pause** prévues à cet effet ; elles sont **distinctes** de la notion d’**échéance** ou de **fin programmée**.",
123
+ ],
124
+ bullets: [
125
+ "**Fin programmée** → la tâche est **terminée** ou la session **clôturée** à l’instant choisi.",
126
+ "**Pause** → action **explicite** (minuteur, session live en pause, pause globale, etc.).",
110
127
  ],
111
128
  },
112
129
  {
113
130
  id: "ug-sessions-tasks",
114
131
  title: "Sessions, tâches, étiquettes et projets",
115
- searchIndex: "session live archiver terminer tâche minuteur pause sous-tâche",
132
+ searchIndex:
133
+ "session live archiver terminer tâche minuteur pause sous-tâche historique liste résumé planifiée pastille badge conflit navigation projet personnel !perso jeton collé courriel",
116
134
  paragraphs: [
117
- "La **session** est le **sac** où vient s’additionner le travail sur une période ; la **tâche** est le fil conducteur du moment. **#mot** = thème, **@nom** = projet (le formulaire en propose souvent) — c’est de la **classification**, pas un examen d’orthographe.",
135
+ "La **session** est le **sac** où vient s’additionner le travail sur une période ; la **tâche** est le fil conducteur du moment. **#mot** = thème ; **@nom** = projet **productif** ; **!nom** = projet **personnel** (suivi hors travail facturable, pastille souvent **rose**) — c’est de la **classification**, pas un examen d’orthographe. Le **`!`** (y compris **`!projet#sous-étiquette`**) peut être **collé** au mot précédent **sans espace** — ex. `Courrier!perso#dentiste` ; le **`@`** reste en principe **après un espace** ou en **début** de segment pour limiter les faux positifs sur les courriels.",
118
136
  ],
119
137
  optionsTitle: "Nouvelle session — le cadre, au choix",
120
138
  options: [
139
+ "**Début** : **maintenant** (lancement immédiat) ou **dans le passé** — dans ce cas, saisie du **début et de la fin** en heure locale du navigateur — si une session est **déjà active**, un **lancement immédiat** ouvre d’abord la **fin de session** (comme le bouton habituel) ; un **début rétroactif** **n’interrompt pas** la session active : la nouvelle ligne va dans l’**historique** et l’écran se place dessus pour **saisir des tâches** (mode passé).",
121
140
  "**Portée minimale** : pas de bordage particulier — vous lancez et c’est le flux qui mène.",
122
141
  "**Durée max (horloge murale)** : l’onglet s’y prête (rappel, pas alarme) quand on veut cadrer un gros **morceau** de journée.",
123
142
  "**Fenêtre calendrier** : dates de **début** et de **fin** (engagement auprès de vous-même ou d’un tiers).",
124
143
  "**Semaine** : jours de la semaine + **plage horaire** (utile en rythme **fixe** — pas pour tout le monde, et c’est normal).",
125
144
  "Dans les sélecteurs de dates/heures, les actions rapides **Aujourd’hui** et/ou **Maintenant** sont disponibles pour éviter la saisie manuelle.",
126
- "Les **tâches** se suivent en **direct** (minuteur) ou s’inscrivent **dans le passé** (début / fin explicites) : honnête quand on remplit **après coup** le soir, sans théâtre."
145
+ "Les **tâches** se suivent en **direct** (minuteur) ou s’inscrivent **dans le passé** (début, fin et **durée du minuteur** en h/m/s comme lors d’un ajustement) : honnête quand on remplit **après coup** le soir, sans théâtre."
127
146
  ],
128
147
  stepsTitle: "Dès que vous avez cliqué « Démarrer » sur une tâche (ordre usuel)",
129
148
  steps: [
130
- "Taper un **titre** ; saupoudrer d’un **#** (étiquette) et/ou d’un **@** (projet) dès que le mot vient (aperçu souvent **sous** le champ de saisie).",
149
+ "Taper un **titre** ; saupoudrer d’un **#** (étiquette), d’un **@** (projet travail) et/ou d’un **!** (projet personnel) dès que le mot vient (aperçu souvent **sous** le champ de saisie).",
131
150
  "Cliquer **Démarrer** sur la tâche — ou, si l’heure s’y prête, lancer d’**abord** le **KronoFocus** depuis cette tâche (même bateau, rythme différent).",
132
151
  "Si le minuteur d’**une** autre tâche tourne déjà : l’appli offre **pause** sur l’ancienne, **terminer** l’ancienne, ou **tout** tenir en parallèle (vous **pouvez** mémoriser l’**option** pour les prochains lancements).",
133
152
  "En **cours** : lister des **sous-tâches** ; les cocher, les reclasser au **glisser-déposer** ; **pause** / reprise en douceur.",
134
153
  "**Terminer la session** quand le bloc a une fin (bouton d’en-tête ou bannière) ; une **raison** de clôture **facultative** (dans les temps, en avance, dépassement, autre + note) : pour poser mots sur la **fin** du cycle — d’**abord** pour vous, pas pour un **audit** froid."
135
154
  ],
136
155
  bullets: [
137
- "L’**option** **Commit** à la fin d’une tâche, quand elle apparaît, concerne **Git** (voir [Synchronisation Git](/settings#settings-git) côté paramètres) : elle n’est **là** que **si** lintégration est en place — les **équipiers** **non** devs peuvent l’**ignorer** sereinement."
156
+ "Chaque **tâche** peut porter une **note libre** (texte) visible sur la carte ; cette note saffiche avant les **sous-tâches** pour garder le contexte en tête.",
157
+ "Chaque **session** peut porter une **note de session** ; un aperçu (icône + extrait) apparaît dans la liste des sessions et dans les archives.",
158
+ "Le bouton de **pause globale** est **inactif** (avec une infobulle) lorsque **rien ne tourne** : murale déjà figée et aucun minuteur ; sinon il ouvre une **confirmation** avec un **résumé** : **début** et **fin** (ou mention *en cours*), **durée murale**, **temps de codage** et **temps actif** de session lorsque l’hôte les fournit, décompte **tâches** / **sous-tâches**, **total enregistré** sur les minuteurs de tâches puis **répartition** minuteur principal vs sous-tâches, puis la liste des effets sur les minuteurs ; une fois validée, il met en pause la session, les tâches et les sous-tâches en cours du contexte affiché ; le clic suivant **reprend uniquement** ce lot.",
159
+ "La **pause session** (contrôle d’**en-tête** lorsque la session est **live**) **fige aussi** les minuteurs **actifs** des **tâches** et **sous-tâches** ; **reprendre la session** ne rallume que ce qui avait été gelé **par cette pause** — pas une tâche déjà laissée en pause **manuelle** avant. Reprendre une **tâche** avant le bandeau retire cette entrée du **lot** concerné par une reprise session ultérieure.",
160
+ "À la **fermeture** d’une session avec des tâches ouvertes, vous pouvez les **terminer**, les **transposer** vers une **nouvelle session en pause**, ou les **laisser ouvertes** dans l’instantané archivé ; dans tous les cas, les **minuteurs** de cette session **cessent**.",
161
+ "Dans une **session live** ainsi en pause, un **bandeau** propose de **reprendre la session** ; le **lecture** sur une tâche **reprend aussi** l’horloge murale (collecte).",
162
+ "Lorsque la session live est en **pause** (murale et minuteurs concernés, ou **pause globale**), le bloc **Session en cours** affiche une pastille **En pause** ou **Pause globale** ; un **voile** à l’écran centre un rappel, la **barre du haut** restant utilisable pour **reprendre**.",
163
+ "Même une **session passée terminée** accepte encore une **entrée dans le passé** : sélectionnez-la, indiquez début, fin et durée, puis ajoutez la tâche à son historique.",
164
+ "Dans [Paramètres → Tableau de bord web](/settings#settings-default-session-name), un **gabarit** optionnel définit le **nom initial** des **nouvelles** sessions (`%UUID`, codes date/heure façon POSIX `strftime` — référence indiquée sur l’écran) avec le même **fuseau d’affichage** que le tableau de bord et les rapports.",
165
+ "Sur une tâche **en cours**, **en pause** ou **terminée**, un bouton **Sauvegarder comme template** (icône) enregistre son titre, **#étiquettes** et projet **@** ou **!** ; la saisie « sur quoi travaillez-vous » propose ces modèles (**Modèle :** dans les suggestions) avec recherche **debounce**, la **palette Ctrl+K** les inclut, et [Paramètres → Modèles de tâche](/settings#settings-task-templates) permet aussi de les **gérer**.",
166
+ "Lors d’une correction d’**heure de début/fin** d’une tâche, une modale vous laisse choisir la règle de durée : conserver la durée système, saisir une durée manuelle, ou recalculer depuis début/fin. Pour une tâche en cours, une **heure de fin** (passée ou future) **termine la tâche** à cet instant — ce n’est pas une simple pause du minuteur.",
167
+ "Lorsque le **début** d’une tâche **non terminée** est encore **dans le futur** (horloge), l’entrée est sous **Planifiées** avec un style **bleu ciel** : pas de **minuteur** « en direct ». Pour une tâche **terminée**, le bloc « planifié » ne s’applique que si **début et fin** sont encore **tous deux** dans le futur ; si le début est déjà passé et seule la fin est future, l’entrée reste avec les **terminées** (évite d’y rester coincée jusqu’à l’heure de fin). Même logique visuelle pour une **session live** dont l’**heure de début officielle** est encore dans le futur (ligne distincte dans la liste). Il n’y a **pas de pastille texte** « planifié » : la distinction repose sur la section, le style et le point d’état.",
168
+ "Lorsqu’une tâche **sort de Planifiées** et devient **en cours** alors qu’**au moins un** autre minuteur était déjà affiché comme **en cours**, une modale propose les mêmes options **pause / terminer / parallèle** (avec la même mémorisation que pour le démarrage manuel) pour les **tâches déjà au minuteur** ; hors route du tableau de bord, l’icône **Tableau de bord** peut **pulser** brièvement pour signaler qu’une action est attendue.",
169
+ "Pour une **session** de l’**historique** (pas la session **live**), le **résumé** (nom, durée, métriques) s’affiche **sous la ligne** correspondante dans la **liste** des sessions, pour garder le détail au même endroit pendant la navigation."
138
170
  ],
139
171
  },
140
172
  {
@@ -158,16 +190,16 @@ function frBundle(): UserGuideBundle {
158
190
  },
159
191
  {
160
192
  id: "ug-search-palette",
161
- title: "Recherche : données (tableau de bord) & rubriques (ce guide)",
162
- searchIndex: "palette recherche données sessions tâches ctrl k",
193
+ title: "Recherche Spotlight : données (tableau de bord) & rubriques (ce guide)",
194
+ searchIndex: "palette recherche données sessions tâches modèles ctrl k",
163
195
  paragraphs: [
164
- "Même **allure** de champ (bordure zinc, focus **violet**) : **deux cibles** — d’**abord** l’**atelier** (sessions, tâches, étiquettes, mots du workspace) ; **ensuite** le **fil** en tête de **cette** page, qui ne filtre **que** les **rubriques** du **guide**."
196
+ "Même **allure** de champ (bordure zinc, focus **violet**) : **deux cibles** — d’**abord** l’**atelier** (sessions, tâches, **modèles de tâche**, étiquettes, mots du workspace) ; **ensuite** le **fil** en tête de **cette** page, qui ne filtre **que** les **rubriques** du **guide**."
165
197
  ],
166
198
  stepsTitle: "Données — la palette (tableau de bord)",
167
199
  steps: [
168
200
  "Cliquer sur **Rechercher dans les données** ou presser **Ctrl+K** (Windows / Linux) / **⌘K** (macOS) : la **palette** s’ouvre (raccourci **réservé** : on ne le **redéfinit** **pas** dans la modale raccourcis).",
169
- "Saisir **deux** ou **trois** **lettres** d’**une** **session**, d’**une** **tâche**, d’**un** **#** ou d’**un** **@** : la **liste** se **restreint** en **direct**.",
170
- "Choisir **une** **ligne** (**Entrée** ou **clic**) : l’**écran** **saute** **vers** l’**objet** ; **Échap** **ferme** la **boîte** **sans** **toucher** le **fond**."
201
+ "Saisir **deux** ou **trois** **lettres** d’**une** **session**, d’**une** **tâche**, d’**un** **modèle**, d’**un** **#**, d’**un** **@** ou d’**un** **!** : la **liste** se **restreint** en **direct**.",
202
+ "Choisir **une** **ligne** (**Entrée** ou **clic**) : l’**écran** **saute** **vers** l’**objet** ; pour **un modèle**, le **champ** nouvelle **tâche** est **rempli** ; **Échap** **ferme** la **boîte** **sans** **toucher** le **fond**."
171
203
  ],
172
204
  optionsTitle: "Ce guide — le champ collé en haut de page",
173
205
  options: [
@@ -180,7 +212,7 @@ function frBundle(): UserGuideBundle {
180
212
  title: "Raccourcis clavier (tableau de bord)",
181
213
  searchIndex: "raccourcis clavier alt shift ctrl",
182
214
  paragraphs: [
183
- "Ouvrez la **modale des raccourcis** depuis le petit clavier près de la palette pour voir, **modifier** ou **réinitialiser** les combinaisons (les touches **Ctrl+K** / **⌘K** restent réservées à la palette de recherche de données). La relance de **certaines** visites guidées et des options d’**API** se gèrent aussi dans [Paramètres — Web & API](/settings#settings-web).",
215
+ "Ouvrez la **modale des raccourcis** depuis le petit clavier près de la palette pour voir, **modifier** ou **réinitialiser** les combinaisons (les touches **Ctrl+K** / **⌘K** restent réservées à la palette **Spotlight**). La relance de **certaines** visites guidées et des options d’**API** se gèrent aussi dans [Paramètres — Web & API](/settings#settings-web).",
184
216
  ],
185
217
  bullets: [
186
218
  "Nouvelle session : Alt+Shift+N (par défaut).",
@@ -203,18 +235,21 @@ function frBundle(): UserGuideBundle {
203
235
  "Ouvrir **Rapports** (icône **graphe** ou raccourci **Alt+Shift+G** sur le tableau de bord).",
204
236
  "Choisir une **plage** : champs **Du** / **Au**, bouton **Aujourd’hui**, ou préréglages **jour** / **semaine** / **mois** / **année** (selon ce que l’UI expose).",
205
237
  "Optionnel : **sélectionner** une ou plusieurs **#étiquettes** pour **restreindre** les tâches (les **sessions** **sans** tâche **correspondante** **disparaissent** des **vues** **basées** **tâches**).",
206
- "Lire les **blocs** : **résumé**, **tableaux** par **jour**, **temps** par **@projet** / **#tag**, **navigation** de **semaine** **le** **cas** **échéant** ; **lancer** la **visite** **guidée** **si** la **pancarte** **le** **propose**."
238
+ "Lire les **blocs** : **résumé**, **tableaux** par **jour**, temps par **@projet** / **!projet** / **#tag** (les grilles **par projet** du tableau **Rapports** comptent par défaut le temps **@** sans y mélanger le temps **!**) ; **navigation** de **semaine** **le** **cas** **échéant** ; **lancer** la **visite** **guidée** **si** la **pancarte** **le** **propose**.",
207
239
  ],
208
240
  options: [
209
241
  "**Indicateurs non finaux** (pastilles) : rappellent le **travail encore ouvert** dans la plage — lire prudemment, pas de chiffrage *figé* tant que des tâches *bougent* encore.",
242
+ "Sous le **résumé**, une **ventilation** peut compter les **sessions** par **type de clôture** enregistré à la fin de session (lorsque l’hôte en a choisi un) ; les sessions **sans** catégorie y figurent à part.",
243
+ "Le **tableau par jour** inclut aussi un total de temps tâche **non concurrent** (sans chevauchement des intervalles horodatés) pour comparer avec le temps enregistré brut.",
210
244
  "**Début de semaine** (lundi, dimanche ou samedi) : réglage souvent près des **calendriers** hebdo des rapports — choisissez **ce** qui coïncide avec **votre** semaine réelle.",
211
- "Relancer la visite **Rapports** (aide **premier pas** sur l’écran) : [Paramètres — visite Rapports](/settings#settings-reporting-tour)."
245
+ "Relancer la visite **Rapports** (aide **premier pas** sur l’écran) : [Paramètres — visite Rapports](/settings#settings-reporting-tour).",
246
+ "Une **deuxième grille** dédiée au seul temps personnel (`!`), **miroir** de celle des projets `@`, **n’est pas** encore dans l’interface ; les agrégats côté moteur prévoient déjà les filtres pour une version ultérieure.",
212
247
  ],
213
248
  },
214
249
  {
215
250
  id: "ug-settings-integrations",
216
251
  title: "Paramètres, sauvegardes et bouts d’usine (quand vous êtes prêt·e)",
217
- searchIndex: "export backup sqlite json csv gitlab mongo v4 v4-dev next dev développement local",
252
+ searchIndex: "export backup restore restauration sqlite json csv gitlab mongo v4 v4-dev next dev développement local",
218
253
  paragraphs: [
219
254
  "Ici, vous **réglez** l’**appareil** (KronoFocus, **étiquettes** / **@** avancés, planification) et, **seulement si** vous voulez, le **câble** (Git, GitLab, miroir). La **zone dangereuse** : **lisez** le texte à l’**écran** et la **phrase** de confirmation avant de **valider** un **effacement**. L’[index de la page Paramètres](/settings#settings-usage-profile) liste toutes les sections (sommaire à gauche en grand écran)."
220
255
  ],
@@ -222,9 +257,11 @@ function frBundle(): UserGuideBundle {
222
257
  options: [
223
258
  "**Profil d’usage** ([ancre Profil d’utilisation](/settings#settings-usage-profile)) : ex. *gestion* masque des blocs (p. ex. Lignes de code) qu’un **dév** n’aurait pas caché.",
224
259
  "[KronoFocus](/settings#settings-kronoFocus), [Collecte et tampons](/settings#settings-collection), [Horaire de travail](/settings#settings-schedule) ou [sessions planifiées](/settings#settings-planned-sessions), [Tâches et étiquettes](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB](/settings#settings-mongo) en branchement **opt-in** (rien n’impose d’ouvrir tout le premier soir).",
225
- "**Corrections d’horaire** : commutateurs **on/off** dans [Tâches et étiquettes](/settings#settings-task-tags) pour le **début** et la **fin** d’une **tâche**, et le **début** et la **fin** d’une **session** (la fin : tâches et sessions déjà terminées).",
260
+ "**Migration d’étiquettes** : dans [Tâches et étiquettes](/settings#settings-task-tags), l’outil de portée permet de **copier** ou **déplacer** une étiquette globale vers une portée projet (`Projet#tag`) et l’inverse.",
261
+ "**Renommage des étiquettes/projets (inline)** : dans la colonne droite **Tags / Projects / Templates**, cliquez sur le crayon, modifiez le nom directement dans la ligne puis validez par **Entrée** (ou **Échap** pour annuler). Un avertissement précise l’impact sur les **rapports** ; vous pouvez cocher « ne plus afficher » pour les prochains renommages. (Les listes **`knownPersonalProjects`** pour les jetons **`!`** ne disposent pas encore du même écran d’inline que les projets **`@`**.)",
262
+ "**Corrections d’horaire** : commutateurs **on/off** dans [Tâches et étiquettes](/settings#settings-task-tags) pour le **début** et la **fin** d’une **tâche**, et le **début** et la **fin** d’une **session**. Sur une **tâche** en cours, une heure de fin **termine la tâche** à l’instant prévu. Sur une **session** live, une heure de fin **clôt la session** à l’instant prévu (instantané en historique, équivalent d’une fin de session en mode conserver les tâches ouvertes).",
226
263
  "**Général — mode développement (coffre local)** ([Paramètres → Général](/settings#settings-dev-data), seulement en `next dev`) : **Enregistrer** avec le bouton principal ; par défaut, **jeu de données** séparé de la **production** ; on peut partager le coffre `v4` (puis **redémarrer** le serveur de dev).",
227
- "**Sauvegarde** (export) : côté technique l’**API** `GET /api/backup` sert le fichier (paramètre de **format**) ; côté **appli** voir aussi [Export par défaut](/settings#settings-export). L’**URL** de base et l’**install** = **README** côté déploiement."
264
+ "**Sauvegarde / restauration complète** : côté technique, `GET /api/backup` exporte (format), et `POST /api/restore` restaure un fichier JSON ou SQLite ; côté appli, la **Zone de danger** fournit les actions de sauvegarde + restauration guidée.",
228
265
  ],
229
266
  stepsTitle: "Avant d’effacer l’historique (check-list courte)",
230
267
  steps: [
@@ -249,7 +286,7 @@ function enBundle(): UserGuideBundle {
249
286
  searchNoResults: "No section matches. Try another keyword or clear the filter.",
250
287
  tocHeading: "On this page",
251
288
  tocNavAria: "User guide table of contents",
252
- lastUpdated: "Last updated: April 2026",
289
+ lastUpdated: "Last updated: 12 May 2026",
253
290
  sections: [
254
291
  {
255
292
  id: "ug-essence",
@@ -262,7 +299,7 @@ function enBundle(): UserGuideBundle {
262
299
  ],
263
300
  optionsTitle: "Three “rooms” for three moves",
264
301
  options: [
265
- "**Dashboard** — the workbench (sessions, tasks, focus timer, **#** tags and **@** projects).",
302
+ "**Dashboard** — the workbench (sessions, tasks, focus timer, **#** tags, **@** work projects, and **!** personal projects).",
266
303
  "**Reports** — the look back (range, themes, charts: numbers come from what you **already** logged).",
267
304
  "**Settings** — the back room (habits, connections, the **danger** zone where you wipe history **carefully**). [Open Settings](/settings#settings-usage-profile).",
268
305
  ],
@@ -270,7 +307,7 @@ function enBundle(): UserGuideBundle {
270
307
  steps: [
271
308
  "Open the **home** (dashboard) — the workbench starts there.",
272
309
  "Start a **new session** (or let the app start one the first time a task needs it).",
273
- "Name a **task**; **#** = tag, **@** = project (the form often **suggests** both from what you type).",
310
+ "Name a **task**; **#** = tag; **@** = work project; **!** = personal project (the form often **suggests** tags and projects from what you type).",
274
311
  "Press **Start** on the task, or add **KronoFocus** on the **side** if a ritual helps more than a bare timer in the list.",
275
312
  "When you need the bigger picture, open **Reports** for a **date range** — you should not have to re-run the week in spreadsheets to see it.",
276
313
  ],
@@ -283,56 +320,88 @@ function enBundle(): UserGuideBundle {
283
320
  "The top bar reuses the **same** **family** of controls (zinc, **violet** accents) on every page so **navigation** stays **light** on the brain. The **cog** icon opens [Settings](/settings#settings-usage-profile) (shortcut **Alt+Shift+S** from the dashboard).",
284
321
  ],
285
322
  steps: [
286
- "On the **dashboard**: **Book** → this guide; **chart** → **Reports**; **cog** → **Settings**.",
287
- "On **other** pages: **grid** back to **home**; same book / chart / cog; on **Licenses** only, you also get a **file** icon.",
323
+ "On the **dashboard**: **Book** → this guide; **chart** → **Reports**; **cog** → **Settings**; **code** → user stories (implementation status).",
324
+ "On **other** pages: **grid** back to **home**; same book / chart / cog / code; on **Implementation**, a dedicated **changelog** icon opens `/changelog`; on **Licenses** only, you also get a **file** icon.",
325
+ "On **Implementation**, rows with a **chevron** expand for extra **detail** and an **example** (smaller type) under the short wording.",
326
+ "Still on the dashboard, a **Today Gantt** button (grid) opens one global timeline for tasks from **all** sessions in the current day.",
288
327
  "**Theme** toggle: **light** or **dark** (evening work or a bright room).",
289
328
  "**Refresh** fetches state again from the **server** (e.g. after a change you know happened elsewhere).",
290
329
  "**Language** menu: **EN** / **FR**; if the server is configured, the choice can **stick** between visits.",
291
330
  ],
292
331
  options: [
293
- "**Book** = this guide; **Chart** = **Reports**; **Cog** = **Settings**; **File** = **Licenses** (only on the licenses page).",
332
+ "**Book** = this guide; **Chart** = **Reports**; **Cog** = **Settings**; **Grid** = **Today Gantt** (dashboard); **Code** = user stories (✓/✗); **Changelog** = user update log (dedicated icon on Implementation); **File** = **Licenses** (only on the licenses page).",
294
333
  "The **theme** only changes how the **UI** looks — it does **not** alter your stored work.",
295
334
  ],
296
335
  },
297
336
  {
298
337
  id: "ug-layout",
299
338
  title: "Where to work, where to look back, where to tune",
300
- searchIndex: "workspace dashboard reports settings license legal",
339
+ searchIndex: "workspace dashboard reports settings license legal clock timezone",
301
340
  paragraphs: [
302
341
  "Three main moves: the workbench (now), **Reports** (then), **Settings** (how the app runs + serious cleanup). **Licenses** is the honest credit page for the open building blocks we use.",
303
342
  ],
304
343
  options: [
305
- "**Dashboard** — **sessions** on the left, **tasks** in the **centre**, **tag** and **@** **shortcuts** on the right so you stop retyping the same words.",
344
+ "**Dashboard** — **sessions** on the left, **tasks** in the **centre**, **tag** and **project** shortcuts (**@** work, **!** personal) on the right so you stop retyping the same words.",
306
345
  "**Reports** — pick a **date range** and, if needed, **#** tags; read **summaries** and **charts**; the **tour** may offer itself the first time you land there.",
307
346
  "**Settings** — profile, collection, scheduling, **advanced** tags, optional **Git** or **remote**; the **danger zone** can **delete** all **history** (type-to-confirm). [Settings overview](/settings#settings-usage-profile) · [danger zone](/settings#settings-danger-zone).",
308
347
  "**Licenses** — MIT, third parties, **fonts**; the **file** icon **only** on that page.",
348
+ "A **wall clock** (time zone and 12/24 h from **Web dashboard** settings) stays visible in the header **toolbar**, left of the navigation icons."
349
+ ],
350
+ },
351
+ {
352
+ id: "ug-convention-end-vs-pause",
353
+ title: "Convention: scheduled end time vs pause",
354
+ searchIndex:
355
+ "convention pause scheduled end completion closure timer wall clock deferred break",
356
+ paragraphs: [
357
+ "In Kronosys, a **scheduled end time** on a **running task** or **session** means **completion** at that instant — it is **not** a **deferred pause** or “pause later at this clock time”.",
358
+ "To **pause** tracking (timer, wall clock, session), use the **pause actions** built for that purpose; they are **separate** from **deadlines** and **scheduled ends**.",
359
+ ],
360
+ bullets: [
361
+ "**Scheduled end** → the **task finishes** or the **session closes** at the chosen instant.",
362
+ "**Pause** → an **explicit action** (task timer, paused live session, global pause, etc.).",
309
363
  ],
310
364
  },
311
365
  {
312
366
  id: "ug-sessions-tasks",
313
367
  title: "Sessions, tasks, tags, and projects",
314
- searchIndex: "session archive end task timer pause subtask",
368
+ searchIndex:
369
+ "session archive end task timer pause subtask history list summary planned badge chip conflict navigation personal project glued bang email",
315
370
  paragraphs: [
316
- "A **session** is the **bag** work piles into; a **task** is the **thread** of a moment. **#** and **@** are naming helpers, not a grammar test.",
371
+ "A **session** is the **bag** work piles into; a **task** is the **thread** of a moment. **#** tags themes; **@** marks a **work** project; **!** marks a **personal** project (often a **rose** chip) — naming helpers, not a grammar test. **`!`** (including **`!project#subtag`**) may be **glued** to the previous word with **no space** — e.g. `Errands!personal#dentist`; **`@`** still expects **whitespace before** or **start of field** so emails like `user@host` are not parsed as projects.",
317
372
  ],
318
373
  optionsTitle: "New session — the frame, your choice",
319
374
  options: [
375
+ "**Start** **now** (immediate) or **in the past** — then enter **both start and end** in your browser’s local date and time — if a session is **already live**, **starting now** runs the usual **end session** flow first; a **backdated** row does **not** interrupt the live session: it is added to **history** and the UI focuses it so you can **log tasks** in the past.",
320
376
  "**No** extra frame in particular: start, and the flow **carries** you.",
321
377
  "**Max wall** clock: a **nudge** to reframe a **very** long stint.",
322
378
  "**Calendar** window: from / to **dates** (a commitment to your later self or someone else).",
323
379
  "**Week** + time window on selected **weekdays** (handy in a **fixed** rhythm; skip it if you hate that).",
324
- "Tasks in **real time** or back-filled with start and end: honest to log the evening for **yesterday**’s work.",
380
+ "Tasks in **real time** or back-filled with start, end, and **timer duration** (h/m/s — same idea as duration adjustments): honest to log the evening for **yesterday**’s work.",
325
381
  ],
326
382
  stepsTitle: "After you press “Start” on a task (usual order)",
327
383
  steps: [
328
- "Type a **title**; add **#** and/or **@** when the words come (a **live** **preview** often shows under the field).",
384
+ "Type a **title**; add **#**, **@**, and/or **!** when the words come (a **live** **preview** often shows under the field). Add an optional **free-text task note**, and a **session note** when useful.",
329
385
  "Click **Start** on the task — or, if it fits, launch **KronoFocus** from that **task** first (same work, different rhythm).",
330
386
  "If another **timer** is on: **pause** it, **finish** it, or allow both in **parallel** (you can **save** the choice for the next time).",
331
387
  "While in progress: add **subtasks**; check them; **reorder** by **drag and drop**; use **pause** and **resume** kindly.",
332
388
  "**End session** from the header or banner: optional end reason (on time, early, overrun, other + note) — a word for **how** the block **ended**, not a cold verdict.",
333
389
  ],
334
390
  bullets: [
335
- "When **Commit** on **finish** appears, it is about **Git** (see [Git sync](/settings#settings-git) in **Settings**) you can **ignore** it with a clear head if you are not in that workflow.",
391
+ "Each **task** supports a **free-text note** shown on the card; the note appears before the **subtasks** block to keep context first.",
392
+ "Each **session** supports a **session note**; a preview (icon + excerpt) appears in the session list and in archived sessions.",
393
+ "The **global pause** control is **inactive** (with a tooltip) when **nothing is running** — wall clock already frozen and no timers — otherwise it opens a **confirmation** with a **summary**: **start** and **end** (*ongoing* when there is no end yet), **wall duration**, **session coding** and **active** times when the host records them, **task** / **subtask** counts, **total recorded** task-timer time, then the **split** between **main task** time (excluding subtasks) and **subtask** timers, followed by the list of timer effects; once confirmed, it pauses the current session context (session, task timers, and subtask timers); the next click resumes **only that paused set**.",
394
+ "**Session pause** (header control while the session is **live**) also **freezes** **active** **task** and **subtask** timers; **resume session** only restarts what was frozen **by that pause** — not a task you had already paused **manually** beforehand. Resuming a **single task** removes it from the batch that a later **resume session** would restart.",
395
+ "When ending a session that still has open tasks, you can **finish** them, **move** them to a **new paused session**, or **leave** them **open** in the archived snapshot — **task timers for that session always stop**.",
396
+ "In that **live paused** session, a **banner** lets you **resume session**; **play** on a task also **resumes** wall-clock tracking.",
397
+ "When the live session is **paused** (wall clock and affected timers, or **global pause**), the **Active session** card shows a **Paused** or **Global pause** chip; a **dimmed overlay** centers a reminder while the **top bar** stays usable to **resume**.",
398
+ "Even a **completed past session** still accepts a **past entry**: select it, set start, end, and duration, then add the task to that history snapshot.",
399
+ "Under [Settings → Web dashboard](/settings#settings-default-session-name), an optional **template** sets the **default name** for each **new** session (`%UUID`, POSIX-style `strftime` fields — authoritative link on that screen). Expansion uses your **display** **time zone** (same buckets as Reporting).",
400
+ "On a **running**, **paused**, or **completed** task, **Save as template** (icon) saves its title, **#tags**, and either an **@** or **!** project. The “what are you working on” input suggests them (**Template:** in the dropdown) with **debounced** filtering; **Ctrl+K / ⌘K** search lists them; [Settings → Task templates](/settings#settings-task-templates) also lets you **manage** them.",
401
+ "When you edit a task **start/end** timestamp, a modal asks how to handle duration: keep system timer duration, enter duration manually, or recalculate from start/end. On a **running** task, an **end time** **completes the task** at that instant — it is not a soft pause.",
402
+ "When a **not-done** task’s **start** is still **in the future**, it is grouped under **Planned** with **sky** styling (no live timer). For a **completed** task, that **Planned** styling applies only when **both start and end** are still **strictly in the future**; if the start has passed but the end is still ahead (e.g. a scheduled end), the row stays under **Completed** instead of being stuck under **Planned** until the end time. The same idea applies to a **live** session whose official **start time** is still in the future (**distinct** row in the list). There is **no “planned” text badge** — section, styling, and the status dot carry the meaning.",
403
+ "When a **planned** task **becomes live tracking** while **another** timer was already shown as **running**, a modal offers **pause**, **finish**, and **parallel** (with the same optional **remember** setting as when you start a task manually), applying only to the **tasks that were already running** before the clock crossed; away from the dashboard route, the **Dashboard** icon may **pulse briefly** as a hint.",
404
+ "For a **session** in **history** (not the **live** one), the **summary** (name, duration, metrics) appears **under that row** in the sessions **list**, so details stay anchored to the same entry while you browse.",
336
405
  ],
337
406
  },
338
407
  {
@@ -356,16 +425,16 @@ function enBundle(): UserGuideBundle {
356
425
  },
357
426
  {
358
427
  id: "ug-search-palette",
359
- title: "Search: data (dashboard) and topics (this guide)",
360
- searchIndex: "palette data search ctrl k",
428
+ title: "Spotlight search: data (dashboard) and topics (this guide)",
429
+ searchIndex: "palette data search templates ctrl k",
361
430
  paragraphs: [
362
- "Same field **look** (zinc **border**, **violet** ring on **focus**): first the **workshop** (sessions, tasks, **#** / **@**); on **this** page, the line at the top only **filters** this help text.",
431
+ "Same field **look** (zinc **border**, **violet** ring on **focus**): first the **workshop** (sessions, tasks, **task templates**, **#** / **@** / **!**); on **this** page, the line at the top only **filters** this help text.",
363
432
  ],
364
433
  stepsTitle: "Data — the search palette (dashboard)",
365
434
  steps: [
366
435
  "Click **search data** or press **Ctrl+K** (win/linux) / **⌘K** (mac) — the palette is **reserved**; you do **not** rebind that chord in the **shortcuts** **modal**.",
367
- "Type a few **letters** of a **session**, **task**, **#**, or **@**; the list **tightens** as you type.",
368
- "**Enter** a row to **jump**; **Esc** closes the box without a full **page** **reload**.",
436
+ "Type a few **letters** of a **session**, **task**, **template**, **#**, **@**, or **!**; the list **tightens** as you type.",
437
+ "**Enter** a row to **jump**; for a **template**, the **new task** field is **filled**; **Esc** closes the box without a full **page** **reload**.",
369
438
  ],
370
439
  optionsTitle: "This guide — filter at the top of the page",
371
440
  options: [
@@ -402,19 +471,22 @@ function enBundle(): UserGuideBundle {
402
471
  "Set **from** and **to** (or a day / week / month / year **preset**, depending on what the UI offers).",
403
472
  "Use **Today** / **Now** quick actions in date/time pickers whenever available to jump to the current value.",
404
473
  "Optionally pick one or more **#** **tags** (sessions with **no** **matching** task may **disappear** from some **task**-based **views**).",
405
- "Scroll the **summary**, per-day **tables**, **@project** / **#tag** **breakdowns**, and the week nudger when your data has **enough** **weeks** to flip through.",
474
+ "Scroll the **summary**, per-day **tables**, **@** / **!** / **#** **breakdowns** (the **per-project** grids on **Reports** default to **@** work time and **exclude** **!** personal minutes from those rows), and the week nudger when your data has **enough** **weeks** to flip through.",
406
475
  "Start the **guided** **tour** if a prompt appears the **first** time.",
407
476
  ],
408
477
  options: [
409
478
  "**Non-final** chips mark work that is not **closed** in the **range** you are looking at: read them gently; the **draft** is not a **failure**.",
479
+ "Below the **summary** KPIs, a **breakdown** may count **sessions** by **closure type** saved when a session ended (when the host picked one); sessions **without** a stored category are grouped separately.",
480
+ "The **day table** now includes a **non-concurrent** task-time total (timestamped overlap removed) so you can compare it against raw recorded task time.",
410
481
  "**Week** starts on (Monday, Sunday, or Saturday) — often next to the tag-week **grids**; pick the one that **matches** how you read a week.",
411
482
  "Re-launch the **Reports** first-time **tour** from [Settings — Reporting tour](/settings#settings-reporting-tour).",
483
+ "A **second** grid that shows **only** personal (`!`) project time, **parallel** to the `@` project grid, is **not** in the UI yet; the aggregation layer already has filters for a future release.",
412
484
  ],
413
485
  },
414
486
  {
415
487
  id: "ug-settings-integrations",
416
488
  title: "Settings, safety copies, and extra wiring (when you are ready)",
417
- searchIndex: "export backup sqlite json gitlab mongo v4 v4-dev next dev local development",
489
+ searchIndex: "export backup restore sqlite json gitlab mongo v4 v4-dev next dev local development",
418
490
  paragraphs: [
419
491
  "Here you tune how the app **presents** itself (KronoFocus, tags and **@** **advanced** paths, **schedule**) and, only if you want, the **cable** to **Git**, GitLab, a **mirror**… The **danger** **zone** — read the on-screen text and the **type**-**to**-**confirm** line before a full **wipe**. The [Settings page index](/settings#settings-usage-profile) links every section (left-hand **TOC** on a wide window).",
420
492
  ],
@@ -422,9 +494,11 @@ function enBundle(): UserGuideBundle {
422
494
  options: [
423
495
  "**Usage** profile ([Usage profile section](/settings#settings-usage-profile)): e.g. *manager* hides some developer-heavy **panels** you might still want in *dev* mode.",
424
496
  "[KronoFocus](/settings#settings-kronoFocus), [Collection & buffers](/settings#settings-collection), [work schedule](/settings#settings-schedule) or [planned sessions](/settings#settings-planned-sessions), [Tasks & tags](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB mirror](/settings#settings-mongo) as **opt-in** (nothing forces you to turn everything on day one).",
425
- "**Time correction**: **on/off** toggles in [Tasks & tags](/settings#settings-task-tags) for **task** and **session** **start** times, plus separate toggles for **end** times on **completed** tasks and **finished** sessions.",
497
+ "In [Tasks & tags](/settings#settings-task-tags), the scope migration tool lets you **copy** or **move** a global tag into a project scope (`Project#tag`) and back to global.",
498
+ "**Inline tag/project rename**: in the right **Tags / Projects / Templates** column, click the pencil, edit the name in-place, then confirm with **Enter** (**Escape** cancels). A warning explains the reporting impact; you can tick “don’t show again” for future renames. (**`knownPersonalProjects`** for **`!`** tokens does not yet get the same dedicated inline screen as **`@`** projects.)",
499
+ "**Time correction**: **on/off** toggles in [Tasks & tags](/settings#settings-task-tags) for **task** and **session** **start** and **end** times. On a **running task**, an end time **completes the task** at that instant. On a **live session**, an end time **closes the session** at that instant (history snapshot), like ending with **keep** for open tasks.",
426
500
  "**General — local development (data store)** ([Settings → General](/settings#settings-dev-data), only under `next dev`): use the main **Save** button; by default, **dev** uses a **separate** data folder from **production**; you can opt into the same `v4` path, then **restart** the dev server.",
427
- "**Backup** (export): technically `GET /api/backup` with a **format** query; in the app see also [Export defaults](/settings#settings-export). Base URL and deployment = **README** in your **environment**, not this page alone.",
501
+ "**Backup / full restore**: technically `GET /api/backup` exports by **format**, and `POST /api/restore` restores a JSON or SQLite backup file; in the app, use the **Danger zone** controls for guided backup and restore.",
428
502
  ],
429
503
  stepsTitle: "Before clearing all history (short list)",
430
504
  steps: [
package/next.config.ts CHANGED
@@ -10,6 +10,13 @@ const nextConfig: NextConfig = {
10
10
  },
11
11
  serverExternalPackages: ["better-sqlite3"],
12
12
  outputFileTracingRoot: appDir,
13
+ webpack: (config) => {
14
+ config.resolve.alias = {
15
+ ...config.resolve.alias,
16
+ "@": appDir,
17
+ };
18
+ return config;
19
+ },
13
20
  };
14
21
 
15
22
  export default nextConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nightkatana/kronosys-app",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.21",
4
4
  "description": "Kronosys — application Next.js (UI + API + SQLite).",
5
5
  "license": "MIT",
6
6
  "author": "nightkatana",
@@ -11,19 +11,6 @@
11
11
  "bin": {
12
12
  "kronosys": "./bin/kronosys.mjs"
13
13
  },
14
- "files": [
15
- "README.md",
16
- "bin",
17
- "app",
18
- "components",
19
- "lib",
20
- "public",
21
- "server",
22
- "next.config.ts",
23
- "postcss.config.mjs",
24
- "tsconfig.json",
25
- "next-env.d.ts"
26
- ],
27
14
  "engines": {
28
15
  "node": ">=20"
29
16
  },
@@ -37,12 +24,14 @@
37
24
  "build": "next build --webpack",
38
25
  "start": "next start -p 5555",
39
26
  "lint": "eslint",
27
+ "typecheck": "tsc --noEmit",
40
28
  "test": "vitest run",
41
29
  "test:coverage": "vitest run --coverage --reporter=default --reporter=junit --outputFile.junit=reports/vitest-junit.xml",
42
30
  "test:watch": "vitest",
43
31
  "test:e2e": "playwright test",
44
32
  "test:e2e:ui": "playwright test --ui",
45
33
  "test:e2e:install": "playwright install chromium",
34
+ "test:e2e:podman": "bash scripts/e2e-podman.sh",
46
35
  "prepare": "husky",
47
36
  "prepublishOnly": "npm run build",
48
37
  "hooks:install": "husky",
@@ -56,7 +45,6 @@
56
45
  "@dnd-kit/sortable": "^10.0.0",
57
46
  "@dnd-kit/utilities": "^3.2.2",
58
47
  "@tailwindcss/postcss": "^4",
59
- "better-sqlite3": "^12.9.0",
60
48
  "date-fns": "^4.1.0",
61
49
  "fflate": "^0.8.2",
62
50
  "lucide-react": "^1.8.0",
@@ -65,23 +53,23 @@
65
53
  "react": "19.2.4",
66
54
  "react-day-picker": "^9.14.0",
67
55
  "react-dom": "19.2.4",
56
+ "react-markdown": "^10.1.0",
68
57
  "tailwindcss": "^4",
69
- "typescript": "^5.9.3"
58
+ "typescript": "^5.9.3",
59
+ "@types/node": "^22.15.21",
60
+ "@types/react": "^19",
61
+ "@types/react-dom": "^19"
70
62
  },
71
63
  "devDependencies": {
72
64
  "@changesets/cli": "^2.31.0",
73
65
  "@playwright/test": "^1.59.1",
74
66
  "@testing-library/react": "^16.3.0",
75
67
  "@testing-library/user-event": "^14.6.1",
76
- "@types/better-sqlite3": "^7.6.13",
77
- "@types/node": "^22.15.21",
78
- "@types/react": "^19",
79
- "@types/react-dom": "^19",
80
- "@vitest/coverage-v8": "^3.2.4",
68
+ "@vitest/coverage-v8": "^4.1.5",
81
69
  "eslint": "^9",
82
70
  "eslint-config-next": "16.2.3",
83
71
  "husky": "^9.1.7",
84
- "jsdom": "^26.1.0",
85
- "vitest": "^3.2.4"
72
+ "jsdom": "^29.1.1",
73
+ "vitest": "^4.1.5"
86
74
  }
87
- }
75
+ }