@nightkatana/kronosys-app 1.0.0-beta.0

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 (179) hide show
  1. package/README.md +81 -0
  2. package/app/api/action/route.ts +16 -0
  3. package/app/api/backup/route.ts +84 -0
  4. package/app/api/health/route.ts +22 -0
  5. package/app/api/state/route.ts +27 -0
  6. package/app/apple-icon.png +0 -0
  7. package/app/changelog/page.tsx +122 -0
  8. package/app/globals.css +210 -0
  9. package/app/guide/layout.tsx +11 -0
  10. package/app/guide/page.tsx +278 -0
  11. package/app/icon.png +0 -0
  12. package/app/layout.tsx +77 -0
  13. package/app/licenses/layout.tsx +11 -0
  14. package/app/licenses/page.tsx +246 -0
  15. package/app/manifest.ts +32 -0
  16. package/app/page.tsx +1610 -0
  17. package/app/reporting/page.tsx +2943 -0
  18. package/app/settings/layout.tsx +10 -0
  19. package/app/settings/page.tsx +3518 -0
  20. package/bin/kronosys.mjs +46 -0
  21. package/components/KronosysPackageVersionProvider.tsx +19 -0
  22. package/components/KronosysPayloadProvider.tsx +109 -0
  23. package/components/PwaRegister.tsx +25 -0
  24. package/components/SiteLegalFooter.tsx +21 -0
  25. package/components/ThemeProvider.tsx +78 -0
  26. package/components/dashboard/AppShellLiveSessionDrawer.tsx +394 -0
  27. package/components/dashboard/AppShellRouteNav.tsx +131 -0
  28. package/components/dashboard/AppVersionStamp.tsx +16 -0
  29. package/components/dashboard/DashboardCollapsibleSection.tsx +57 -0
  30. package/components/dashboard/DashboardColumnHintsBanner.tsx +159 -0
  31. package/components/dashboard/DashboardCommandCenter.tsx +470 -0
  32. package/components/dashboard/DashboardLangGateModal.tsx +118 -0
  33. package/components/dashboard/DashboardLoadingOverlay.tsx +42 -0
  34. package/components/dashboard/DashboardSimpleModal.tsx +337 -0
  35. package/components/dashboard/DashboardSuspenseFallback.tsx +52 -0
  36. package/components/dashboard/DashboardToastProvider.tsx +64 -0
  37. package/components/dashboard/DashboardTour.tsx +435 -0
  38. package/components/dashboard/DeferredDescriptionPopoverWrap.tsx +39 -0
  39. package/components/dashboard/DeleteSessionModal.tsx +130 -0
  40. package/components/dashboard/DescriptionTooltipPortaled.tsx +31 -0
  41. package/components/dashboard/GitIdentityQuickSetupModal.tsx +211 -0
  42. package/components/dashboard/HeaderIntegrationBadges.tsx +69 -0
  43. package/components/dashboard/InlineMetricHelpTrigger.tsx +102 -0
  44. package/components/dashboard/IssuePickerModal.tsx +168 -0
  45. package/components/dashboard/KronoFocusPanel.tsx +834 -0
  46. package/components/dashboard/KronosysDatetimePopoverField.tsx +357 -0
  47. package/components/dashboard/KronosysTimePopoverField.tsx +233 -0
  48. package/components/dashboard/LanguageMenu.tsx +123 -0
  49. package/components/dashboard/MongoMirrorSyncLine.tsx +57 -0
  50. package/components/dashboard/NewSessionScopeModal.tsx +410 -0
  51. package/components/dashboard/PageRefreshButton.tsx +130 -0
  52. package/components/dashboard/PlainHelpPopover.tsx +97 -0
  53. package/components/dashboard/ReportingPageToc.tsx +68 -0
  54. package/components/dashboard/ReportingTour.tsx +342 -0
  55. package/components/dashboard/SavedProjectPicker.tsx +92 -0
  56. package/components/dashboard/SavedTagPicker.tsx +115 -0
  57. package/components/dashboard/ScrollToTopFab.tsx +41 -0
  58. package/components/dashboard/SelectedSessionSidebarBlock.tsx +630 -0
  59. package/components/dashboard/SessionEndReasonEditor.tsx +114 -0
  60. package/components/dashboard/SessionListPanel.tsx +320 -0
  61. package/components/dashboard/SessionLocMetricsSection.tsx +128 -0
  62. package/components/dashboard/SettingsTagsProjectsSection.tsx +993 -0
  63. package/components/dashboard/SettingsTour.tsx +332 -0
  64. package/components/dashboard/TagPills.tsx +149 -0
  65. package/components/dashboard/TagsHelpTrigger.tsx +84 -0
  66. package/components/dashboard/TaskFocusPanel.tsx +1261 -0
  67. package/components/dashboard/TaskSessionLiveCard.tsx +832 -0
  68. package/components/dashboard/TaskSubtasksBlock.tsx +748 -0
  69. package/components/dashboard/ThemeToggle.test.tsx +26 -0
  70. package/components/dashboard/ThemeToggle.tsx +36 -0
  71. package/components/dashboard/UserGuideBodyText.tsx +62 -0
  72. package/components/dashboard/WorkspaceGitRepoCard.tsx +191 -0
  73. package/components/dashboard/taskFieldStyles.ts +139 -0
  74. package/components/dashboard/useAnchoredFloatingPortalStyle.ts +71 -0
  75. package/components/dashboard/useDescriptionPopoverAfterMs.ts +220 -0
  76. package/components/dashboard/useKronoFocusLiveSeconds.ts +36 -0
  77. package/components/dashboard/useSmoothStopwatchMs.ts +25 -0
  78. package/lib/appShellHeaderClasses.ts +12 -0
  79. package/lib/backupCsvExport.test.ts +149 -0
  80. package/lib/backupCsvExport.ts +392 -0
  81. package/lib/changelogCopy.ts +34 -0
  82. package/lib/concurrentTaskStartPreference.ts +29 -0
  83. package/lib/dashboardClockFormat.ts +13 -0
  84. package/lib/dashboardColumnChrome.ts +3 -0
  85. package/lib/dashboardColumnHintsStorage.ts +57 -0
  86. package/lib/dashboardCopy.ts +1831 -0
  87. package/lib/dashboardDetachedUrlHintStorage.ts +24 -0
  88. package/lib/dashboardGitIdentityBannerStorage.ts +36 -0
  89. package/lib/dashboardLangStorage.ts +72 -0
  90. package/lib/dashboardQuickSearch.ts +476 -0
  91. package/lib/dashboardQuickSearchQuery.test.ts +63 -0
  92. package/lib/dashboardQuickSearchQuery.ts +179 -0
  93. package/lib/dashboardSessionNav.ts +33 -0
  94. package/lib/dashboardShortcuts.ts +268 -0
  95. package/lib/dashboardTimeZone.ts +91 -0
  96. package/lib/dashboardTourStorage.ts +68 -0
  97. package/lib/dataDir.test.ts +87 -0
  98. package/lib/dataDir.ts +83 -0
  99. package/lib/devDataPreferenceFile.ts +55 -0
  100. package/lib/devDataRuntimeInfo.ts +34 -0
  101. package/lib/formatIsoShort.test.ts +46 -0
  102. package/lib/formatIsoShort.ts +29 -0
  103. package/lib/generatedUserChangelog.ts +34 -0
  104. package/lib/gitlabIssueSearch.ts +8 -0
  105. package/lib/kronoFocusDurationHistory.ts +71 -0
  106. package/lib/kronoFocusRhythm.test.ts +130 -0
  107. package/lib/kronoFocusRhythm.ts +46 -0
  108. package/lib/kronoFocusTimerUrgency.test.ts +74 -0
  109. package/lib/kronoFocusTimerUrgency.ts +24 -0
  110. package/lib/kronosysApi.ts +143 -0
  111. package/lib/legacyEditorPayloadKeys.ts +52 -0
  112. package/lib/legacyKronoFocusStorageKeys.test.ts +29 -0
  113. package/lib/legacyKronoFocusStorageKeys.ts +32 -0
  114. package/lib/licensesCopy.ts +128 -0
  115. package/lib/openPlainTextInNewTab.ts +49 -0
  116. package/lib/readKronosysPackageVersion.ts +10 -0
  117. package/lib/reportingAggregate.test.ts +325 -0
  118. package/lib/reportingAggregate.ts +819 -0
  119. package/lib/reportingDatePresets.ts +41 -0
  120. package/lib/reportingMetricHelp.ts +430 -0
  121. package/lib/reportingNonFinalIndicators.test.ts +157 -0
  122. package/lib/reportingNonFinalIndicators.ts +102 -0
  123. package/lib/reportingStrings.ts +491 -0
  124. package/lib/reportingTagWeekBreakdown.test.ts +141 -0
  125. package/lib/reportingTagWeekBreakdown.ts +181 -0
  126. package/lib/reportingWeekLayout.test.ts +239 -0
  127. package/lib/reportingWeekLayout.ts +313 -0
  128. package/lib/sessionAssiduity.test.ts +25 -0
  129. package/lib/sessionAssiduity.ts +33 -0
  130. package/lib/sessionEndReason.ts +55 -0
  131. package/lib/sessionEndWarnings.test.ts +200 -0
  132. package/lib/sessionEndWarnings.ts +125 -0
  133. package/lib/sessionListMerge.test.ts +101 -0
  134. package/lib/sessionListMerge.ts +70 -0
  135. package/lib/sessionTaskSidebarStats.test.ts +24 -0
  136. package/lib/sessionTaskSidebarStats.ts +54 -0
  137. package/lib/settingsCopy.ts +1276 -0
  138. package/lib/taskParsing.test.ts +153 -0
  139. package/lib/taskParsing.ts +737 -0
  140. package/lib/theme.ts +15 -0
  141. package/lib/translucentButtonClasses.ts +34 -0
  142. package/lib/usageProfile.test.ts +84 -0
  143. package/lib/usageProfile.ts +52 -0
  144. package/lib/userGuideCopy.ts +464 -0
  145. package/lib/workspaceLocDefaults.ts +21 -0
  146. package/next-env.d.ts +6 -0
  147. package/next.config.ts +15 -0
  148. package/package.json +87 -0
  149. package/postcss.config.mjs +12 -0
  150. package/public/apple-icon.png +0 -0
  151. package/public/favicon.ico +0 -0
  152. package/public/file.svg +1 -0
  153. package/public/globe.svg +1 -0
  154. package/public/icon-192.png +0 -0
  155. package/public/icon-512.png +0 -0
  156. package/public/icon.png +0 -0
  157. package/public/next.svg +1 -0
  158. package/public/sw.js +13 -0
  159. package/public/traceback.png +0 -0
  160. package/public/vercel.svg +1 -0
  161. package/public/window.svg +1 -0
  162. package/server/actionDispatch.test.ts +723 -0
  163. package/server/actionDispatch.ts +1476 -0
  164. package/server/actionTaskSession.test.ts +713 -0
  165. package/server/actionTaskSession.ts +717 -0
  166. package/server/db.ts +42 -0
  167. package/server/defaultCfg.ts +87 -0
  168. package/server/gitlabTokenStore.ts +34 -0
  169. package/server/kronoFocusHydrate.test.ts +142 -0
  170. package/server/kronoFocusHydrate.ts +69 -0
  171. package/server/kronoFocusMigrate.test.ts +53 -0
  172. package/server/kronoFocusMigrate.ts +78 -0
  173. package/server/mainTimerHydrate.test.ts +65 -0
  174. package/server/mainTimerHydrate.ts +53 -0
  175. package/server/payloadStore.test.ts +78 -0
  176. package/server/payloadStore.ts +83 -0
  177. package/server/sessionWallHydrate.test.ts +46 -0
  178. package/server/sessionWallHydrate.ts +88 -0
  179. package/tsconfig.json +41 -0
@@ -0,0 +1,153 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ buildStartTaskFromDraft,
5
+ buildStartTaskFromInput,
6
+ DEFAULT_FALLBACK_TASK_TAG,
7
+ displayRawTaskTitle,
8
+ filterTaskTagsForProject,
9
+ formatDuration,
10
+ formatTagDisplay,
11
+ formatTagDisplayForTask,
12
+ formatWallDurationMs,
13
+ formatStopwatchMs,
14
+ mergeQuickAddFromOptionValues,
15
+ normalizeProjectKey,
16
+ normalizeTagKey,
17
+ normalizeTaskTagsForStorage,
18
+ parseProjectScopedTag,
19
+ parseQuickAddTagOrProjectLine,
20
+ parseTaskWithAutoTags,
21
+ readTaskDefaultTagBucketEnabled,
22
+ rebuildTaskRawString,
23
+ removeSavedTagFromDraft,
24
+ resolveProjectForTaskUpdate,
25
+ resolveProjectFromFullTaskLine,
26
+ splitTaskTitleSegments,
27
+ stripProjectsAndTakeFirst,
28
+ stripScopedProjectAtTokens,
29
+ } from "./taskParsing";
30
+
31
+ describe("taskParsing core", () => {
32
+ it("normalizeProjectKey retire les @", () => {
33
+ expect(normalizeProjectKey("@@acme")).toBe("acme");
34
+ expect(normalizeProjectKey("@")).toBe("");
35
+ });
36
+
37
+ it("normalizeTagKey retire les #", () => {
38
+ expect(normalizeTagKey("#bug")).toBe("bug");
39
+ });
40
+
41
+ it("parseProjectScopedTag identifie proj#tag", () => {
42
+ expect(parseProjectScopedTag("acme#dev")).toEqual({ projectKey: "acme", localTag: "dev" });
43
+ expect(parseProjectScopedTag("global")).toBeNull();
44
+ expect(parseProjectScopedTag("#tag")).toBeNull();
45
+ expect(parseProjectScopedTag("acme#")).toBeNull();
46
+ });
47
+ });
48
+
49
+ describe("title parsing & projects", () => {
50
+ it("stripScopedProjectAtTokens extrait @p#t", () => {
51
+ const r = stripScopedProjectAtTokens("Hello @p#t world");
52
+ expect(r.core).toBe("Hello world");
53
+ expect(r.scopedTags).toEqual(["p#t"]);
54
+ expect(r.scopedProjectHint).toBe("p");
55
+ });
56
+
57
+ it("stripProjectsAndTakeFirst gère @p seul et @p#t", () => {
58
+ const r = stripProjectsAndTakeFirst("Task @acme and @ignored#tag");
59
+ expect(r.project).toBe("acme");
60
+ expect(r.scopedTags).toEqual(["ignored#tag"]);
61
+ expect(r.core).toBe("Task and");
62
+ });
63
+
64
+ it("resolveProjectForTaskUpdate", () => {
65
+ expect(resolveProjectForTaskUpdate("No project here")).toBeUndefined();
66
+ expect(resolveProjectForTaskUpdate("Project @demo")).toBe("demo");
67
+ expect(resolveProjectForTaskUpdate("Project @")).toBeNull();
68
+ });
69
+
70
+ it("resolveProjectFromFullTaskLine", () => {
71
+ expect(resolveProjectFromFullTaskLine("Hello @world")).toBe("world");
72
+ expect(resolveProjectFromFullTaskLine("Hello")).toBeNull();
73
+ });
74
+ });
75
+
76
+ describe("tag handling", () => {
77
+ it("normalizeTaskTagsForStorage déduplique et gère default", () => {
78
+ expect(normalizeTaskTagsForStorage(["A", "a", ""])).toEqual(["A"]);
79
+ expect(normalizeTaskTagsForStorage([])).toEqual([DEFAULT_FALLBACK_TASK_TAG]);
80
+ expect(normalizeTaskTagsForStorage([], { assignDefaultTagBucket: false })).toEqual([]);
81
+ });
82
+
83
+ it("filterTaskTagsForProject nettoie les tags incompatibles", () => {
84
+ const tags = ["global", "acme#dev", "beta#design"];
85
+ expect(filterTaskTagsForProject(tags, "acme")).toEqual(["global", "acme#dev"]);
86
+ expect(filterTaskTagsForProject(tags, null)).toEqual(["global"]);
87
+ });
88
+
89
+ it("splitTaskTitleSegments découpe texte et tags", () => {
90
+ const segs = splitTaskTitleSegments("Fix #bug now #urgent");
91
+ expect(segs).toHaveLength(4);
92
+ expect(segs[1]).toEqual({ kind: "tag", value: "#bug" });
93
+ });
94
+
95
+ it("parseTaskWithAutoTags moteur complet", () => {
96
+ const r = parseTaskWithAutoTags("Fix #bug @acme");
97
+ expect(r.name).toBe("Fix");
98
+ expect(r.tags).toEqual(["bug"]);
99
+ expect(r.project).toBe("acme");
100
+ });
101
+ });
102
+
103
+ describe("rebuild & display", () => {
104
+ it("rebuildTaskRawString", () => {
105
+ expect(rebuildTaskRawString("Name", ["tag"], "proj")).toBe("Name#tag@proj");
106
+ expect(rebuildTaskRawString("Name", ["p#t"], "p")).toBe("Name@p#t");
107
+ });
108
+
109
+ it("displayRawTaskTitle", () => {
110
+ expect(displayRawTaskTitle("Name #t", ["t"], "p")).toBe("Name #t@p");
111
+ expect(displayRawTaskTitle("Name", ["t"], "p")).toBe("Name #t@p");
112
+ });
113
+
114
+ it("formatTagDisplay", () => {
115
+ expect(formatTagDisplay("dev")).toBe("#dev");
116
+ expect(formatTagDisplay("acme#dev")).toBe("@acme#dev");
117
+ });
118
+ });
119
+
120
+ describe("quick add & draft builders", () => {
121
+ it("parseQuickAddTagOrProjectLine", () => {
122
+ expect(parseQuickAddTagOrProjectLine("just text")).toEqual({ tags: ["justtext"], project: undefined });
123
+ expect(parseQuickAddTagOrProjectLine("#tag")).toEqual({ tags: ["tag"], project: undefined });
124
+ expect(parseQuickAddTagOrProjectLine("@proj")).toEqual({ tags: [], project: "proj" });
125
+ });
126
+
127
+ it("buildStartTaskFromInput", () => {
128
+ expect(buildStartTaskFromInput("#tag @proj")).toEqual({ name: "tag", tags: ["tag"], project: "proj" });
129
+ expect(buildStartTaskFromInput("Task #tag")).toEqual({ name: "Task", tags: ["tag"], project: undefined });
130
+ });
131
+
132
+ it("buildStartTaskFromDraft", () => {
133
+ const r = buildStartTaskFromDraft("Title", ["tag"], "proj");
134
+ expect(r.name).toBe("Title");
135
+ expect(r.tags).toEqual(["tag"]);
136
+ expect(r.project).toBe("proj");
137
+ });
138
+ });
139
+
140
+ describe("durations", () => {
141
+ it("formatDuration", () => {
142
+ expect(formatDuration(1.5)).toBe("1 min 30 s");
143
+ expect(formatDuration(120)).toBe("2h");
144
+ });
145
+
146
+ it("formatWallDurationMs", () => {
147
+ expect(formatWallDurationMs(61000)).toBe("1 min 1 s");
148
+ });
149
+
150
+ it("formatStopwatchMs", () => {
151
+ expect(formatStopwatchMs(61000)).toBe("1:01.00");
152
+ });
153
+ });