epoch-tui 0.1.0 → 0.1.1

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 (147) hide show
  1. package/dist/index.js +3804 -4
  2. package/package.json +4 -3
  3. package/dist/App.d.ts +0 -3
  4. package/dist/App.js +0 -38
  5. package/dist/components/calendar/CalendarPane.d.ts +0 -2
  6. package/dist/components/calendar/CalendarPane.js +0 -91
  7. package/dist/components/calendar/DayCell.d.ts +0 -7
  8. package/dist/components/calendar/DayCell.js +0 -26
  9. package/dist/components/calendar/MonthView.d.ts +0 -7
  10. package/dist/components/calendar/MonthView.js +0 -10
  11. package/dist/components/common/BorderedBox.d.ts +0 -18
  12. package/dist/components/common/BorderedBox.js +0 -29
  13. package/dist/components/common/ClearTimelineDialog.d.ts +0 -2
  14. package/dist/components/common/ClearTimelineDialog.js +0 -33
  15. package/dist/components/common/FullscreenBackground.d.ts +0 -11
  16. package/dist/components/common/FullscreenBackground.js +0 -12
  17. package/dist/components/common/HelpDialog.d.ts +0 -2
  18. package/dist/components/common/HelpDialog.js +0 -40
  19. package/dist/components/common/Modal.d.ts +0 -10
  20. package/dist/components/common/Modal.js +0 -15
  21. package/dist/components/common/Separator.d.ts +0 -8
  22. package/dist/components/common/Separator.js +0 -10
  23. package/dist/components/common/ThemeDialog.d.ts +0 -2
  24. package/dist/components/common/ThemeDialog.js +0 -117
  25. package/dist/components/common/ThemedScreen.d.ts +0 -22
  26. package/dist/components/common/ThemedScreen.js +0 -36
  27. package/dist/components/common/ThemedText.d.ts +0 -11
  28. package/dist/components/common/ThemedText.js +0 -20
  29. package/dist/components/layout/Pane.d.ts +0 -12
  30. package/dist/components/layout/Pane.js +0 -10
  31. package/dist/components/layout/ThreeColumnLayout.d.ts +0 -13
  32. package/dist/components/layout/ThreeColumnLayout.js +0 -22
  33. package/dist/components/overview/OverviewScreen.d.ts +0 -2
  34. package/dist/components/overview/OverviewScreen.js +0 -138
  35. package/dist/components/tasks/TaskHeader.d.ts +0 -7
  36. package/dist/components/tasks/TaskHeader.js +0 -8
  37. package/dist/components/tasks/TaskItem.d.ts +0 -10
  38. package/dist/components/tasks/TaskItem.js +0 -25
  39. package/dist/components/tasks/TaskList.d.ts +0 -11
  40. package/dist/components/tasks/TaskList.js +0 -11
  41. package/dist/components/tasks/TasksPane.d.ts +0 -2
  42. package/dist/components/tasks/TasksPane.js +0 -410
  43. package/dist/components/timeline/TimelineEntry.d.ts +0 -9
  44. package/dist/components/timeline/TimelineEntry.js +0 -26
  45. package/dist/components/timeline/TimelinePane.d.ts +0 -2
  46. package/dist/components/timeline/TimelinePane.js +0 -78
  47. package/dist/contexts/AppContext.d.ts +0 -47
  48. package/dist/contexts/AppContext.js +0 -104
  49. package/dist/contexts/StorageContext.d.ts +0 -15
  50. package/dist/contexts/StorageContext.js +0 -83
  51. package/dist/contexts/ThemeContext.d.ts +0 -15
  52. package/dist/contexts/ThemeContext.js +0 -44
  53. package/dist/hooks/useKeyboardNav.d.ts +0 -1
  54. package/dist/hooks/useKeyboardNav.js +0 -89
  55. package/dist/hooks/useTerminalSize.d.ts +0 -9
  56. package/dist/hooks/useTerminalSize.js +0 -34
  57. package/dist/index.d.ts +0 -2
  58. package/dist/services/calendarService.d.ts +0 -18
  59. package/dist/services/calendarService.js +0 -57
  60. package/dist/services/storage.d.ts +0 -14
  61. package/dist/services/storage.js +0 -130
  62. package/dist/services/taskService.d.ts +0 -17
  63. package/dist/services/taskService.js +0 -106
  64. package/dist/services/timelineService.d.ts +0 -25
  65. package/dist/services/timelineService.js +0 -78
  66. package/dist/themes/amazon.d.ts +0 -2
  67. package/dist/themes/amazon.js +0 -37
  68. package/dist/themes/amazonLight.d.ts +0 -2
  69. package/dist/themes/amazonLight.js +0 -38
  70. package/dist/themes/apple.d.ts +0 -2
  71. package/dist/themes/apple.js +0 -38
  72. package/dist/themes/appleLight.d.ts +0 -2
  73. package/dist/themes/appleLight.js +0 -38
  74. package/dist/themes/atomOneDark.d.ts +0 -2
  75. package/dist/themes/atomOneDark.js +0 -37
  76. package/dist/themes/atomOneLight.d.ts +0 -2
  77. package/dist/themes/atomOneLight.js +0 -38
  78. package/dist/themes/batman.d.ts +0 -2
  79. package/dist/themes/batman.js +0 -37
  80. package/dist/themes/catppuccin.d.ts +0 -2
  81. package/dist/themes/catppuccin.js +0 -37
  82. package/dist/themes/catppuccinLatte.d.ts +0 -2
  83. package/dist/themes/catppuccinLatte.js +0 -38
  84. package/dist/themes/claude.d.ts +0 -2
  85. package/dist/themes/claude.js +0 -48
  86. package/dist/themes/claudeCode.d.ts +0 -2
  87. package/dist/themes/claudeCode.js +0 -47
  88. package/dist/themes/cursor.d.ts +0 -2
  89. package/dist/themes/cursor.js +0 -38
  90. package/dist/themes/cursorLight.d.ts +0 -2
  91. package/dist/themes/cursorLight.js +0 -38
  92. package/dist/themes/dark.d.ts +0 -2
  93. package/dist/themes/dark.js +0 -38
  94. package/dist/themes/githubDark.d.ts +0 -2
  95. package/dist/themes/githubDark.js +0 -37
  96. package/dist/themes/githubLight.d.ts +0 -2
  97. package/dist/themes/githubLight.js +0 -38
  98. package/dist/themes/index.d.ts +0 -9
  99. package/dist/themes/index.js +0 -83
  100. package/dist/themes/instagram.d.ts +0 -2
  101. package/dist/themes/instagram.js +0 -37
  102. package/dist/themes/instagramLight.d.ts +0 -2
  103. package/dist/themes/instagramLight.js +0 -38
  104. package/dist/themes/intellij.d.ts +0 -2
  105. package/dist/themes/intellij.js +0 -37
  106. package/dist/themes/intellijLight.d.ts +0 -2
  107. package/dist/themes/intellijLight.js +0 -38
  108. package/dist/themes/light.d.ts +0 -2
  109. package/dist/themes/light.js +0 -38
  110. package/dist/themes/nord.d.ts +0 -2
  111. package/dist/themes/nord.js +0 -37
  112. package/dist/themes/nordLight.d.ts +0 -2
  113. package/dist/themes/nordLight.js +0 -38
  114. package/dist/themes/postman.d.ts +0 -2
  115. package/dist/themes/postman.js +0 -37
  116. package/dist/themes/postmanLight.d.ts +0 -2
  117. package/dist/themes/postmanLight.js +0 -38
  118. package/dist/themes/spiderman.d.ts +0 -2
  119. package/dist/themes/spiderman.js +0 -37
  120. package/dist/themes/terminal.d.ts +0 -2
  121. package/dist/themes/terminal.js +0 -37
  122. package/dist/themes/ubuntu.d.ts +0 -2
  123. package/dist/themes/ubuntu.js +0 -37
  124. package/dist/themes/ubuntuLight.d.ts +0 -2
  125. package/dist/themes/ubuntuLight.js +0 -38
  126. package/dist/themes/x.d.ts +0 -2
  127. package/dist/themes/x.js +0 -38
  128. package/dist/themes/xLight.d.ts +0 -2
  129. package/dist/themes/xLight.js +0 -38
  130. package/dist/types/calendar.d.ts +0 -19
  131. package/dist/types/calendar.js +0 -1
  132. package/dist/types/storage.d.ts +0 -21
  133. package/dist/types/storage.js +0 -1
  134. package/dist/types/task.d.ts +0 -21
  135. package/dist/types/task.js +0 -1
  136. package/dist/types/theme.d.ts +0 -38
  137. package/dist/types/theme.js +0 -1
  138. package/dist/types/timeline.d.ts +0 -23
  139. package/dist/types/timeline.js +0 -9
  140. package/dist/utils/date.d.ts +0 -7
  141. package/dist/utils/date.js +0 -37
  142. package/dist/utils/logger.d.ts +0 -3
  143. package/dist/utils/logger.js +0 -39
  144. package/dist/utils/tree.d.ts +0 -11
  145. package/dist/utils/tree.js +0 -64
  146. package/dist/utils/validation.d.ts +0 -7
  147. package/dist/utils/validation.js +0 -35
package/dist/index.js CHANGED
@@ -1,8 +1,3808 @@
1
1
  #!/usr/bin/env node
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+
3
+ // src/index.tsx
3
4
  import { render } from "ink";
4
- import App from "./App";
5
+
6
+ // src/App.tsx
7
+ import { Box as Box16, Text as Text12 } from "ink";
8
+
9
+ // src/contexts/ThemeContext.tsx
10
+ import { createContext as createContext2, useContext as useContext2, useState as useState2, useEffect as useEffect2 } from "react";
11
+
12
+ // src/themes/dark.ts
13
+ var darkTheme = {
14
+ name: "dark",
15
+ colors: {
16
+ background: "#1a1a1a",
17
+ foreground: "#e5e5e5",
18
+ border: "#404040",
19
+ calendarBorder: "#404040",
20
+ calendarHeader: "#f59e0b",
21
+ // Amber
22
+ calendarToday: "#f59e0b",
23
+ // Amber
24
+ calendarSelected: "#fbbf24",
25
+ // Amber light
26
+ calendarDayWithTasks: "#d97706",
27
+ // Amber dark
28
+ calendarDayOtherMonth: "#525252",
29
+ taskBorder: "#404040",
30
+ taskHeader: "#f59e0b",
31
+ // Amber
32
+ taskCheckboxEmpty: "#525252",
33
+ taskCheckboxFilled: "#f59e0b",
34
+ // Amber
35
+ taskStateTodo: "#e5e5e5",
36
+ taskStateCompleted: "#737373",
37
+ taskStateDelegated: "#a3a3a3",
38
+ taskStateDelayed: "#fbbf24",
39
+ // Amber light for attention
40
+ taskIndent: "#525252",
41
+ timelineBorder: "#404040",
42
+ timelineHeader: "#f59e0b",
43
+ // Amber
44
+ timelineTimestamp: "#737373",
45
+ timelineEventCreated: "#e5e5e5",
46
+ timelineEventStarted: "#fbbf24",
47
+ // Amber light
48
+ timelineEventCompleted: "#a3a3a3",
49
+ timelineEventDelegated: "#8a8a8a",
50
+ timelineEventDelayed: "#f59e0b",
51
+ // Amber
52
+ separator: "#404040",
53
+ keyboardHint: "#737373",
54
+ helpDialogBorder: "#f59e0b",
55
+ // Amber
56
+ focusIndicator: "#f59e0b",
57
+ // Amber
58
+ modalOverlay: "#0a0a0a",
59
+ modalBackground: "#1a1a1a"
60
+ }
61
+ };
62
+
63
+ // src/themes/light.ts
64
+ var lightTheme = {
65
+ name: "light",
66
+ colors: {
67
+ // Hex colors work with Ink's Text backgroundColor (via chalk)
68
+ background: "#f5f5f5",
69
+ foreground: "#1a1a1a",
70
+ border: "#888888",
71
+ calendarBorder: "#888888",
72
+ calendarHeader: "#0066cc",
73
+ calendarToday: "#00aa77",
74
+ calendarSelected: "#9933cc",
75
+ calendarDayWithTasks: "#cc6600",
76
+ calendarDayOtherMonth: "#666666",
77
+ // Darker
78
+ taskBorder: "#888888",
79
+ taskHeader: "#0066cc",
80
+ taskCheckboxEmpty: "#666666",
81
+ // Darker
82
+ taskCheckboxFilled: "#00aa77",
83
+ taskStateTodo: "#1a1a1a",
84
+ taskStateCompleted: "#00aa77",
85
+ taskStateDelegated: "#cc6600",
86
+ taskStateDelayed: "#cc3333",
87
+ taskIndent: "#888888",
88
+ timelineBorder: "#888888",
89
+ timelineHeader: "#0066cc",
90
+ timelineTimestamp: "#444444",
91
+ // Darker
92
+ timelineEventCreated: "#0066cc",
93
+ timelineEventStarted: "#cc6600",
94
+ timelineEventCompleted: "#00aa77",
95
+ timelineEventDelegated: "#9933cc",
96
+ timelineEventDelayed: "#cc3333",
97
+ separator: "#888888",
98
+ keyboardHint: "#444444",
99
+ // Darker
100
+ helpDialogBorder: "#0066cc",
101
+ focusIndicator: "#9933cc",
102
+ modalOverlay: "#e0e0e0",
103
+ modalBackground: "#f5f5f5"
104
+ }
105
+ };
106
+
107
+ // src/themes/terminal.ts
108
+ var terminalTheme = {
109
+ name: "terminal",
110
+ colors: {
111
+ // defaults rely on terminal settings
112
+ border: "gray",
113
+ calendarBorder: "gray",
114
+ calendarHeader: "blue",
115
+ calendarToday: "green",
116
+ calendarSelected: "magenta",
117
+ calendarDayWithTasks: "yellow",
118
+ calendarDayOtherMonth: "gray",
119
+ taskBorder: "gray",
120
+ taskHeader: "blue",
121
+ taskCheckboxEmpty: "gray",
122
+ taskCheckboxFilled: "green",
123
+ taskStateTodo: void 0,
124
+ // default
125
+ taskStateCompleted: "green",
126
+ taskStateDelegated: "magenta",
127
+ taskStateDelayed: "red",
128
+ taskIndent: "gray",
129
+ timelineBorder: "gray",
130
+ timelineHeader: "blue",
131
+ timelineTimestamp: "gray",
132
+ timelineEventCreated: "cyan",
133
+ timelineEventStarted: "yellow",
134
+ timelineEventCompleted: "green",
135
+ timelineEventDelegated: "magenta",
136
+ timelineEventDelayed: "red",
137
+ separator: "gray",
138
+ keyboardHint: "gray",
139
+ helpDialogBorder: "blue",
140
+ focusIndicator: "cyan",
141
+ // Modal colors follow terminal defaults
142
+ modalOverlay: void 0,
143
+ modalBackground: void 0
144
+ }
145
+ };
146
+
147
+ // src/themes/claude.ts
148
+ var claudeTheme = {
149
+ name: "claude",
150
+ colors: {
151
+ // Warm cream background with white text
152
+ background: "#F4F3EE",
153
+ foreground: "#1a1614",
154
+ border: "#B1ADA1",
155
+ // Calendar - Rust accents
156
+ calendarBorder: "#B1ADA1",
157
+ calendarHeader: "#C15F3C",
158
+ calendarToday: "#C15F3C",
159
+ calendarSelected: "#C15F3C",
160
+ calendarDayWithTasks: "#C15F3C",
161
+ calendarDayOtherMonth: "#736F66",
162
+ // Darker for readability
163
+ // Tasks - Warm palette
164
+ taskBorder: "#B1ADA1",
165
+ taskHeader: "#C15F3C",
166
+ taskCheckboxEmpty: "#736F66",
167
+ // Darker for readability
168
+ taskCheckboxFilled: "#98C379",
169
+ taskStateTodo: "#1a1614",
170
+ taskStateCompleted: "#98C379",
171
+ taskStateDelegated: "#736F66",
172
+ // Darker for readability
173
+ taskStateDelayed: "#E06C75",
174
+ taskIndent: "#B1ADA1",
175
+ // Timeline - Rust theme
176
+ timelineBorder: "#B1ADA1",
177
+ timelineHeader: "#C15F3C",
178
+ timelineTimestamp: "#736F66",
179
+ // Darker for readability
180
+ timelineEventCreated: "#61AFEF",
181
+ timelineEventStarted: "#C15F3C",
182
+ timelineEventCompleted: "#98C379",
183
+ timelineEventDelegated: "#736F66",
184
+ timelineEventDelayed: "#E06C75",
185
+ // UI elements
186
+ separator: "#B1ADA1",
187
+ keyboardHint: "#736F66",
188
+ // Darker for readability
189
+ helpDialogBorder: "#C15F3C",
190
+ focusIndicator: "#C15F3C",
191
+ // Modal - Light overlay
192
+ modalOverlay: "#F4F3EE",
193
+ modalBackground: "#FFFFFF"
194
+ }
195
+ };
196
+
197
+ // src/themes/githubDark.ts
198
+ var githubDarkTheme = {
199
+ name: "github-dark",
200
+ colors: {
201
+ background: "#0d1117",
202
+ foreground: "#c9d1d9",
203
+ border: "#30363d",
204
+ calendarBorder: "#30363d",
205
+ calendarHeader: "#58a6ff",
206
+ calendarToday: "#1f6feb",
207
+ calendarSelected: "#1f6feb",
208
+ calendarDayWithTasks: "#238636",
209
+ calendarDayOtherMonth: "#484f58",
210
+ taskBorder: "#30363d",
211
+ taskHeader: "#58a6ff",
212
+ taskCheckboxEmpty: "#484f58",
213
+ taskCheckboxFilled: "#3fb950",
214
+ taskStateTodo: "#c9d1d9",
215
+ taskStateCompleted: "#8b949e",
216
+ taskStateDelegated: "#a371f7",
217
+ taskStateDelayed: "#d29922",
218
+ taskIndent: "#484f58",
219
+ timelineBorder: "#30363d",
220
+ timelineHeader: "#58a6ff",
221
+ timelineTimestamp: "#8b949e",
222
+ timelineEventCreated: "#58a6ff",
223
+ timelineEventStarted: "#d29922",
224
+ timelineEventCompleted: "#3fb950",
225
+ timelineEventDelegated: "#a371f7",
226
+ timelineEventDelayed: "#f85149",
227
+ separator: "#30363d",
228
+ keyboardHint: "#8b949e",
229
+ helpDialogBorder: "#58a6ff",
230
+ focusIndicator: "#58a6ff",
231
+ modalOverlay: "#0d1117",
232
+ modalBackground: "#161b22"
233
+ }
234
+ };
235
+
236
+ // src/themes/githubLight.ts
237
+ var githubLightTheme = {
238
+ name: "github-light",
239
+ colors: {
240
+ background: "#ffffff",
241
+ foreground: "#24292f",
242
+ border: "#d0d7de",
243
+ calendarBorder: "#d0d7de",
244
+ calendarHeader: "#0969da",
245
+ // Blue
246
+ calendarToday: "#0969da",
247
+ calendarSelected: "#0969da",
248
+ calendarDayWithTasks: "#1a7f37",
249
+ // Green
250
+ calendarDayOtherMonth: "#8c959f",
251
+ taskBorder: "#d0d7de",
252
+ taskHeader: "#0969da",
253
+ taskCheckboxEmpty: "#8c959f",
254
+ taskCheckboxFilled: "#1a7f37",
255
+ taskStateTodo: "#24292f",
256
+ taskStateCompleted: "#8c959f",
257
+ taskStateDelegated: "#8250df",
258
+ // Purple
259
+ taskStateDelayed: "#bf8700",
260
+ // Yellow/Orange
261
+ taskIndent: "#d0d7de",
262
+ timelineBorder: "#d0d7de",
263
+ timelineHeader: "#0969da",
264
+ timelineTimestamp: "#8c959f",
265
+ timelineEventCreated: "#0969da",
266
+ timelineEventStarted: "#bf8700",
267
+ timelineEventCompleted: "#1a7f37",
268
+ timelineEventDelegated: "#8250df",
269
+ timelineEventDelayed: "#cf222e",
270
+ // Red
271
+ separator: "#d0d7de",
272
+ keyboardHint: "#656d76",
273
+ helpDialogBorder: "#0969da",
274
+ focusIndicator: "#0969da",
275
+ modalOverlay: "#00000033",
276
+ modalBackground: "#f6f8fa"
277
+ }
278
+ };
279
+
280
+ // src/themes/catppuccin.ts
281
+ var catppuccinTheme = {
282
+ name: "catppuccin",
283
+ colors: {
284
+ background: "#1e1e2e",
285
+ foreground: "#cdd6f4",
286
+ border: "#45475a",
287
+ calendarBorder: "#45475a",
288
+ calendarHeader: "#89b4fa",
289
+ // Blue
290
+ calendarToday: "#cba6f7",
291
+ // Mauve
292
+ calendarSelected: "#cba6f7",
293
+ calendarDayWithTasks: "#a6e3a1",
294
+ // Green
295
+ calendarDayOtherMonth: "#585b70",
296
+ // Surface 2
297
+ taskBorder: "#45475a",
298
+ taskHeader: "#89b4fa",
299
+ taskCheckboxEmpty: "#585b70",
300
+ taskCheckboxFilled: "#a6e3a1",
301
+ taskStateTodo: "#cdd6f4",
302
+ taskStateCompleted: "#a6adc8",
303
+ // Subtext 0
304
+ taskStateDelegated: "#f5c2e7",
305
+ // Pink
306
+ taskStateDelayed: "#fab387",
307
+ // Peach
308
+ taskIndent: "#585b70",
309
+ timelineBorder: "#45475a",
310
+ timelineHeader: "#89b4fa",
311
+ timelineTimestamp: "#a6adc8",
312
+ timelineEventCreated: "#89b4fa",
313
+ timelineEventStarted: "#fab387",
314
+ timelineEventCompleted: "#a6e3a1",
315
+ timelineEventDelegated: "#f5c2e7",
316
+ timelineEventDelayed: "#f38ba8",
317
+ // Red
318
+ separator: "#45475a",
319
+ keyboardHint: "#a6adc8",
320
+ helpDialogBorder: "#cba6f7",
321
+ focusIndicator: "#cba6f7",
322
+ modalOverlay: "#181825",
323
+ // Mantle
324
+ modalBackground: "#1e1e2e"
325
+ }
326
+ };
327
+
328
+ // src/themes/catppuccinLatte.ts
329
+ var catppuccinLatteTheme = {
330
+ name: "catppuccin-latte",
331
+ colors: {
332
+ background: "#eff1f5",
333
+ // Base
334
+ foreground: "#4c4f69",
335
+ // Text
336
+ border: "#ccd0da",
337
+ // Surface 0
338
+ calendarBorder: "#ccd0da",
339
+ calendarHeader: "#1e66f5",
340
+ // Blue
341
+ calendarToday: "#8839ef",
342
+ // Mauve
343
+ calendarSelected: "#8839ef",
344
+ calendarDayWithTasks: "#40a02b",
345
+ // Green
346
+ calendarDayOtherMonth: "#9ca0b0",
347
+ // Overlay 0
348
+ taskBorder: "#ccd0da",
349
+ taskHeader: "#1e66f5",
350
+ taskCheckboxEmpty: "#9ca0b0",
351
+ taskCheckboxFilled: "#40a02b",
352
+ taskStateTodo: "#4c4f69",
353
+ taskStateCompleted: "#6c6f85",
354
+ // Subtext 0
355
+ taskStateDelegated: "#ea76cb",
356
+ // Pink
357
+ taskStateDelayed: "#fe640b",
358
+ // Peach
359
+ taskIndent: "#bcc0cc",
360
+ // Surface 1
361
+ timelineBorder: "#ccd0da",
362
+ timelineHeader: "#1e66f5",
363
+ timelineTimestamp: "#6c6f85",
364
+ timelineEventCreated: "#1e66f5",
365
+ timelineEventStarted: "#fe640b",
366
+ timelineEventCompleted: "#40a02b",
367
+ timelineEventDelegated: "#ea76cb",
368
+ timelineEventDelayed: "#d20f39",
369
+ // Red
370
+ separator: "#ccd0da",
371
+ keyboardHint: "#6c6f85",
372
+ helpDialogBorder: "#8839ef",
373
+ focusIndicator: "#8839ef",
374
+ modalOverlay: "#e6e9ef",
375
+ // Mantle
376
+ modalBackground: "#eff1f5"
377
+ }
378
+ };
379
+
380
+ // src/themes/ubuntu.ts
381
+ var ubuntuTheme = {
382
+ name: "ubuntu",
383
+ colors: {
384
+ background: "#2c001e",
385
+ // Aubergine
386
+ foreground: "#f6f5f4",
387
+ border: "#5c5c5c",
388
+ // Warm Grey
389
+ calendarBorder: "#5c5c5c",
390
+ calendarHeader: "#E95420",
391
+ // Orange
392
+ calendarToday: "#E95420",
393
+ calendarSelected: "#E95420",
394
+ calendarDayWithTasks: "#77216F",
395
+ // Aubergine light / Purple
396
+ calendarDayOtherMonth: "#AEA79F",
397
+ taskBorder: "#5c5c5c",
398
+ taskHeader: "#E95420",
399
+ taskCheckboxEmpty: "#AEA79F",
400
+ taskCheckboxFilled: "#0E8420",
401
+ // Green
402
+ taskStateTodo: "#f6f5f4",
403
+ taskStateCompleted: "#AEA79F",
404
+ taskStateDelegated: "#77216F",
405
+ taskStateDelayed: "#C7162B",
406
+ // Red
407
+ taskIndent: "#5c5c5c",
408
+ timelineBorder: "#5c5c5c",
409
+ timelineHeader: "#E95420",
410
+ timelineTimestamp: "#AEA79F",
411
+ timelineEventCreated: "#E95420",
412
+ timelineEventStarted: "#F99B11",
413
+ timelineEventCompleted: "#0E8420",
414
+ timelineEventDelegated: "#77216F",
415
+ timelineEventDelayed: "#C7162B",
416
+ separator: "#5c5c5c",
417
+ keyboardHint: "#AEA79F",
418
+ helpDialogBorder: "#E95420",
419
+ focusIndicator: "#E95420",
420
+ modalOverlay: "#1a0012",
421
+ modalBackground: "#300a24"
422
+ }
423
+ };
424
+
425
+ // src/themes/ubuntuLight.ts
426
+ var ubuntuLightTheme = {
427
+ name: "ubuntu-light",
428
+ colors: {
429
+ background: "#fafafa",
430
+ foreground: "#3d3d3d",
431
+ border: "#cdcdcd",
432
+ calendarBorder: "#cdcdcd",
433
+ calendarHeader: "#e95420",
434
+ // Ubuntu Orange
435
+ calendarToday: "#e95420",
436
+ calendarSelected: "#e95420",
437
+ calendarDayWithTasks: "#77216f",
438
+ // Ubuntu Aubergine
439
+ calendarDayOtherMonth: "#929292",
440
+ taskBorder: "#cdcdcd",
441
+ taskHeader: "#e95420",
442
+ taskCheckboxEmpty: "#929292",
443
+ taskCheckboxFilled: "#0e8420",
444
+ // Ubuntu Green
445
+ taskStateTodo: "#3d3d3d",
446
+ taskStateCompleted: "#929292",
447
+ taskStateDelegated: "#77216f",
448
+ taskStateDelayed: "#c7162b",
449
+ // Ubuntu Red
450
+ taskIndent: "#cdcdcd",
451
+ timelineBorder: "#cdcdcd",
452
+ timelineHeader: "#e95420",
453
+ timelineTimestamp: "#929292",
454
+ timelineEventCreated: "#e95420",
455
+ timelineEventStarted: "#f99b11",
456
+ // Light Orange
457
+ timelineEventCompleted: "#0e8420",
458
+ timelineEventDelegated: "#77216f",
459
+ timelineEventDelayed: "#c7162b",
460
+ separator: "#cdcdcd",
461
+ keyboardHint: "#929292",
462
+ helpDialogBorder: "#e95420",
463
+ focusIndicator: "#e95420",
464
+ modalOverlay: "#e8e8e8",
465
+ modalBackground: "#ffffff"
466
+ }
467
+ };
468
+
469
+ // src/themes/atomOneDark.ts
470
+ var atomOneDarkTheme = {
471
+ name: "atom",
472
+ colors: {
473
+ background: "#282c34",
474
+ foreground: "#abb2bf",
475
+ border: "#4b5263",
476
+ calendarBorder: "#4b5263",
477
+ calendarHeader: "#61afef",
478
+ // Blue
479
+ calendarToday: "#c678dd",
480
+ // Purple
481
+ calendarSelected: "#c678dd",
482
+ calendarDayWithTasks: "#98c379",
483
+ // Green
484
+ calendarDayOtherMonth: "#5c6370",
485
+ taskBorder: "#4b5263",
486
+ taskHeader: "#61afef",
487
+ taskCheckboxEmpty: "#5c6370",
488
+ taskCheckboxFilled: "#98c379",
489
+ taskStateTodo: "#abb2bf",
490
+ taskStateCompleted: "#5c6370",
491
+ taskStateDelegated: "#c678dd",
492
+ taskStateDelayed: "#e5c07b",
493
+ // Yellow
494
+ taskIndent: "#5c6370",
495
+ timelineBorder: "#4b5263",
496
+ timelineHeader: "#61afef",
497
+ timelineTimestamp: "#5c6370",
498
+ timelineEventCreated: "#61afef",
499
+ timelineEventStarted: "#e5c07b",
500
+ timelineEventCompleted: "#98c379",
501
+ timelineEventDelegated: "#c678dd",
502
+ timelineEventDelayed: "#e06c75",
503
+ // Red
504
+ separator: "#4b5263",
505
+ keyboardHint: "#5c6370",
506
+ helpDialogBorder: "#61afef",
507
+ focusIndicator: "#56b6c2",
508
+ // Cyan
509
+ modalOverlay: "#21252b",
510
+ modalBackground: "#282c34"
511
+ }
512
+ };
513
+
514
+ // src/themes/atomOneLight.ts
515
+ var atomOneLightTheme = {
516
+ name: "atom-light",
517
+ colors: {
518
+ background: "#fafafa",
519
+ foreground: "#383a42",
520
+ border: "#a0a1a7",
521
+ calendarBorder: "#a0a1a7",
522
+ calendarHeader: "#4078f2",
523
+ // Blue
524
+ calendarToday: "#a626a4",
525
+ // Purple
526
+ calendarSelected: "#a626a4",
527
+ calendarDayWithTasks: "#50a14f",
528
+ // Green
529
+ calendarDayOtherMonth: "#a0a1a7",
530
+ taskBorder: "#a0a1a7",
531
+ taskHeader: "#4078f2",
532
+ taskCheckboxEmpty: "#a0a1a7",
533
+ taskCheckboxFilled: "#50a14f",
534
+ taskStateTodo: "#383a42",
535
+ taskStateCompleted: "#a0a1a7",
536
+ taskStateDelegated: "#a626a4",
537
+ taskStateDelayed: "#c18401",
538
+ // Yellow/Orange
539
+ taskIndent: "#d0d0d0",
540
+ timelineBorder: "#a0a1a7",
541
+ timelineHeader: "#4078f2",
542
+ timelineTimestamp: "#a0a1a7",
543
+ timelineEventCreated: "#4078f2",
544
+ timelineEventStarted: "#c18401",
545
+ timelineEventCompleted: "#50a14f",
546
+ timelineEventDelegated: "#a626a4",
547
+ timelineEventDelayed: "#e45649",
548
+ // Red
549
+ separator: "#a0a1a7",
550
+ keyboardHint: "#a0a1a7",
551
+ helpDialogBorder: "#4078f2",
552
+ focusIndicator: "#0184bc",
553
+ // Cyan
554
+ modalOverlay: "#e8e8e8",
555
+ modalBackground: "#fafafa"
556
+ }
557
+ };
558
+
559
+ // src/themes/intellij.ts
560
+ var intellijTheme = {
561
+ name: "intellij",
562
+ colors: {
563
+ background: "#2b2b2b",
564
+ foreground: "#a9b7c6",
565
+ border: "#323232",
566
+ calendarBorder: "#323232",
567
+ calendarHeader: "#cc7832",
568
+ // Orange (Keyword)
569
+ calendarToday: "#3592c4",
570
+ // Blue (Accent)
571
+ calendarSelected: "#3592c4",
572
+ calendarDayWithTasks: "#6a8759",
573
+ // Green (String)
574
+ calendarDayOtherMonth: "#606366",
575
+ taskBorder: "#323232",
576
+ taskHeader: "#cc7832",
577
+ taskCheckboxEmpty: "#606366",
578
+ taskCheckboxFilled: "#6a8759",
579
+ taskStateTodo: "#a9b7c6",
580
+ taskStateCompleted: "#606366",
581
+ taskStateDelegated: "#9876aa",
582
+ // Purple
583
+ taskStateDelayed: "#ffc66d",
584
+ // Yellow
585
+ taskIndent: "#606366",
586
+ timelineBorder: "#323232",
587
+ timelineHeader: "#cc7832",
588
+ timelineTimestamp: "#808080",
589
+ timelineEventCreated: "#6897bb",
590
+ // Light Blue
591
+ timelineEventStarted: "#cc7832",
592
+ timelineEventCompleted: "#6a8759",
593
+ timelineEventDelegated: "#9876aa",
594
+ timelineEventDelayed: "#cc7832",
595
+ separator: "#323232",
596
+ keyboardHint: "#808080",
597
+ helpDialogBorder: "#3592c4",
598
+ focusIndicator: "#3592c4",
599
+ modalOverlay: "#1e1e1e",
600
+ modalBackground: "#3c3f41"
601
+ }
602
+ };
603
+
604
+ // src/themes/intellijLight.ts
605
+ var intellijLightTheme = {
606
+ name: "intellij-light",
607
+ colors: {
608
+ background: "#f7f7f7",
609
+ foreground: "#000000",
610
+ border: "#c4c4c4",
611
+ calendarBorder: "#c4c4c4",
612
+ calendarHeader: "#0033b3",
613
+ // Keyword Blue
614
+ calendarToday: "#0033b3",
615
+ calendarSelected: "#0033b3",
616
+ calendarDayWithTasks: "#067d17",
617
+ // String Green
618
+ calendarDayOtherMonth: "#8c8c8c",
619
+ taskBorder: "#c4c4c4",
620
+ taskHeader: "#0033b3",
621
+ taskCheckboxEmpty: "#8c8c8c",
622
+ taskCheckboxFilled: "#067d17",
623
+ taskStateTodo: "#000000",
624
+ taskStateCompleted: "#8c8c8c",
625
+ taskStateDelegated: "#871094",
626
+ // Purple
627
+ taskStateDelayed: "#9e880d",
628
+ // Yellow
629
+ taskIndent: "#d4d4d4",
630
+ timelineBorder: "#c4c4c4",
631
+ timelineHeader: "#0033b3",
632
+ timelineTimestamp: "#8c8c8c",
633
+ timelineEventCreated: "#0033b3",
634
+ timelineEventStarted: "#9e880d",
635
+ timelineEventCompleted: "#067d17",
636
+ timelineEventDelegated: "#871094",
637
+ timelineEventDelayed: "#c00000",
638
+ // Red
639
+ separator: "#c4c4c4",
640
+ keyboardHint: "#8c8c8c",
641
+ helpDialogBorder: "#0033b3",
642
+ focusIndicator: "#0033b3",
643
+ modalOverlay: "#e8e8e8",
644
+ modalBackground: "#ffffff"
645
+ }
646
+ };
647
+
648
+ // src/themes/nord.ts
649
+ var nordTheme = {
650
+ name: "nord",
651
+ colors: {
652
+ background: "#2e3440",
653
+ foreground: "#d8dee9",
654
+ border: "#3b4252",
655
+ calendarBorder: "#3b4252",
656
+ calendarHeader: "#88c0d0",
657
+ // Frost Blue
658
+ calendarToday: "#81a1c1",
659
+ // Frost Blue darker
660
+ calendarSelected: "#81a1c1",
661
+ calendarDayWithTasks: "#a3be8c",
662
+ // Green
663
+ calendarDayOtherMonth: "#4c566a",
664
+ taskBorder: "#3b4252",
665
+ taskHeader: "#88c0d0",
666
+ taskCheckboxEmpty: "#4c566a",
667
+ taskCheckboxFilled: "#a3be8c",
668
+ taskStateTodo: "#d8dee9",
669
+ taskStateCompleted: "#4c566a",
670
+ taskStateDelegated: "#b48ead",
671
+ // Purple
672
+ taskStateDelayed: "#d08770",
673
+ // Orange
674
+ taskIndent: "#4c566a",
675
+ timelineBorder: "#3b4252",
676
+ timelineHeader: "#88c0d0",
677
+ timelineTimestamp: "#4c566a",
678
+ timelineEventCreated: "#5e81ac",
679
+ // Darkest Blue
680
+ timelineEventStarted: "#ebcb8b",
681
+ // Yellow
682
+ timelineEventCompleted: "#a3be8c",
683
+ timelineEventDelegated: "#b48ead",
684
+ timelineEventDelayed: "#bf616a",
685
+ // Red
686
+ separator: "#3b4252",
687
+ keyboardHint: "#4c566a",
688
+ helpDialogBorder: "#88c0d0",
689
+ focusIndicator: "#88c0d0",
690
+ modalOverlay: "#242933",
691
+ modalBackground: "#3b4252"
692
+ }
693
+ };
694
+
695
+ // src/themes/nordLight.ts
696
+ var nordLightTheme = {
697
+ name: "nord-light",
698
+ colors: {
699
+ background: "#eceff4",
700
+ // Nord6 (Snow Storm)
701
+ foreground: "#2e3440",
702
+ // Nord0 (Polar Night)
703
+ border: "#d8dee9",
704
+ // Nord4
705
+ calendarBorder: "#d8dee9",
706
+ calendarHeader: "#5e81ac",
707
+ // Nord10 (Frost - darkest blue)
708
+ calendarToday: "#5e81ac",
709
+ calendarSelected: "#5e81ac",
710
+ calendarDayWithTasks: "#a3be8c",
711
+ // Nord14 (Aurora - green)
712
+ calendarDayOtherMonth: "#4c566a",
713
+ // Nord3
714
+ taskBorder: "#d8dee9",
715
+ taskHeader: "#5e81ac",
716
+ taskCheckboxEmpty: "#4c566a",
717
+ taskCheckboxFilled: "#a3be8c",
718
+ taskStateTodo: "#2e3440",
719
+ taskStateCompleted: "#4c566a",
720
+ taskStateDelegated: "#b48ead",
721
+ // Nord15 (Aurora - purple)
722
+ taskStateDelayed: "#d08770",
723
+ // Nord12 (Aurora - orange)
724
+ taskIndent: "#d8dee9",
725
+ timelineBorder: "#d8dee9",
726
+ timelineHeader: "#5e81ac",
727
+ timelineTimestamp: "#4c566a",
728
+ timelineEventCreated: "#81a1c1",
729
+ // Nord9 (Frost)
730
+ timelineEventStarted: "#ebcb8b",
731
+ // Nord13 (Aurora - yellow)
732
+ timelineEventCompleted: "#a3be8c",
733
+ timelineEventDelegated: "#b48ead",
734
+ timelineEventDelayed: "#bf616a",
735
+ // Nord11 (Aurora - red)
736
+ separator: "#d8dee9",
737
+ keyboardHint: "#4c566a",
738
+ helpDialogBorder: "#5e81ac",
739
+ focusIndicator: "#5e81ac",
740
+ modalOverlay: "#e5e9f0",
741
+ // Nord5
742
+ modalBackground: "#eceff4"
743
+ }
744
+ };
745
+
746
+ // src/themes/postman.ts
747
+ var postmanTheme = {
748
+ name: "postman",
749
+ colors: {
750
+ background: "#212121",
751
+ foreground: "#ededed",
752
+ border: "#333333",
753
+ calendarBorder: "#333333",
754
+ calendarHeader: "#EF5B25",
755
+ // Postman Orange
756
+ calendarToday: "#EF5B25",
757
+ calendarSelected: "#EF5B25",
758
+ calendarDayWithTasks: "#00B8D9",
759
+ // Accent Blueish
760
+ calendarDayOtherMonth: "#666666",
761
+ taskBorder: "#333333",
762
+ taskHeader: "#EF5B25",
763
+ taskCheckboxEmpty: "#666666",
764
+ taskCheckboxFilled: "#00B8D9",
765
+ taskStateTodo: "#ededed",
766
+ taskStateCompleted: "#666666",
767
+ taskStateDelegated: "#FF9900",
768
+ taskStateDelayed: "#FF3333",
769
+ taskIndent: "#333333",
770
+ timelineBorder: "#333333",
771
+ timelineHeader: "#EF5B25",
772
+ timelineTimestamp: "#666666",
773
+ timelineEventCreated: "#EF5B25",
774
+ timelineEventStarted: "#FF9900",
775
+ timelineEventCompleted: "#00B8D9",
776
+ timelineEventDelegated: "#6554C0",
777
+ // Purple
778
+ timelineEventDelayed: "#FF3333",
779
+ separator: "#333333",
780
+ keyboardHint: "#666666",
781
+ helpDialogBorder: "#EF5B25",
782
+ focusIndicator: "#EF5B25",
783
+ modalOverlay: "#121212",
784
+ modalBackground: "#212121"
785
+ }
786
+ };
787
+
788
+ // src/themes/postmanLight.ts
789
+ var postmanLightTheme = {
790
+ name: "postman-light",
791
+ colors: {
792
+ background: "#ffffff",
793
+ foreground: "#212121",
794
+ border: "#e0e0e0",
795
+ calendarBorder: "#e0e0e0",
796
+ calendarHeader: "#ff6c37",
797
+ // Postman Orange
798
+ calendarToday: "#ff6c37",
799
+ calendarSelected: "#ff6c37",
800
+ calendarDayWithTasks: "#00a86b",
801
+ // Green
802
+ calendarDayOtherMonth: "#9e9e9e",
803
+ taskBorder: "#e0e0e0",
804
+ taskHeader: "#ff6c37",
805
+ taskCheckboxEmpty: "#9e9e9e",
806
+ taskCheckboxFilled: "#00a86b",
807
+ taskStateTodo: "#212121",
808
+ taskStateCompleted: "#9e9e9e",
809
+ taskStateDelegated: "#6554c0",
810
+ // Purple
811
+ taskStateDelayed: "#ffab00",
812
+ // Amber
813
+ taskIndent: "#e0e0e0",
814
+ timelineBorder: "#e0e0e0",
815
+ timelineHeader: "#ff6c37",
816
+ timelineTimestamp: "#9e9e9e",
817
+ timelineEventCreated: "#ff6c37",
818
+ timelineEventStarted: "#ffab00",
819
+ timelineEventCompleted: "#00a86b",
820
+ timelineEventDelegated: "#6554c0",
821
+ timelineEventDelayed: "#ff3333",
822
+ // Red
823
+ separator: "#e0e0e0",
824
+ keyboardHint: "#9e9e9e",
825
+ helpDialogBorder: "#ff6c37",
826
+ focusIndicator: "#ff6c37",
827
+ modalOverlay: "#f5f5f5",
828
+ modalBackground: "#ffffff"
829
+ }
830
+ };
831
+
832
+ // src/themes/cursor.ts
833
+ var cursorTheme = {
834
+ name: "cursor",
835
+ colors: {
836
+ background: "#1e1e1e",
837
+ // VS Code default dark background
838
+ foreground: "#cccccc",
839
+ border: "#3c3c3c",
840
+ calendarBorder: "#3c3c3c",
841
+ calendarHeader: "#569cd6",
842
+ // VS Code blue
843
+ calendarToday: "#569cd6",
844
+ calendarSelected: "#569cd6",
845
+ calendarDayWithTasks: "#4ec9b0",
846
+ // Teal
847
+ calendarDayOtherMonth: "#6e7681",
848
+ taskBorder: "#3c3c3c",
849
+ taskHeader: "#569cd6",
850
+ taskCheckboxEmpty: "#6e7681",
851
+ taskCheckboxFilled: "#4ec9b0",
852
+ taskStateTodo: "#cccccc",
853
+ taskStateCompleted: "#6e7681",
854
+ taskStateDelegated: "#c586c0",
855
+ // Purple
856
+ taskStateDelayed: "#ce9178",
857
+ // Orange
858
+ taskIndent: "#3c3c3c",
859
+ timelineBorder: "#3c3c3c",
860
+ timelineHeader: "#569cd6",
861
+ timelineTimestamp: "#6e7681",
862
+ timelineEventCreated: "#569cd6",
863
+ timelineEventStarted: "#dcdcaa",
864
+ // Yellow
865
+ timelineEventCompleted: "#4ec9b0",
866
+ timelineEventDelegated: "#c586c0",
867
+ timelineEventDelayed: "#f14c4c",
868
+ // Red
869
+ separator: "#3c3c3c",
870
+ keyboardHint: "#6e7681",
871
+ helpDialogBorder: "#569cd6",
872
+ focusIndicator: "#569cd6",
873
+ modalOverlay: "#0d0d0d",
874
+ modalBackground: "#252526"
875
+ // VS Code sidebar
876
+ }
877
+ };
878
+
879
+ // src/themes/cursorLight.ts
880
+ var cursorLightTheme = {
881
+ name: "cursor-light",
882
+ colors: {
883
+ background: "#ffffff",
884
+ foreground: "#1e1e1e",
885
+ border: "#e0e0e0",
886
+ calendarBorder: "#e0e0e0",
887
+ calendarHeader: "#0066b8",
888
+ // VS Code Blue
889
+ calendarToday: "#0066b8",
890
+ calendarSelected: "#0066b8",
891
+ calendarDayWithTasks: "#22863a",
892
+ // Green
893
+ calendarDayOtherMonth: "#a0a0a0",
894
+ taskBorder: "#e0e0e0",
895
+ taskHeader: "#0066b8",
896
+ taskCheckboxEmpty: "#a0a0a0",
897
+ taskCheckboxFilled: "#0066b8",
898
+ taskStateTodo: "#1e1e1e",
899
+ taskStateCompleted: "#a0a0a0",
900
+ taskStateDelegated: "#6f42c1",
901
+ // Purple
902
+ taskStateDelayed: "#d29922",
903
+ // Orange/Yellow
904
+ taskIndent: "#e0e0e0",
905
+ timelineBorder: "#e0e0e0",
906
+ timelineHeader: "#0066b8",
907
+ timelineTimestamp: "#a0a0a0",
908
+ timelineEventCreated: "#0066b8",
909
+ timelineEventStarted: "#d29922",
910
+ timelineEventCompleted: "#22863a",
911
+ timelineEventDelegated: "#6f42c1",
912
+ timelineEventDelayed: "#cb2431",
913
+ // Red
914
+ separator: "#e0e0e0",
915
+ keyboardHint: "#a0a0a0",
916
+ helpDialogBorder: "#0066b8",
917
+ focusIndicator: "#0066b8",
918
+ modalOverlay: "#f3f3f3",
919
+ modalBackground: "#ffffff"
920
+ }
921
+ };
922
+
923
+ // src/themes/x.ts
924
+ var xTheme = {
925
+ name: "x",
926
+ colors: {
927
+ background: "#15202b",
928
+ // X Dim background
929
+ foreground: "#f7f9f9",
930
+ border: "#38444d",
931
+ calendarBorder: "#38444d",
932
+ calendarHeader: "#1d9bf0",
933
+ // X Blue
934
+ calendarToday: "#1d9bf0",
935
+ calendarSelected: "#1d9bf0",
936
+ calendarDayWithTasks: "#00ba7c",
937
+ // Green
938
+ calendarDayOtherMonth: "#8b98a5",
939
+ // Secondary text
940
+ taskBorder: "#38444d",
941
+ taskHeader: "#1d9bf0",
942
+ taskCheckboxEmpty: "#8b98a5",
943
+ taskCheckboxFilled: "#00ba7c",
944
+ taskStateTodo: "#f7f9f9",
945
+ taskStateCompleted: "#8b98a5",
946
+ taskStateDelegated: "#7856ff",
947
+ // Purple
948
+ taskStateDelayed: "#f4212e",
949
+ // Red
950
+ taskIndent: "#38444d",
951
+ timelineBorder: "#38444d",
952
+ timelineHeader: "#1d9bf0",
953
+ timelineTimestamp: "#8b98a5",
954
+ timelineEventCreated: "#1d9bf0",
955
+ timelineEventStarted: "#ffad1f",
956
+ // Yellow
957
+ timelineEventCompleted: "#00ba7c",
958
+ timelineEventDelegated: "#7856ff",
959
+ timelineEventDelayed: "#f4212e",
960
+ separator: "#38444d",
961
+ keyboardHint: "#8b98a5",
962
+ helpDialogBorder: "#1d9bf0",
963
+ focusIndicator: "#1d9bf0",
964
+ modalOverlay: "#5b708366",
965
+ // X dim overlay style
966
+ modalBackground: "#1e2d3d"
967
+ }
968
+ };
969
+
970
+ // src/themes/xLight.ts
971
+ var xLightTheme = {
972
+ name: "x-light",
973
+ colors: {
974
+ background: "#ffffff",
975
+ foreground: "#0f1419",
976
+ // Twitter black text
977
+ border: "#eff3f4",
978
+ calendarBorder: "#eff3f4",
979
+ calendarHeader: "#1d9bf0",
980
+ // X Blue
981
+ calendarToday: "#1d9bf0",
982
+ calendarSelected: "#1d9bf0",
983
+ calendarDayWithTasks: "#00ba7c",
984
+ // Green
985
+ calendarDayOtherMonth: "#536471",
986
+ // Gray
987
+ taskBorder: "#eff3f4",
988
+ taskHeader: "#1d9bf0",
989
+ taskCheckboxEmpty: "#536471",
990
+ taskCheckboxFilled: "#00ba7c",
991
+ taskStateTodo: "#0f1419",
992
+ taskStateCompleted: "#536471",
993
+ taskStateDelegated: "#7856ff",
994
+ // Purple
995
+ taskStateDelayed: "#f4212e",
996
+ // Red (delayed = urgent)
997
+ taskIndent: "#eff3f4",
998
+ timelineBorder: "#eff3f4",
999
+ timelineHeader: "#1d9bf0",
1000
+ timelineTimestamp: "#536471",
1001
+ timelineEventCreated: "#1d9bf0",
1002
+ timelineEventStarted: "#ffad1f",
1003
+ // Yellow
1004
+ timelineEventCompleted: "#00ba7c",
1005
+ timelineEventDelegated: "#7856ff",
1006
+ timelineEventDelayed: "#f4212e",
1007
+ separator: "#eff3f4",
1008
+ keyboardHint: "#536471",
1009
+ helpDialogBorder: "#1d9bf0",
1010
+ focusIndicator: "#1d9bf0",
1011
+ modalOverlay: "#00000033",
1012
+ modalBackground: "#ffffff"
1013
+ }
1014
+ };
1015
+
1016
+ // src/themes/instagram.ts
1017
+ var instagramTheme = {
1018
+ name: "instagram",
1019
+ colors: {
1020
+ background: "#121212",
1021
+ foreground: "#fafafa",
1022
+ border: "#262626",
1023
+ calendarBorder: "#262626",
1024
+ calendarHeader: "#e1306c",
1025
+ // Instagram gradient pinkish
1026
+ calendarToday: "#0095f6",
1027
+ // Instagram blue
1028
+ calendarSelected: "#0095f6",
1029
+ calendarDayWithTasks: "#0095f6",
1030
+ calendarDayOtherMonth: "#8e8e8e",
1031
+ taskBorder: "#262626",
1032
+ taskHeader: "#e1306c",
1033
+ taskCheckboxEmpty: "#8e8e8e",
1034
+ taskCheckboxFilled: "#0095f6",
1035
+ taskStateTodo: "#fafafa",
1036
+ taskStateCompleted: "#8e8e8e",
1037
+ taskStateDelegated: "#833ab4",
1038
+ // Purple from gradient
1039
+ taskStateDelayed: "#fca1cc",
1040
+ // Orange/Yellow ish
1041
+ taskIndent: "#262626",
1042
+ timelineBorder: "#262626",
1043
+ timelineHeader: "#e1306c",
1044
+ timelineTimestamp: "#8e8e8e",
1045
+ timelineEventCreated: "#0095f6",
1046
+ timelineEventStarted: "#f56040",
1047
+ timelineEventCompleted: "#0095f6",
1048
+ timelineEventDelegated: "#833ab4",
1049
+ timelineEventDelayed: "#fd1d1d",
1050
+ separator: "#262626",
1051
+ keyboardHint: "#8e8e8e",
1052
+ helpDialogBorder: "#e1306c",
1053
+ focusIndicator: "#e1306c",
1054
+ modalOverlay: "#00000080",
1055
+ modalBackground: "#262626"
1056
+ }
1057
+ };
1058
+
1059
+ // src/themes/instagramLight.ts
1060
+ var instagramLightTheme = {
1061
+ name: "instagram-light",
1062
+ colors: {
1063
+ background: "#ffffff",
1064
+ foreground: "#262626",
1065
+ border: "#dbdbdb",
1066
+ calendarBorder: "#dbdbdb",
1067
+ calendarHeader: "#e1306c",
1068
+ // Instagram pink
1069
+ calendarToday: "#0095f6",
1070
+ // Instagram blue
1071
+ calendarSelected: "#0095f6",
1072
+ calendarDayWithTasks: "#0095f6",
1073
+ calendarDayOtherMonth: "#8e8e8e",
1074
+ taskBorder: "#dbdbdb",
1075
+ taskHeader: "#e1306c",
1076
+ taskCheckboxEmpty: "#8e8e8e",
1077
+ taskCheckboxFilled: "#0095f6",
1078
+ taskStateTodo: "#262626",
1079
+ taskStateCompleted: "#8e8e8e",
1080
+ taskStateDelegated: "#833ab4",
1081
+ // Purple gradient
1082
+ taskStateDelayed: "#fd1d1d",
1083
+ // Red
1084
+ taskIndent: "#dbdbdb",
1085
+ timelineBorder: "#dbdbdb",
1086
+ timelineHeader: "#e1306c",
1087
+ timelineTimestamp: "#8e8e8e",
1088
+ timelineEventCreated: "#0095f6",
1089
+ timelineEventStarted: "#f56040",
1090
+ // Orange
1091
+ timelineEventCompleted: "#0095f6",
1092
+ timelineEventDelegated: "#833ab4",
1093
+ timelineEventDelayed: "#fd1d1d",
1094
+ separator: "#dbdbdb",
1095
+ keyboardHint: "#8e8e8e",
1096
+ helpDialogBorder: "#e1306c",
1097
+ focusIndicator: "#e1306c",
1098
+ modalOverlay: "#00000066",
1099
+ modalBackground: "#ffffff"
1100
+ }
1101
+ };
1102
+
1103
+ // src/themes/amazon.ts
1104
+ var amazonTheme = {
1105
+ name: "amazon",
1106
+ colors: {
1107
+ background: "#131A22",
1108
+ foreground: "#ffffff",
1109
+ border: "#232f3e",
1110
+ calendarBorder: "#232f3e",
1111
+ calendarHeader: "#ff9900",
1112
+ // Amazon Orange
1113
+ calendarToday: "#ff9900",
1114
+ calendarSelected: "#ff9900",
1115
+ calendarDayWithTasks: "#ff9900",
1116
+ calendarDayOtherMonth: "#3a4553",
1117
+ taskBorder: "#232f3e",
1118
+ taskHeader: "#ff9900",
1119
+ taskCheckboxEmpty: "#3a4553",
1120
+ taskCheckboxFilled: "#ff9900",
1121
+ taskStateTodo: "#ffffff",
1122
+ taskStateCompleted: "#565959",
1123
+ taskStateDelegated: "#146eb4",
1124
+ // Amazon Prime blueish
1125
+ taskStateDelayed: "#ff9900",
1126
+ taskIndent: "#232f3e",
1127
+ timelineBorder: "#232f3e",
1128
+ timelineHeader: "#ff9900",
1129
+ timelineTimestamp: "#565959",
1130
+ timelineEventCreated: "#ff9900",
1131
+ timelineEventStarted: "#ff9900",
1132
+ timelineEventCompleted: "#ff9900",
1133
+ timelineEventDelegated: "#146eb4",
1134
+ timelineEventDelayed: "#cc0c39",
1135
+ separator: "#232f3e",
1136
+ keyboardHint: "#565959",
1137
+ helpDialogBorder: "#ff9900",
1138
+ focusIndicator: "#ff9900",
1139
+ modalOverlay: "#00000099",
1140
+ modalBackground: "#232f3e"
1141
+ }
1142
+ };
1143
+
1144
+ // src/themes/amazonLight.ts
1145
+ var amazonLightTheme = {
1146
+ name: "amazon-light",
1147
+ colors: {
1148
+ background: "#ffffff",
1149
+ foreground: "#0f1111",
1150
+ border: "#ddd",
1151
+ calendarBorder: "#ddd",
1152
+ calendarHeader: "#ff9900",
1153
+ // Amazon Orange
1154
+ calendarToday: "#ff9900",
1155
+ calendarSelected: "#ff9900",
1156
+ calendarDayWithTasks: "#ff9900",
1157
+ calendarDayOtherMonth: "#565959",
1158
+ taskBorder: "#ddd",
1159
+ taskHeader: "#ff9900",
1160
+ taskCheckboxEmpty: "#565959",
1161
+ taskCheckboxFilled: "#ff9900",
1162
+ taskStateTodo: "#0f1111",
1163
+ taskStateCompleted: "#565959",
1164
+ taskStateDelegated: "#146eb4",
1165
+ // Amazon Prime blue
1166
+ taskStateDelayed: "#b12704",
1167
+ // Amazon red/warning
1168
+ taskIndent: "#ddd",
1169
+ timelineBorder: "#ddd",
1170
+ timelineHeader: "#ff9900",
1171
+ timelineTimestamp: "#565959",
1172
+ timelineEventCreated: "#ff9900",
1173
+ timelineEventStarted: "#ff9900",
1174
+ timelineEventCompleted: "#007600",
1175
+ // Amazon green (success)
1176
+ timelineEventDelegated: "#146eb4",
1177
+ timelineEventDelayed: "#b12704",
1178
+ separator: "#ddd",
1179
+ keyboardHint: "#565959",
1180
+ helpDialogBorder: "#ff9900",
1181
+ focusIndicator: "#ff9900",
1182
+ modalOverlay: "#00000033",
1183
+ modalBackground: "#f7f8f8"
1184
+ }
1185
+ };
1186
+
1187
+ // src/themes/apple.ts
1188
+ var appleTheme = {
1189
+ name: "apple",
1190
+ colors: {
1191
+ background: "#1c1c1e",
1192
+ // System Background Dark
1193
+ foreground: "#ffffff",
1194
+ border: "#38383a",
1195
+ // System Gray 5 Dark
1196
+ calendarBorder: "#38383a",
1197
+ calendarHeader: "#0a84ff",
1198
+ // System Blue Dark
1199
+ calendarToday: "#0a84ff",
1200
+ calendarSelected: "#0a84ff",
1201
+ calendarDayWithTasks: "#30d158",
1202
+ // System Green Dark
1203
+ calendarDayOtherMonth: "#636366",
1204
+ // System Gray 3 Dark
1205
+ taskBorder: "#38383a",
1206
+ taskHeader: "#0a84ff",
1207
+ taskCheckboxEmpty: "#636366",
1208
+ taskCheckboxFilled: "#30d158",
1209
+ taskStateTodo: "#ffffff",
1210
+ taskStateCompleted: "#8e8e93",
1211
+ // System Gray Dark
1212
+ taskStateDelegated: "#bf5af2",
1213
+ // System Purple Dark
1214
+ taskStateDelayed: "#ff9f0a",
1215
+ // System Orange Dark
1216
+ taskIndent: "#48484a",
1217
+ // System Gray 4 Dark
1218
+ timelineBorder: "#38383a",
1219
+ timelineHeader: "#0a84ff",
1220
+ timelineTimestamp: "#8e8e93",
1221
+ timelineEventCreated: "#0a84ff",
1222
+ timelineEventStarted: "#ff9f0a",
1223
+ timelineEventCompleted: "#30d158",
1224
+ timelineEventDelegated: "#bf5af2",
1225
+ timelineEventDelayed: "#ff453a",
1226
+ // System Red Dark
1227
+ separator: "#38383a",
1228
+ keyboardHint: "#8e8e93",
1229
+ helpDialogBorder: "#0a84ff",
1230
+ focusIndicator: "#0a84ff",
1231
+ modalOverlay: "#00000066",
1232
+ modalBackground: "#2c2c2e"
1233
+ // System Gray 5 Dark
1234
+ }
1235
+ };
1236
+
1237
+ // src/themes/appleLight.ts
1238
+ var appleLightTheme = {
1239
+ name: "apple-light",
1240
+ colors: {
1241
+ background: "#ffffff",
1242
+ // System Background Light
1243
+ foreground: "#000000",
1244
+ border: "#d1d1d6",
1245
+ // System Gray 4 Light
1246
+ calendarBorder: "#d1d1d6",
1247
+ calendarHeader: "#007aff",
1248
+ // System Blue Light
1249
+ calendarToday: "#007aff",
1250
+ calendarSelected: "#007aff",
1251
+ calendarDayWithTasks: "#34c759",
1252
+ // System Green Light
1253
+ calendarDayOtherMonth: "#8e8e93",
1254
+ // System Gray Light
1255
+ taskBorder: "#d1d1d6",
1256
+ taskHeader: "#007aff",
1257
+ taskCheckboxEmpty: "#8e8e93",
1258
+ taskCheckboxFilled: "#34c759",
1259
+ taskStateTodo: "#000000",
1260
+ taskStateCompleted: "#8e8e93",
1261
+ taskStateDelegated: "#af52de",
1262
+ // System Purple Light
1263
+ taskStateDelayed: "#ff9500",
1264
+ // System Orange Light
1265
+ taskIndent: "#c7c7cc",
1266
+ timelineBorder: "#d1d1d6",
1267
+ timelineHeader: "#007aff",
1268
+ timelineTimestamp: "#8e8e93",
1269
+ timelineEventCreated: "#007aff",
1270
+ timelineEventStarted: "#ff9500",
1271
+ timelineEventCompleted: "#34c759",
1272
+ timelineEventDelegated: "#af52de",
1273
+ timelineEventDelayed: "#ff3b30",
1274
+ // System Red Light
1275
+ separator: "#d1d1d6",
1276
+ keyboardHint: "#8e8e93",
1277
+ helpDialogBorder: "#007aff",
1278
+ focusIndicator: "#007aff",
1279
+ modalOverlay: "#00000033",
1280
+ modalBackground: "#f2f2f7"
1281
+ // System Gray 6 Light
1282
+ }
1283
+ };
1284
+
1285
+ // src/themes/batman.ts
1286
+ var batmanTheme = {
1287
+ name: "batman",
1288
+ colors: {
1289
+ background: "#000000",
1290
+ foreground: "#d6d6d6",
1291
+ border: "#333333",
1292
+ calendarBorder: "#333333",
1293
+ calendarHeader: "#ffff00",
1294
+ // Bright Yellow
1295
+ calendarToday: "#ffff00",
1296
+ calendarSelected: "#ffff00",
1297
+ calendarDayWithTasks: "#ffff00",
1298
+ calendarDayOtherMonth: "#444444",
1299
+ taskBorder: "#333333",
1300
+ taskHeader: "#ffff00",
1301
+ taskCheckboxEmpty: "#444444",
1302
+ taskCheckboxFilled: "#ffff00",
1303
+ taskStateTodo: "#d6d6d6",
1304
+ taskStateCompleted: "#555555",
1305
+ taskStateDelegated: "#2a3c5f",
1306
+ // Dark Knight Blue
1307
+ taskStateDelayed: "#e6aa5f",
1308
+ // Goldish
1309
+ taskIndent: "#333333",
1310
+ timelineBorder: "#333333",
1311
+ timelineHeader: "#ffff00",
1312
+ timelineTimestamp: "#555555",
1313
+ timelineEventCreated: "#ffff00",
1314
+ timelineEventStarted: "#e6aa5f",
1315
+ timelineEventCompleted: "#ffff00",
1316
+ timelineEventDelegated: "#2a3c5f",
1317
+ timelineEventDelayed: "#8c541c",
1318
+ separator: "#333333",
1319
+ keyboardHint: "#444444",
1320
+ helpDialogBorder: "#ffff00",
1321
+ focusIndicator: "#ffff00",
1322
+ modalOverlay: "#00000099",
1323
+ modalBackground: "#1a1a1a"
1324
+ }
1325
+ };
1326
+
1327
+ // src/themes/spiderman.ts
1328
+ var spidermanTheme = {
1329
+ name: "spiderman",
1330
+ colors: {
1331
+ background: "#101820",
1332
+ // Very dark blueish black
1333
+ foreground: "#e0e0e0",
1334
+ border: "#2B3784",
1335
+ // Spidey Blue
1336
+ calendarBorder: "#2B3784",
1337
+ calendarHeader: "#DF1F2D",
1338
+ // Spidey Red
1339
+ calendarToday: "#DF1F2D",
1340
+ calendarSelected: "#DF1F2D",
1341
+ calendarDayWithTasks: "#DF1F2D",
1342
+ calendarDayOtherMonth: "#4a4a4a",
1343
+ taskBorder: "#2B3784",
1344
+ taskHeader: "#DF1F2D",
1345
+ taskCheckboxEmpty: "#2B3784",
1346
+ taskCheckboxFilled: "#DF1F2D",
1347
+ taskStateTodo: "#e0e0e0",
1348
+ taskStateCompleted: "#4a4a4a",
1349
+ taskStateDelegated: "#2B3784",
1350
+ taskStateDelayed: "#a71814",
1351
+ taskIndent: "#2B3784",
1352
+ timelineBorder: "#2B3784",
1353
+ timelineHeader: "#DF1F2D",
1354
+ timelineTimestamp: "#4a4a4a",
1355
+ timelineEventCreated: "#DF1F2D",
1356
+ timelineEventStarted: "#DF1F2D",
1357
+ timelineEventCompleted: "#DF1F2D",
1358
+ timelineEventDelegated: "#2B3784",
1359
+ timelineEventDelayed: "#a71814",
1360
+ separator: "#2B3784",
1361
+ keyboardHint: "#4a4a4a",
1362
+ helpDialogBorder: "#DF1F2D",
1363
+ focusIndicator: "#DF1F2D",
1364
+ modalOverlay: "#000000cc",
1365
+ modalBackground: "#1d2a38"
1366
+ }
1367
+ };
1368
+
1369
+ // src/themes/index.ts
1370
+ var lightThemes = {
1371
+ light: lightTheme,
1372
+ claude: claudeTheme,
1373
+ "apple-light": appleLightTheme,
1374
+ "github-light": githubLightTheme,
1375
+ "catppuccin-latte": catppuccinLatteTheme,
1376
+ "ubuntu-light": ubuntuLightTheme,
1377
+ "atom-light": atomOneLightTheme,
1378
+ "intellij-light": intellijLightTheme,
1379
+ "nord-light": nordLightTheme,
1380
+ "postman-light": postmanLightTheme,
1381
+ "cursor-light": cursorLightTheme,
1382
+ "x-light": xLightTheme,
1383
+ "instagram-light": instagramLightTheme,
1384
+ "amazon-light": amazonLightTheme
1385
+ };
1386
+ var darkThemes = {
1387
+ dark: darkTheme,
1388
+ terminal: terminalTheme,
1389
+ apple: appleTheme,
1390
+ "github-dark": githubDarkTheme,
1391
+ catppuccin: catppuccinTheme,
1392
+ ubuntu: ubuntuTheme,
1393
+ atom: atomOneDarkTheme,
1394
+ intellij: intellijTheme,
1395
+ nord: nordTheme,
1396
+ postman: postmanTheme,
1397
+ cursor: cursorTheme,
1398
+ x: xTheme,
1399
+ instagram: instagramTheme,
1400
+ amazon: amazonTheme,
1401
+ batman: batmanTheme,
1402
+ spiderman: spidermanTheme
1403
+ };
1404
+ var themes = {
1405
+ ...lightThemes,
1406
+ ...darkThemes
1407
+ };
1408
+ var getTheme = (name) => {
1409
+ return themes[name] || themes.dark;
1410
+ };
1411
+ var getThemeNames = () => {
1412
+ return Object.keys(themes);
1413
+ };
1414
+ var getLightThemeNames = () => {
1415
+ return Object.keys(lightThemes);
1416
+ };
1417
+ var getDarkThemeNames = () => {
1418
+ return Object.keys(darkThemes);
1419
+ };
1420
+
1421
+ // src/contexts/StorageContext.tsx
1422
+ import {
1423
+ createContext,
1424
+ useContext,
1425
+ useEffect,
1426
+ useRef,
1427
+ useState,
1428
+ useCallback
1429
+ } from "react";
1430
+
1431
+ // src/services/storage.ts
1432
+ import { promises as fs } from "fs";
1433
+ import { dirname } from "path";
1434
+ import { homedir } from "os";
1435
+ var getStoragePath = () => {
1436
+ const home = homedir();
1437
+ const platform = process.platform;
1438
+ if (platform === "darwin") {
1439
+ return `${home}/Library/Application Support/epoch/data.json`;
1440
+ } else if (platform === "linux") {
1441
+ return `${home}/.config/epoch/data.json`;
1442
+ } else if (platform === "win32") {
1443
+ const appData = process.env.APPDATA || `${home}\\AppData\\Roaming`;
1444
+ return `${appData}\\epoch\\data.json`;
1445
+ }
1446
+ return `${home}/.epoch/data.json`;
1447
+ };
1448
+ var getDefaultSchema = () => ({
1449
+ version: "1.0.0",
1450
+ tasks: {},
1451
+ timeline: {},
1452
+ settings: {
1453
+ theme: "dark",
1454
+ defaultStartTime: "now",
1455
+ dateFormat: "MMMM do, yyyy",
1456
+ timeFormat: "12h"
1457
+ }
1458
+ });
1459
+ var StorageService = class {
1460
+ constructor(filePath) {
1461
+ this.filePath = filePath || getStoragePath();
1462
+ }
1463
+ async load() {
1464
+ try {
1465
+ const data = await fs.readFile(this.filePath, "utf-8");
1466
+ const parsed = JSON.parse(data);
1467
+ return this.hydrateDates(parsed);
1468
+ } catch (error) {
1469
+ if (error.code === "ENOENT") {
1470
+ return getDefaultSchema();
1471
+ }
1472
+ console.error("Failed to load storage:", error);
1473
+ return getDefaultSchema();
1474
+ }
1475
+ }
1476
+ async save(data) {
1477
+ try {
1478
+ const dir = dirname(this.filePath);
1479
+ await fs.mkdir(dir, { recursive: true });
1480
+ const serialized = this.serializeDates(data);
1481
+ await fs.writeFile(
1482
+ this.filePath,
1483
+ JSON.stringify(serialized, null, 2),
1484
+ "utf-8"
1485
+ );
1486
+ } catch (error) {
1487
+ console.error("Failed to save storage:", error);
1488
+ }
1489
+ }
1490
+ async backup() {
1491
+ try {
1492
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-");
1493
+ const backupPath = `${this.filePath}.backup-${timestamp}`;
1494
+ const data = await fs.readFile(this.filePath, "utf-8");
1495
+ await fs.writeFile(backupPath, data, "utf-8");
1496
+ } catch (error) {
1497
+ console.error("Failed to backup storage:", error);
1498
+ }
1499
+ }
1500
+ getStoragePath() {
1501
+ return this.filePath;
1502
+ }
1503
+ hydrateDates(data) {
1504
+ if (data.tasks) {
1505
+ Object.keys(data.tasks).forEach((date) => {
1506
+ data.tasks[date] = data.tasks[date].map(
1507
+ (task) => this.hydrateTask(task)
1508
+ );
1509
+ });
1510
+ }
1511
+ if (data.timeline) {
1512
+ Object.keys(data.timeline).forEach((date) => {
1513
+ data.timeline[date] = data.timeline[date].map((event) => ({
1514
+ ...event,
1515
+ timestamp: new Date(event.timestamp),
1516
+ previousState: event.previousState,
1517
+ newState: event.newState
1518
+ }));
1519
+ });
1520
+ }
1521
+ return data;
1522
+ }
1523
+ hydrateTask(task) {
1524
+ return {
1525
+ ...task,
1526
+ createdAt: new Date(task.createdAt),
1527
+ updatedAt: new Date(task.updatedAt),
1528
+ startTime: task.startTime ? new Date(task.startTime) : void 0,
1529
+ endTime: task.endTime ? new Date(task.endTime) : void 0,
1530
+ children: task.children ? task.children.map((child) => this.hydrateTask(child)) : []
1531
+ };
1532
+ }
1533
+ serializeDates(data) {
1534
+ return {
1535
+ ...data,
1536
+ tasks: Object.keys(data.tasks).reduce((acc, date) => {
1537
+ acc[date] = data.tasks[date].map((task) => this.serializeTask(task));
1538
+ return acc;
1539
+ }, {}),
1540
+ timeline: Object.keys(data.timeline).reduce((acc, date) => {
1541
+ acc[date] = data.timeline[date].map((event) => ({
1542
+ ...event,
1543
+ timestamp: event.timestamp.toISOString()
1544
+ }));
1545
+ return acc;
1546
+ }, {})
1547
+ };
1548
+ }
1549
+ serializeTask(task) {
1550
+ return {
1551
+ ...task,
1552
+ createdAt: task.createdAt.toISOString(),
1553
+ updatedAt: task.updatedAt.toISOString(),
1554
+ startTime: task.startTime ? task.startTime.toISOString() : void 0,
1555
+ endTime: task.endTime ? task.endTime.toISOString() : void 0,
1556
+ children: task.children ? task.children.map((child) => this.serializeTask(child)) : []
1557
+ };
1558
+ }
1559
+ };
1560
+ var storageService = new StorageService();
1561
+
1562
+ // src/contexts/StorageContext.tsx
1563
+ import { jsx } from "react/jsx-runtime";
1564
+ var StorageContext = createContext(void 0);
1565
+ var StorageProvider = ({
1566
+ children
1567
+ }) => {
1568
+ const [data, setData] = useState(null);
1569
+ const [isLoading, setIsLoading] = useState(true);
1570
+ const [error, setError] = useState(null);
1571
+ const saveTimeoutRef = useRef(void 0);
1572
+ const latestDataRef = useRef(null);
1573
+ useEffect(() => {
1574
+ const loadData = async () => {
1575
+ try {
1576
+ setIsLoading(true);
1577
+ const loadedData = await storageService.load();
1578
+ setData(loadedData);
1579
+ latestDataRef.current = loadedData;
1580
+ setError(null);
1581
+ } catch (err) {
1582
+ setError(err instanceof Error ? err : new Error("Unknown error"));
1583
+ } finally {
1584
+ setIsLoading(false);
1585
+ }
1586
+ };
1587
+ loadData();
1588
+ }, []);
1589
+ const save = useCallback(async (newData) => {
1590
+ setData(newData);
1591
+ latestDataRef.current = newData;
1592
+ if (saveTimeoutRef.current) {
1593
+ clearTimeout(saveTimeoutRef.current);
1594
+ }
1595
+ saveTimeoutRef.current = setTimeout(async () => {
1596
+ try {
1597
+ await storageService.save(newData);
1598
+ } catch (err) {
1599
+ setError(err instanceof Error ? err : new Error("Failed to save"));
1600
+ }
1601
+ }, 500);
1602
+ }, []);
1603
+ const saveNow = useCallback(async () => {
1604
+ if (saveTimeoutRef.current) {
1605
+ clearTimeout(saveTimeoutRef.current);
1606
+ }
1607
+ if (latestDataRef.current) {
1608
+ try {
1609
+ await storageService.save(latestDataRef.current);
1610
+ } catch (err) {
1611
+ console.error("Failed to save:", err);
1612
+ }
1613
+ }
1614
+ }, []);
1615
+ useEffect(() => {
1616
+ return () => {
1617
+ if (saveTimeoutRef.current) {
1618
+ clearTimeout(saveTimeoutRef.current);
1619
+ }
1620
+ if (latestDataRef.current) {
1621
+ storageService.save(latestDataRef.current).catch((err) => {
1622
+ console.error("Failed to save on unmount:", err);
1623
+ });
1624
+ }
1625
+ };
1626
+ }, []);
1627
+ return /* @__PURE__ */ jsx(StorageContext.Provider, { value: { data, isLoading, error, save, saveNow }, children });
1628
+ };
1629
+ var useStorage = () => {
1630
+ const context = useContext(StorageContext);
1631
+ if (!context) {
1632
+ throw new Error("useStorage must be used within StorageProvider");
1633
+ }
1634
+ return context;
1635
+ };
1636
+
1637
+ // src/contexts/ThemeContext.tsx
1638
+ import { jsx as jsx2 } from "react/jsx-runtime";
1639
+ var ThemeContext = createContext2(void 0);
1640
+ var ThemeProvider = ({
1641
+ children,
1642
+ initialTheme = "dark"
1643
+ }) => {
1644
+ const { data, save } = useStorage();
1645
+ const [themeName, setThemeName] = useState2(initialTheme);
1646
+ const theme = getTheme(themeName);
1647
+ useEffect2(() => {
1648
+ if (data?.settings?.theme) {
1649
+ setThemeName(data.settings.theme);
1650
+ }
1651
+ }, [data?.settings?.theme]);
1652
+ const handleSetTheme = (name) => {
1653
+ if (getThemeNames().includes(name)) {
1654
+ setThemeName(name);
1655
+ if (data) {
1656
+ save({
1657
+ ...data,
1658
+ settings: {
1659
+ ...data.settings,
1660
+ theme: name
1661
+ }
1662
+ });
1663
+ }
1664
+ }
1665
+ };
1666
+ return /* @__PURE__ */ jsx2(
1667
+ ThemeContext.Provider,
1668
+ {
1669
+ value: {
1670
+ theme,
1671
+ themeName,
1672
+ setTheme: handleSetTheme,
1673
+ availableThemes: getThemeNames()
1674
+ },
1675
+ children
1676
+ }
1677
+ );
1678
+ };
1679
+ var useTheme = () => {
1680
+ const context = useContext2(ThemeContext);
1681
+ if (!context) {
1682
+ throw new Error("useTheme must be used within ThemeProvider");
1683
+ }
1684
+ return context;
1685
+ };
1686
+
1687
+ // src/contexts/AppContext.tsx
1688
+ import {
1689
+ createContext as createContext3,
1690
+ useContext as useContext3,
1691
+ useEffect as useEffect3,
1692
+ useState as useState3,
1693
+ useRef as useRef2,
1694
+ useCallback as useCallback2
1695
+ } from "react";
1696
+ import { jsx as jsx3 } from "react/jsx-runtime";
1697
+ var AppContext = createContext3(void 0);
1698
+ var AppProvider = ({ children }) => {
1699
+ const { data, save, saveNow } = useStorage();
1700
+ const today = /* @__PURE__ */ new Date();
1701
+ const [selectedDate, setSelectedDate] = useState3({
1702
+ year: today.getFullYear(),
1703
+ month: today.getMonth(),
1704
+ day: today.getDate()
1705
+ });
1706
+ const [tasks, setTasks] = useState3({});
1707
+ const [timeline, setTimeline] = useState3(
1708
+ {}
1709
+ );
1710
+ const [activePane, setActivePane] = useState3("tasks");
1711
+ const [showHelp, setShowHelp] = useState3(false);
1712
+ const isInputModeRef = useRef2(false);
1713
+ const [isInputModeState, setIsInputModeState] = useState3(false);
1714
+ const [showOverview, setShowOverview] = useState3(false);
1715
+ const setIsInputMode = useCallback2((mode) => {
1716
+ isInputModeRef.current = mode;
1717
+ setIsInputModeState(mode);
1718
+ }, []);
1719
+ const isInputMode = isInputModeRef.current;
1720
+ const [overviewMonth, setOverviewMonth] = useState3({
1721
+ year: today.getFullYear(),
1722
+ month: today.getMonth()
1723
+ });
1724
+ const [exitConfirmation, setExitConfirmation] = useState3(false);
1725
+ const [showThemeDialog, setShowThemeDialog] = useState3(false);
1726
+ const [showClearTimelineDialog, setShowClearTimelineDialog] = useState3(false);
1727
+ const clearTimelineForDate = useCallback2((dateStr) => {
1728
+ setTimeline((prev) => {
1729
+ const newTimeline = { ...prev };
1730
+ delete newTimeline[dateStr];
1731
+ return newTimeline;
1732
+ });
1733
+ }, []);
1734
+ const initialLoadDone = useRef2(false);
1735
+ const dataRef = useRef2(data);
1736
+ const saveRef = useRef2(save);
1737
+ useEffect3(() => {
1738
+ dataRef.current = data;
1739
+ saveRef.current = save;
1740
+ }, [data, save]);
1741
+ useEffect3(() => {
1742
+ if (data && !initialLoadDone.current) {
1743
+ setTasks(data.tasks);
1744
+ setTimeline(data.timeline);
1745
+ initialLoadDone.current = true;
1746
+ }
1747
+ }, [data]);
1748
+ useEffect3(() => {
1749
+ if (initialLoadDone.current && dataRef.current) {
1750
+ saveRef.current({
1751
+ ...dataRef.current,
1752
+ tasks,
1753
+ timeline
1754
+ });
1755
+ }
1756
+ }, [tasks, timeline]);
1757
+ return /* @__PURE__ */ jsx3(
1758
+ AppContext.Provider,
1759
+ {
1760
+ value: {
1761
+ selectedDate,
1762
+ setSelectedDate,
1763
+ tasks,
1764
+ setTasks,
1765
+ timeline,
1766
+ setTimeline,
1767
+ activePane,
1768
+ setActivePane,
1769
+ showHelp,
1770
+ setShowHelp,
1771
+ isInputMode,
1772
+ setIsInputMode,
1773
+ showOverview,
1774
+ setShowOverview,
1775
+ overviewMonth,
1776
+ setOverviewMonth,
1777
+ exitConfirmation,
1778
+ setExitConfirmation,
1779
+ showThemeDialog,
1780
+ setShowThemeDialog,
1781
+ showClearTimelineDialog,
1782
+ setShowClearTimelineDialog,
1783
+ clearTimelineForDate,
1784
+ isModalOpen: showHelp || showThemeDialog || showOverview || showClearTimelineDialog,
1785
+ saveNow
1786
+ },
1787
+ children
1788
+ }
1789
+ );
1790
+ };
1791
+ var useApp = () => {
1792
+ const context = useContext3(AppContext);
1793
+ if (!context) {
1794
+ throw new Error("useApp must be used within AppProvider");
1795
+ }
1796
+ return context;
1797
+ };
1798
+
1799
+ // src/hooks/useKeyboardNav.ts
1800
+ import { useInput } from "ink";
1801
+ import { useEffect as useEffect4 } from "react";
1802
+ var useKeyboardNav = () => {
1803
+ const { showHelp, setShowHelp, activePane, setActivePane, isInputMode, showOverview, setShowOverview, overviewMonth, setOverviewMonth, exitConfirmation, setExitConfirmation, showThemeDialog, setShowThemeDialog, showClearTimelineDialog, setShowClearTimelineDialog, saveNow } = useApp();
1804
+ useEffect4(() => {
1805
+ if (exitConfirmation) {
1806
+ const timer = setTimeout(() => {
1807
+ setExitConfirmation(false);
1808
+ }, 3e3);
1809
+ return () => clearTimeout(timer);
1810
+ }
1811
+ }, [exitConfirmation, setExitConfirmation]);
1812
+ const isActive = !isInputMode && !showThemeDialog && !showClearTimelineDialog;
1813
+ useInput((input, key) => {
1814
+ if (key.ctrl && input === "c") {
1815
+ if (exitConfirmation) {
1816
+ saveNow().then(() => {
1817
+ const inkApp = global.__inkApp;
1818
+ if (inkApp) {
1819
+ inkApp.unmount();
1820
+ }
1821
+ setTimeout(() => {
1822
+ console.clear();
1823
+ process.stdout.write("\x1Bc");
1824
+ process.exit(0);
1825
+ }, 100);
1826
+ }).catch(() => {
1827
+ const inkApp = global.__inkApp;
1828
+ if (inkApp) {
1829
+ inkApp.unmount();
1830
+ }
1831
+ setTimeout(() => {
1832
+ console.clear();
1833
+ process.stdout.write("\x1Bc");
1834
+ process.exit(0);
1835
+ }, 100);
1836
+ });
1837
+ return;
1838
+ } else {
1839
+ setExitConfirmation(true);
1840
+ return;
1841
+ }
1842
+ }
1843
+ if (input === ":") {
1844
+ setShowOverview(!showOverview);
1845
+ return;
1846
+ }
1847
+ if (input === "?") {
1848
+ setShowHelp(!showHelp);
1849
+ return;
1850
+ }
1851
+ if (key.ctrl && input === "t") {
1852
+ setShowThemeDialog(true);
1853
+ return;
1854
+ }
1855
+ if (input === "C" && activePane === "timeline") {
1856
+ setShowClearTimelineDialog(true);
1857
+ return;
1858
+ }
1859
+ if (input === "1") {
1860
+ setActivePane("calendar");
1861
+ return;
1862
+ }
1863
+ if (input === "2" || key.tab && !key.shift) {
1864
+ setActivePane("tasks");
1865
+ return;
1866
+ }
1867
+ if (input === "3" || key.tab && key.shift) {
1868
+ setActivePane("timeline");
1869
+ return;
1870
+ }
1871
+ }, {
1872
+ // Disable this hook when in input mode or dialogs are open to prevent interference with TextInput
1873
+ isActive
1874
+ });
1875
+ };
1876
+
1877
+ // src/hooks/useTerminalSize.ts
1878
+ import { useState as useState4, useEffect as useEffect5 } from "react";
1879
+ import { useStdout } from "ink";
1880
+ var useTerminalSize = () => {
1881
+ const { stdout } = useStdout();
1882
+ const [size, setSize] = useState4({
1883
+ width: stdout?.columns || 100,
1884
+ height: stdout?.rows || 30
1885
+ });
1886
+ useEffect5(() => {
1887
+ if (!stdout) return;
1888
+ setSize({
1889
+ width: stdout.columns || 100,
1890
+ height: stdout.rows || 30
1891
+ });
1892
+ const handleResize = () => {
1893
+ setSize({
1894
+ width: stdout.columns || 100,
1895
+ height: stdout.rows || 30
1896
+ });
1897
+ };
1898
+ stdout.on("resize", handleResize);
1899
+ return () => {
1900
+ stdout.off("resize", handleResize);
1901
+ };
1902
+ }, [stdout]);
1903
+ return size;
1904
+ };
1905
+
1906
+ // src/components/layout/ThreeColumnLayout.tsx
1907
+ import { Box, Text } from "ink";
1908
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1909
+ var VerticalSeparator = ({ color, backgroundColor, height, isFocused }) => {
1910
+ const char = isFocused ? "\u2503" : "\u2502";
1911
+ const lines = height ? Array(height).fill(char) : [char];
1912
+ return /* @__PURE__ */ jsx4(Box, { flexDirection: "column", backgroundColor, children: lines.map((c, i) => /* @__PURE__ */ jsx4(Text, { color, backgroundColor, children: c }, i)) });
1913
+ };
1914
+ var ThreeColumnLayout = ({
1915
+ leftPane,
1916
+ centerPane,
1917
+ rightPane,
1918
+ leftWidth = "15%",
1919
+ rightWidth = "25%",
1920
+ height,
1921
+ activePane
1922
+ }) => {
1923
+ const { theme } = useTheme();
1924
+ const focusedColor = theme.colors.focusIndicator;
1925
+ const normalColor = theme.colors.border;
1926
+ const bgColor = theme.name !== "terminal" ? theme.colors.background : void 0;
1927
+ return /* @__PURE__ */ jsxs(
1928
+ Box,
1929
+ {
1930
+ flexDirection: "row",
1931
+ width: "100%",
1932
+ height,
1933
+ backgroundColor: bgColor,
1934
+ children: [
1935
+ /* @__PURE__ */ jsx4(
1936
+ Box,
1937
+ {
1938
+ width: leftWidth,
1939
+ flexShrink: 0,
1940
+ flexDirection: "column",
1941
+ backgroundColor: bgColor,
1942
+ children: leftPane
1943
+ }
1944
+ ),
1945
+ /* @__PURE__ */ jsx4(
1946
+ VerticalSeparator,
1947
+ {
1948
+ isFocused: activePane === "calendar" || activePane === "tasks",
1949
+ color: activePane === "calendar" || activePane === "tasks" ? focusedColor : normalColor,
1950
+ backgroundColor: bgColor,
1951
+ height
1952
+ }
1953
+ ),
1954
+ /* @__PURE__ */ jsx4(
1955
+ Box,
1956
+ {
1957
+ flexGrow: 1,
1958
+ flexShrink: 1,
1959
+ flexDirection: "column",
1960
+ backgroundColor: bgColor,
1961
+ children: centerPane
1962
+ }
1963
+ ),
1964
+ /* @__PURE__ */ jsx4(
1965
+ VerticalSeparator,
1966
+ {
1967
+ isFocused: activePane === "tasks" || activePane === "timeline",
1968
+ color: activePane === "tasks" || activePane === "timeline" ? focusedColor : normalColor,
1969
+ backgroundColor: bgColor,
1970
+ height
1971
+ }
1972
+ ),
1973
+ /* @__PURE__ */ jsx4(
1974
+ Box,
1975
+ {
1976
+ width: rightWidth,
1977
+ flexShrink: 0.3,
1978
+ flexDirection: "column",
1979
+ backgroundColor: bgColor,
1980
+ children: rightPane
1981
+ }
1982
+ )
1983
+ ]
1984
+ }
1985
+ );
1986
+ };
1987
+
1988
+ // src/components/calendar/CalendarPane.tsx
1989
+ import { useState as useState5, useEffect as useEffect6 } from "react";
1990
+ import { Box as Box5, Text as Text3, useInput as useInput2 } from "ink";
1991
+ import { addDays, addWeeks, subDays, subWeeks } from "date-fns";
1992
+
1993
+ // src/components/layout/Pane.tsx
1994
+ import { Box as Box2 } from "ink";
1995
+
1996
+ // src/components/common/ThemedText.tsx
1997
+ import { Text as Text2 } from "ink";
1998
+ import { jsx as jsx5 } from "react/jsx-runtime";
1999
+ var ThemedText = ({
2000
+ children,
2001
+ backgroundColor,
2002
+ ...props
2003
+ }) => {
2004
+ const { theme } = useTheme();
2005
+ const bgColor = backgroundColor ?? (theme.name !== "terminal" ? theme.colors.background : void 0);
2006
+ return /* @__PURE__ */ jsx5(Text2, { ...props, backgroundColor: bgColor, children });
2007
+ };
2008
+
2009
+ // src/components/layout/Pane.tsx
2010
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
2011
+ var Pane = ({
2012
+ children,
2013
+ title,
2014
+ isFocused = false,
2015
+ width,
2016
+ height,
2017
+ center = false
2018
+ }) => {
2019
+ const { theme } = useTheme();
2020
+ const paneHeight = height;
2021
+ return /* @__PURE__ */ jsxs2(
2022
+ Box2,
2023
+ {
2024
+ flexDirection: "column",
2025
+ width,
2026
+ height: paneHeight,
2027
+ paddingRight: 1,
2028
+ paddingX: 2,
2029
+ alignItems: center ? "center" : "flex-start",
2030
+ children: [
2031
+ title && /* @__PURE__ */ jsx6(Box2, { marginBottom: 1, children: /* @__PURE__ */ jsx6(
2032
+ ThemedText,
2033
+ {
2034
+ backgroundColor: isFocused ? theme.colors.focusIndicator : void 0,
2035
+ color: isFocused ? theme.colors.background : theme.colors.taskHeader,
2036
+ bold: true,
2037
+ children: isFocused ? ` ${title.toUpperCase()} ` : title
2038
+ }
2039
+ ) }),
2040
+ /* @__PURE__ */ jsx6(
2041
+ Box2,
2042
+ {
2043
+ flexDirection: "column",
2044
+ flexGrow: 1,
2045
+ overflowY: "hidden",
2046
+ alignItems: center ? "center" : "flex-start",
2047
+ children
2048
+ }
2049
+ )
2050
+ ]
2051
+ }
2052
+ );
2053
+ };
2054
+
2055
+ // src/components/calendar/MonthView.tsx
2056
+ import { Box as Box4 } from "ink";
2057
+
2058
+ // src/components/calendar/DayCell.tsx
2059
+ import { Box as Box3 } from "ink";
2060
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
2061
+ var DayCell = ({ day }) => {
2062
+ const { theme } = useTheme();
2063
+ let textColor = theme.colors.calendarDayOtherMonth;
2064
+ if (day.isCurrentMonth) {
2065
+ textColor = day.hasTasks ? theme.colors.calendarDayWithTasks : theme.colors.foreground;
2066
+ }
2067
+ const isSelected = day.isSelected;
2068
+ const isToday2 = day.isToday && !day.isSelected;
2069
+ if (isSelected) {
2070
+ textColor = theme.colors.calendarSelected;
2071
+ } else if (day.isToday) {
2072
+ textColor = theme.colors.calendarToday;
2073
+ }
2074
+ const dayNum = day.date.day.toString().padStart(2, " ");
2075
+ const leftBracket = isSelected ? "[" : isToday2 ? "(" : " ";
2076
+ const rightBracket = isSelected ? "]" : isToday2 ? ")" : " ";
2077
+ return /* @__PURE__ */ jsx7(Box3, { width: 4, children: /* @__PURE__ */ jsxs3(ThemedText, { color: textColor, children: [
2078
+ leftBracket,
2079
+ dayNum,
2080
+ rightBracket
2081
+ ] }) });
2082
+ };
2083
+
2084
+ // src/components/calendar/MonthView.tsx
2085
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
2086
+ var MonthView = ({ calendarView }) => {
2087
+ const { theme } = useTheme();
2088
+ const dayHeaders = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
2089
+ return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
2090
+ /* @__PURE__ */ jsx8(Box4, { marginBottom: 1, children: dayHeaders.map((day) => /* @__PURE__ */ jsx8(Box4, { width: 4, children: /* @__PURE__ */ jsx8(ThemedText, { color: theme.colors.calendarHeader, bold: true, children: day }) }, day)) }),
2091
+ calendarView.weeks.map((week, weekIdx) => /* @__PURE__ */ jsx8(Box4, { marginBottom: 0, children: week.map((day) => /* @__PURE__ */ jsx8(DayCell, { day }, day.dateString)) }, weekIdx))
2092
+ ] });
2093
+ };
2094
+
2095
+ // src/utils/date.ts
2096
+ import { format, startOfMonth, endOfMonth, eachDayOfInterval, startOfWeek, endOfWeek } from "date-fns";
2097
+ var formatDate = (date, formatStr = "MMM d, yyyy") => {
2098
+ return format(date, formatStr);
2099
+ };
2100
+ var getDateString = (date) => {
2101
+ return format(date, "yyyy-MM-dd");
2102
+ };
2103
+ var generateMonthCalendar = (year, month) => {
2104
+ const monthStart = startOfMonth(new Date(year, month, 1));
2105
+ const monthEnd = endOfMonth(monthStart);
2106
+ const calendarStart = startOfWeek(monthStart);
2107
+ const calendarEnd = endOfWeek(monthEnd);
2108
+ const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });
2109
+ const weeks = [];
2110
+ for (let i = 0; i < days.length; i += 7) {
2111
+ weeks.push(days.slice(i, i + 7));
2112
+ }
2113
+ return weeks;
2114
+ };
2115
+ var isToday = (date) => {
2116
+ const today = /* @__PURE__ */ new Date();
2117
+ return date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear();
2118
+ };
2119
+
2120
+ // src/services/calendarService.ts
2121
+ var CalendarService = class {
2122
+ generateMonthView(year, month, selectedDate, tasks) {
2123
+ const weeks = generateMonthCalendar(year, month);
2124
+ const calendarDays = weeks.map(
2125
+ (week) => week.map((date) => this.createCalendarDay(date, selectedDate, tasks, month))
2126
+ );
2127
+ return {
2128
+ year,
2129
+ month,
2130
+ weeks: calendarDays
2131
+ };
2132
+ }
2133
+ createCalendarDay(date, selectedDate, tasks, currentMonth) {
2134
+ const dateString = getDateString(date);
2135
+ const dayTasks = tasks[dateString] || [];
2136
+ return {
2137
+ date: {
2138
+ year: date.getFullYear(),
2139
+ month: date.getMonth(),
2140
+ day: date.getDate()
2141
+ },
2142
+ dateString,
2143
+ isToday: isToday(date),
2144
+ isSelected: this.isSameDay(date, selectedDate),
2145
+ isCurrentMonth: date.getMonth() === currentMonth,
2146
+ hasTasks: dayTasks.length > 0,
2147
+ taskCount: dayTasks.length
2148
+ };
2149
+ }
2150
+ isSameDay(date, calendarDate) {
2151
+ return date.getDate() === calendarDate.day && date.getMonth() === calendarDate.month && date.getFullYear() === calendarDate.year;
2152
+ }
2153
+ getNextMonth(year, month) {
2154
+ if (month === 11) {
2155
+ return { year: year + 1, month: 0 };
2156
+ }
2157
+ return { year, month: month + 1 };
2158
+ }
2159
+ getPreviousMonth(year, month) {
2160
+ if (month === 0) {
2161
+ return { year: year - 1, month: 11 };
2162
+ }
2163
+ return { year, month: month - 1 };
2164
+ }
2165
+ getDayOfWeek(date) {
2166
+ return date.getDay();
2167
+ }
2168
+ getMonthName(month) {
2169
+ const months = [
2170
+ "January",
2171
+ "February",
2172
+ "March",
2173
+ "April",
2174
+ "May",
2175
+ "June",
2176
+ "July",
2177
+ "August",
2178
+ "September",
2179
+ "October",
2180
+ "November",
2181
+ "December"
2182
+ ];
2183
+ return months[month];
2184
+ }
2185
+ };
2186
+ var calendarService = new CalendarService();
2187
+
2188
+ // src/components/calendar/CalendarPane.tsx
2189
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
2190
+ var CalendarPane = () => {
2191
+ const { theme } = useTheme();
2192
+ const { selectedDate, setSelectedDate, tasks, activePane, isModalOpen, isInputMode } = useApp();
2193
+ const [currentMonth, setCurrentMonth] = useState5({
2194
+ year: selectedDate.year,
2195
+ month: selectedDate.month
2196
+ });
2197
+ useEffect6(() => {
2198
+ if (selectedDate.month !== currentMonth.month || selectedDate.year !== currentMonth.year) {
2199
+ setCurrentMonth({ year: selectedDate.year, month: selectedDate.month });
2200
+ }
2201
+ }, [selectedDate.year, selectedDate.month]);
2202
+ const calendarView = calendarService.generateMonthView(
2203
+ currentMonth.year,
2204
+ currentMonth.month,
2205
+ selectedDate,
2206
+ tasks
2207
+ );
2208
+ const isFocused = activePane === "calendar" && !isModalOpen;
2209
+ const navigateDate = (newDate) => {
2210
+ setSelectedDate({
2211
+ year: newDate.getFullYear(),
2212
+ month: newDate.getMonth(),
2213
+ day: newDate.getDate()
2214
+ });
2215
+ };
2216
+ useInput2(
2217
+ (input, key) => {
2218
+ if (!isFocused) return;
2219
+ const currentDate = new Date(
2220
+ selectedDate.year,
2221
+ selectedDate.month,
2222
+ selectedDate.day
2223
+ );
2224
+ if (input === "h" || key.leftArrow) {
2225
+ navigateDate(subDays(currentDate, 1));
2226
+ return;
2227
+ }
2228
+ if (input === "l" || key.rightArrow) {
2229
+ navigateDate(addDays(currentDate, 1));
2230
+ return;
2231
+ }
2232
+ if (input === "j" || key.downArrow) {
2233
+ navigateDate(addWeeks(currentDate, 1));
2234
+ return;
2235
+ }
2236
+ if (input === "k" || key.upArrow) {
2237
+ navigateDate(subWeeks(currentDate, 1));
2238
+ return;
2239
+ }
2240
+ if (input === "n") {
2241
+ const next = calendarService.getNextMonth(
2242
+ currentMonth.year,
2243
+ currentMonth.month
2244
+ );
2245
+ setCurrentMonth(next);
2246
+ setSelectedDate({
2247
+ year: next.year,
2248
+ month: next.month,
2249
+ day: 1
2250
+ });
2251
+ return;
2252
+ }
2253
+ if (input === "p") {
2254
+ const prev = calendarService.getPreviousMonth(
2255
+ currentMonth.year,
2256
+ currentMonth.month
2257
+ );
2258
+ setCurrentMonth(prev);
2259
+ setSelectedDate({
2260
+ year: prev.year,
2261
+ month: prev.month,
2262
+ day: 1
2263
+ });
2264
+ return;
2265
+ }
2266
+ if (input === "T") {
2267
+ const today = /* @__PURE__ */ new Date();
2268
+ setSelectedDate({
2269
+ year: today.getFullYear(),
2270
+ month: today.getMonth(),
2271
+ day: today.getDate()
2272
+ });
2273
+ return;
2274
+ }
2275
+ },
2276
+ { isActive: isFocused && !isInputMode }
2277
+ );
2278
+ const monthName = calendarService.getMonthName(currentMonth.month);
2279
+ return /* @__PURE__ */ jsx9(
2280
+ Pane,
2281
+ {
2282
+ title: `${monthName} ${currentMonth.year}`,
2283
+ isFocused,
2284
+ center: true,
2285
+ children: /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", alignItems: "center", children: [
2286
+ /* @__PURE__ */ jsx9(MonthView, { calendarView }),
2287
+ /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
2288
+ /* @__PURE__ */ jsx9(Text3, { color: theme.colors.keyboardHint, dimColor: true, children: "h/l: days j/k: weeks" }),
2289
+ /* @__PURE__ */ jsx9(Text3, { color: theme.colors.keyboardHint, dimColor: true, children: "n/p: month T: today" })
2290
+ ] })
2291
+ ] })
2292
+ }
2293
+ );
2294
+ };
2295
+
2296
+ // src/components/tasks/TasksPane.tsx
2297
+ import { useState as useState6, useEffect as useEffect7, useMemo, useRef as useRef3 } from "react";
2298
+ import { Box as Box7, Text as Text5, useInput as useInput3 } from "ink";
2299
+ import { TextInput } from "@inkjs/ui";
2300
+
2301
+ // src/components/tasks/TaskHeader.tsx
2302
+ import { Box as Box6, Text as Text4 } from "ink";
2303
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
2304
+ var TaskHeader = ({
2305
+ selectedDate,
2306
+ completionPercentage
2307
+ }) => {
2308
+ const { theme } = useTheme();
2309
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginBottom: 1, children: [
2310
+ /* @__PURE__ */ jsx10(Text4, { color: theme.colors.taskHeader, children: formatDate(selectedDate, "EEEE, MMMM d, yyyy") }),
2311
+ /* @__PURE__ */ jsxs6(Text4, { color: theme.colors.taskHeader, children: [
2312
+ completionPercentage,
2313
+ "% completed"
2314
+ ] })
2315
+ ] });
2316
+ };
2317
+
2318
+ // src/services/taskService.ts
2319
+ import { v4 as uuid } from "uuid";
2320
+
2321
+ // src/utils/tree.ts
2322
+ var findTaskById = (tasks, id) => {
2323
+ for (const task of tasks) {
2324
+ if (task.id === id) return task;
2325
+ const found = findTaskById(task.children, id);
2326
+ if (found) return found;
2327
+ }
2328
+ return null;
2329
+ };
2330
+ var updateTaskInTree = (tasks, id, updates) => {
2331
+ return tasks.map((task) => {
2332
+ if (task.id === id) {
2333
+ return { ...task, ...updates, updatedAt: /* @__PURE__ */ new Date() };
2334
+ }
2335
+ return {
2336
+ ...task,
2337
+ children: updateTaskInTree(task.children, id, updates)
2338
+ };
2339
+ });
2340
+ };
2341
+ var deleteTaskFromTree = (tasks, id) => {
2342
+ return tasks.filter((task) => task.id !== id).map((task) => ({
2343
+ ...task,
2344
+ children: deleteTaskFromTree(task.children, id)
2345
+ }));
2346
+ };
2347
+ var addSubtaskToTree = (tasks, parentId, newTask) => {
2348
+ return tasks.map((task) => {
2349
+ if (task.id === parentId) {
2350
+ return {
2351
+ ...task,
2352
+ children: [...task.children, newTask]
2353
+ };
2354
+ }
2355
+ return {
2356
+ ...task,
2357
+ children: addSubtaskToTree(task.children, parentId, newTask)
2358
+ };
2359
+ });
2360
+ };
2361
+ var flattenTasks = (tasks) => {
2362
+ const result = [];
2363
+ const traverse = (taskList) => {
2364
+ for (const task of taskList) {
2365
+ result.push(task);
2366
+ traverse(task.children);
2367
+ }
2368
+ };
2369
+ traverse(tasks);
2370
+ return result;
2371
+ };
2372
+ var getTaskStats = (tasks) => {
2373
+ const flat = flattenTasks(tasks);
2374
+ const total = flat.length;
2375
+ const completed = flat.filter((t) => t.state === "completed").length;
2376
+ return {
2377
+ total,
2378
+ completed,
2379
+ percentage: total === 0 ? 0 : Math.round(completed / total * 100)
2380
+ };
2381
+ };
2382
+
2383
+ // src/utils/validation.ts
2384
+ var validateTaskTimes = (task) => {
2385
+ if (task.startTime && task.endTime) {
2386
+ if (task.startTime >= task.endTime) {
2387
+ return {
2388
+ valid: false,
2389
+ error: "Start time must be before end time"
2390
+ };
2391
+ }
2392
+ }
2393
+ if (task.startTime && !task.endTime) {
2394
+ if (task.startTime > /* @__PURE__ */ new Date()) {
2395
+ return {
2396
+ valid: false,
2397
+ error: "Start time cannot be in the future"
2398
+ };
2399
+ }
2400
+ }
2401
+ return { valid: true };
2402
+ };
2403
+ var validateTaskTitle = (title) => {
2404
+ if (!title || title.trim().length === 0) {
2405
+ return {
2406
+ valid: false,
2407
+ error: "Task title cannot be empty"
2408
+ };
2409
+ }
2410
+ if (title.length > 255) {
2411
+ return {
2412
+ valid: false,
2413
+ error: "Task title is too long (max 255 characters)"
2414
+ };
2415
+ }
2416
+ return { valid: true };
2417
+ };
2418
+
2419
+ // src/services/taskService.ts
2420
+ var TaskService = class {
2421
+ createTask(title, date, state = "todo") {
2422
+ const validation = validateTaskTitle(title);
2423
+ if (!validation.valid) {
2424
+ throw new Error(validation.error);
2425
+ }
2426
+ const now = /* @__PURE__ */ new Date();
2427
+ return {
2428
+ id: uuid(),
2429
+ title,
2430
+ state,
2431
+ createdAt: now,
2432
+ updatedAt: now,
2433
+ children: [],
2434
+ date
2435
+ };
2436
+ }
2437
+ updateTask(tasks, taskId, updates) {
2438
+ const dateStr = Object.keys(tasks).find(
2439
+ (date) => findTaskById(tasks[date], taskId)
2440
+ );
2441
+ if (!dateStr) {
2442
+ throw new Error("Task not found");
2443
+ }
2444
+ if (updates.title) {
2445
+ const validation = validateTaskTitle(updates.title);
2446
+ if (!validation.valid) {
2447
+ throw new Error(validation.error);
2448
+ }
2449
+ }
2450
+ if (updates.startTime || updates.endTime) {
2451
+ const task = findTaskById(tasks[dateStr], taskId);
2452
+ if (task) {
2453
+ const updated = { ...task, ...updates };
2454
+ const validation = validateTaskTimes(updated);
2455
+ if (!validation.valid) {
2456
+ throw new Error(validation.error);
2457
+ }
2458
+ }
2459
+ }
2460
+ return {
2461
+ ...tasks,
2462
+ [dateStr]: updateTaskInTree(tasks[dateStr], taskId, {
2463
+ ...updates,
2464
+ updatedAt: /* @__PURE__ */ new Date()
2465
+ })
2466
+ };
2467
+ }
2468
+ deleteTask(tasks, taskId) {
2469
+ const dateStr = Object.keys(tasks).find(
2470
+ (date) => findTaskById(tasks[date], taskId)
2471
+ );
2472
+ if (!dateStr) {
2473
+ throw new Error("Task not found");
2474
+ }
2475
+ return {
2476
+ ...tasks,
2477
+ [dateStr]: deleteTaskFromTree(tasks[dateStr], taskId)
2478
+ };
2479
+ }
2480
+ addSubtask(tasks, parentId, title) {
2481
+ const parentTask = Object.values(tasks).flat().find((t) => findTaskById([t], parentId));
2482
+ if (!parentTask) {
2483
+ throw new Error("Parent task not found");
2484
+ }
2485
+ const newSubtask = this.createTask(title, parentTask.date);
2486
+ const dateStr = Object.keys(tasks).find(
2487
+ (date) => findTaskById(tasks[date], parentId)
2488
+ );
2489
+ if (!dateStr) {
2490
+ throw new Error("Parent task not found");
2491
+ }
2492
+ return {
2493
+ ...tasks,
2494
+ [dateStr]: addSubtaskToTree(tasks[dateStr], parentId, {
2495
+ ...newSubtask,
2496
+ parentId
2497
+ })
2498
+ };
2499
+ }
2500
+ changeTaskState(tasks, taskId, newState) {
2501
+ return this.updateTask(tasks, taskId, {
2502
+ state: newState,
2503
+ endTime: ["completed", "delegated", "delayed"].includes(newState) ? /* @__PURE__ */ new Date() : void 0
2504
+ });
2505
+ }
2506
+ startTask(tasks, taskId, startTime) {
2507
+ return this.updateTask(tasks, taskId, {
2508
+ startTime: startTime || /* @__PURE__ */ new Date(),
2509
+ endTime: void 0,
2510
+ state: "todo"
2511
+ // Reset to todo when starting
2512
+ });
2513
+ }
2514
+ getTasksForDate(tasks, date) {
2515
+ return tasks[date] || [];
2516
+ }
2517
+ getAllTasks(tasks) {
2518
+ return Object.values(tasks).flat();
2519
+ }
2520
+ getTaskStats(tasks, date) {
2521
+ return getTaskStats(this.getTasksForDate(tasks, date));
2522
+ }
2523
+ };
2524
+ var taskService = new TaskService();
2525
+
2526
+ // src/services/timelineService.ts
2527
+ import { v4 as uuid2 } from "uuid";
2528
+ var TimelineService = class {
2529
+ createEvent(taskId, taskTitle, eventType, timestamp = /* @__PURE__ */ new Date(), previousState, newState) {
2530
+ return {
2531
+ id: uuid2(),
2532
+ taskId,
2533
+ taskTitle,
2534
+ type: eventType,
2535
+ timestamp,
2536
+ previousState,
2537
+ newState
2538
+ };
2539
+ }
2540
+ getEventsForDate(timeline, date) {
2541
+ return timeline[date] || [];
2542
+ }
2543
+ addEvent(timeline, event) {
2544
+ const dateStr = getDateString(event.timestamp);
2545
+ return {
2546
+ ...timeline,
2547
+ [dateStr]: [...timeline[dateStr] || [], event]
2548
+ };
2549
+ }
2550
+ // Remove all events for a specific task (used when deleting a task)
2551
+ removeEventsByTaskId(timeline, taskId) {
2552
+ const result = {};
2553
+ for (const [date, events] of Object.entries(timeline)) {
2554
+ const filtered = events.filter((e) => e.taskId !== taskId);
2555
+ if (filtered.length > 0) {
2556
+ result[date] = filtered;
2557
+ }
2558
+ }
2559
+ return result;
2560
+ }
2561
+ // Remove the last event of a specific type for a task (used for undo operations)
2562
+ removeLastEventByType(timeline, taskId, eventType) {
2563
+ const result = {};
2564
+ let removed = false;
2565
+ const dates = Object.keys(timeline).sort().reverse();
2566
+ for (const date of dates) {
2567
+ const events = timeline[date];
2568
+ if (!removed) {
2569
+ const lastIndex = events.map((e, i) => ({ e, i })).filter(({ e }) => e.taskId === taskId && e.type === eventType).pop()?.i;
2570
+ if (lastIndex !== void 0) {
2571
+ const filtered = events.filter((_, i) => i !== lastIndex);
2572
+ if (filtered.length > 0) {
2573
+ result[date] = filtered;
2574
+ }
2575
+ removed = true;
2576
+ } else {
2577
+ result[date] = events;
2578
+ }
2579
+ } else {
2580
+ result[date] = events;
2581
+ }
2582
+ }
2583
+ return result;
2584
+ }
2585
+ formatEventDescription(event) {
2586
+ const timeStr = event.timestamp.toLocaleTimeString("en-US", {
2587
+ hour: "2-digit",
2588
+ minute: "2-digit",
2589
+ hour12: true
2590
+ });
2591
+ const stateInfo = event.newState ? ` (${event.previousState} -> ${event.newState})` : "";
2592
+ return `${timeStr} - ${event.type.charAt(0).toUpperCase() + event.type.slice(1)}: ${event.taskTitle}${stateInfo}`;
2593
+ }
2594
+ };
2595
+ var timelineService = new TimelineService();
2596
+
2597
+ // src/components/tasks/TasksPane.tsx
2598
+ import { Fragment, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
2599
+ var TasksPane = () => {
2600
+ const {
2601
+ tasks,
2602
+ setTasks,
2603
+ timeline,
2604
+ setTimeline,
2605
+ activePane,
2606
+ selectedDate,
2607
+ isInputMode,
2608
+ setIsInputMode,
2609
+ isModalOpen
2610
+ } = useApp();
2611
+ const { theme } = useTheme();
2612
+ const [expandedIds, setExpandedIds] = useState6(/* @__PURE__ */ new Set());
2613
+ const [selectedIndex, setSelectedIndex] = useState6(0);
2614
+ const [editMode, setEditMode] = useState6("none");
2615
+ const [editValue, setEditValue] = useState6("");
2616
+ const [parentTaskId, setParentTaskId] = useState6(null);
2617
+ const inputValueRef = useRef3("");
2618
+ const [inputKey, setInputKey] = useState6(0);
2619
+ const [scrollOffset, setScrollOffset] = useState6(0);
2620
+ const { height: terminalHeight } = useTerminalSize();
2621
+ const visibleRows = useMemo(() => {
2622
+ return Math.max(5, terminalHeight - 11);
2623
+ }, [terminalHeight]);
2624
+ const dateStr = getDateString(
2625
+ new Date(selectedDate.year, selectedDate.month, selectedDate.day)
2626
+ );
2627
+ const dayTasks = tasks[dateStr] || [];
2628
+ const stats = taskService.getTaskStats(tasks, dateStr);
2629
+ const isFocused = activePane === "tasks" && !isModalOpen;
2630
+ const flatTasks = useMemo(() => {
2631
+ const result = [];
2632
+ const traverse = (taskList, depth) => {
2633
+ for (const task of taskList) {
2634
+ result.push({ task, depth });
2635
+ if (task.children.length > 0 && expandedIds.has(task.id)) {
2636
+ traverse(task.children, depth + 1);
2637
+ }
2638
+ }
2639
+ };
2640
+ traverse(dayTasks, 0);
2641
+ return result;
2642
+ }, [dayTasks, expandedIds]);
2643
+ const selectedTask = flatTasks[selectedIndex]?.task;
2644
+ const selectedTaskId = selectedTask?.id;
2645
+ useEffect7(() => {
2646
+ setSelectedIndex(0);
2647
+ setEditMode("none");
2648
+ }, [dateStr]);
2649
+ useEffect7(() => {
2650
+ if (selectedIndex >= flatTasks.length && flatTasks.length > 0) {
2651
+ setSelectedIndex(flatTasks.length - 1);
2652
+ }
2653
+ }, [flatTasks.length, selectedIndex]);
2654
+ useEffect7(() => {
2655
+ if (selectedIndex < scrollOffset) {
2656
+ setScrollOffset(selectedIndex);
2657
+ } else if (selectedIndex >= scrollOffset + visibleRows) {
2658
+ setScrollOffset(selectedIndex - visibleRows + 1);
2659
+ }
2660
+ }, [selectedIndex, visibleRows, scrollOffset]);
2661
+ useEffect7(() => {
2662
+ setScrollOffset(0);
2663
+ }, [dateStr]);
2664
+ const handleAddTask = () => {
2665
+ inputValueRef.current = "";
2666
+ setEditMode("add");
2667
+ setEditValue("");
2668
+ setInputKey((k) => k + 1);
2669
+ setIsInputMode(true);
2670
+ };
2671
+ const handleEditTask = () => {
2672
+ if (selectedTask) {
2673
+ inputValueRef.current = selectedTask.title;
2674
+ setEditMode("edit");
2675
+ setEditValue(selectedTask.title);
2676
+ setInputKey((k) => k + 1);
2677
+ setIsInputMode(true);
2678
+ }
2679
+ };
2680
+ const handleAddSubtask = () => {
2681
+ if (selectedTask) {
2682
+ inputValueRef.current = "";
2683
+ setEditMode("addSubtask");
2684
+ setEditValue("");
2685
+ setParentTaskId(selectedTask.id);
2686
+ setInputKey((k) => k + 1);
2687
+ setIsInputMode(true);
2688
+ setExpandedIds((prev) => new Set(prev).add(selectedTask.id));
2689
+ }
2690
+ };
2691
+ const handleDeleteTask = () => {
2692
+ if (selectedTaskId) {
2693
+ try {
2694
+ const updated = taskService.deleteTask(tasks, selectedTaskId);
2695
+ setTasks(updated);
2696
+ const updatedTimeline = timelineService.removeEventsByTaskId(
2697
+ timeline,
2698
+ selectedTaskId
2699
+ );
2700
+ setTimeline(updatedTimeline);
2701
+ } catch (err) {
2702
+ console.error("Error deleting task:", err);
2703
+ }
2704
+ }
2705
+ };
2706
+ const handleChangeState = (newState) => {
2707
+ if (selectedTaskId && selectedTask) {
2708
+ try {
2709
+ const previousState = selectedTask.state;
2710
+ const updated = taskService.changeTaskState(
2711
+ tasks,
2712
+ selectedTaskId,
2713
+ newState
2714
+ );
2715
+ setTasks(updated);
2716
+ if (newState === "todo") {
2717
+ const eventTypeToRemove = {
2718
+ todo: "started" /* STARTED */,
2719
+ // shouldn't happen
2720
+ completed: "completed" /* COMPLETED */,
2721
+ delegated: "delegated" /* DELEGATED */,
2722
+ delayed: "delayed" /* DELAYED */
2723
+ };
2724
+ const updatedTimeline = timelineService.removeLastEventByType(
2725
+ timeline,
2726
+ selectedTaskId,
2727
+ eventTypeToRemove[previousState]
2728
+ );
2729
+ setTimeline(updatedTimeline);
2730
+ } else {
2731
+ const eventTypeMap = {
2732
+ todo: "started" /* STARTED */,
2733
+ // shouldn't happen
2734
+ completed: "completed" /* COMPLETED */,
2735
+ delegated: "delegated" /* DELEGATED */,
2736
+ delayed: "delayed" /* DELAYED */
2737
+ };
2738
+ const event = timelineService.createEvent(
2739
+ selectedTaskId,
2740
+ selectedTask.title,
2741
+ eventTypeMap[newState],
2742
+ /* @__PURE__ */ new Date(),
2743
+ previousState,
2744
+ newState
2745
+ );
2746
+ const updatedTimeline = timelineService.addEvent(timeline, event);
2747
+ setTimeline(updatedTimeline);
2748
+ }
2749
+ } catch (err) {
2750
+ console.error("Error changing task state:", err);
2751
+ }
2752
+ }
2753
+ };
2754
+ const handleToggleComplete = () => {
2755
+ if (selectedTask) {
2756
+ const newState = selectedTask.state === "completed" ? "todo" : "completed";
2757
+ handleChangeState(newState);
2758
+ }
2759
+ };
2760
+ const handleSubmitEdit = (value) => {
2761
+ const trimmed = value.trim();
2762
+ if (!trimmed) {
2763
+ setEditMode("none");
2764
+ setEditValue("");
2765
+ setParentTaskId(null);
2766
+ setIsInputMode(false);
2767
+ return;
2768
+ }
2769
+ try {
2770
+ if (editMode === "add") {
2771
+ const newTask = taskService.createTask(trimmed, dateStr);
2772
+ const newTasks = {
2773
+ ...tasks,
2774
+ [dateStr]: [...dayTasks, newTask]
2775
+ };
2776
+ setTasks(newTasks);
2777
+ setSelectedIndex(flatTasks.length);
2778
+ } else if (editMode === "addSubtask" && parentTaskId) {
2779
+ const updated = taskService.addSubtask(tasks, parentTaskId, trimmed);
2780
+ setTasks(updated);
2781
+ const parentIndex = flatTasks.findIndex(
2782
+ (ft) => ft.task.id === parentTaskId
2783
+ );
2784
+ if (parentIndex !== -1) {
2785
+ setSelectedIndex(parentIndex + 1);
2786
+ }
2787
+ } else if (editMode === "edit" && selectedTaskId) {
2788
+ const updated = taskService.updateTask(tasks, selectedTaskId, {
2789
+ title: trimmed
2790
+ });
2791
+ setTasks(updated);
2792
+ }
2793
+ } catch (err) {
2794
+ console.error("Error saving task:", err);
2795
+ }
2796
+ setEditMode("none");
2797
+ setEditValue("");
2798
+ setParentTaskId(null);
2799
+ setIsInputMode(false);
2800
+ };
2801
+ const handleCancelEdit = () => {
2802
+ setEditMode("none");
2803
+ setEditValue("");
2804
+ setParentTaskId(null);
2805
+ setIsInputMode(false);
2806
+ };
2807
+ const handleToggleExpand = () => {
2808
+ if (selectedTaskId && selectedTask?.children.length > 0) {
2809
+ setExpandedIds((prev) => {
2810
+ const newSet = new Set(prev);
2811
+ if (newSet.has(selectedTaskId)) {
2812
+ newSet.delete(selectedTaskId);
2813
+ } else {
2814
+ newSet.add(selectedTaskId);
2815
+ }
2816
+ return newSet;
2817
+ });
2818
+ }
2819
+ };
2820
+ const handleExpand = () => {
2821
+ if (selectedTaskId && selectedTask?.children.length > 0) {
2822
+ setExpandedIds((prev) => new Set(prev).add(selectedTaskId));
2823
+ }
2824
+ };
2825
+ const handleCollapse = () => {
2826
+ if (selectedTaskId && selectedTask?.children.length > 0) {
2827
+ setExpandedIds((prev) => {
2828
+ const newSet = new Set(prev);
2829
+ newSet.delete(selectedTaskId);
2830
+ return newSet;
2831
+ });
2832
+ }
2833
+ };
2834
+ const handleExpandAll = () => {
2835
+ const allParentIds = /* @__PURE__ */ new Set();
2836
+ const collectParents = (taskList) => {
2837
+ for (const task of taskList) {
2838
+ if (task.children.length > 0) {
2839
+ allParentIds.add(task.id);
2840
+ collectParents(task.children);
2841
+ }
2842
+ }
2843
+ };
2844
+ collectParents(dayTasks);
2845
+ setExpandedIds(allParentIds);
2846
+ };
2847
+ const handleCollapseAll = () => {
2848
+ setExpandedIds(/* @__PURE__ */ new Set());
2849
+ };
2850
+ useInput3(
2851
+ (_input, key) => {
2852
+ if (key.escape) {
2853
+ handleCancelEdit();
2854
+ }
2855
+ },
2856
+ { isActive: isFocused && editMode !== "none" }
2857
+ );
2858
+ useInput3(
2859
+ (input, key) => {
2860
+ if ((key.meta || key.ctrl) && (input === "a" || key.leftArrow)) {
2861
+ handleCollapseAll();
2862
+ return;
2863
+ }
2864
+ if ((key.meta || key.ctrl) && (input === "e" || key.rightArrow)) {
2865
+ handleExpandAll();
2866
+ return;
2867
+ }
2868
+ if (input === "j" || key.downArrow) {
2869
+ setSelectedIndex((prev) => Math.min(prev + 1, flatTasks.length - 1));
2870
+ return;
2871
+ }
2872
+ if (input === "k" || key.upArrow) {
2873
+ setSelectedIndex((prev) => Math.max(prev - 1, 0));
2874
+ return;
2875
+ }
2876
+ if (key.leftArrow && !key.meta && !key.ctrl) {
2877
+ handleCollapse();
2878
+ return;
2879
+ }
2880
+ if (key.rightArrow && !key.meta && !key.ctrl) {
2881
+ handleExpand();
2882
+ return;
2883
+ }
2884
+ if (input === "a" && !key.meta && !key.ctrl && !key.shift) {
2885
+ handleAddTask();
2886
+ return;
2887
+ }
2888
+ if (input === "e" && selectedTask && !key.meta && !key.ctrl && !key.shift) {
2889
+ handleEditTask();
2890
+ return;
2891
+ }
2892
+ if (input === "d" && selectedTask) {
2893
+ handleDeleteTask();
2894
+ return;
2895
+ }
2896
+ if (input === " " && selectedTask) {
2897
+ handleToggleComplete();
2898
+ return;
2899
+ }
2900
+ if (input === "D" && selectedTask) {
2901
+ handleChangeState("delegated");
2902
+ return;
2903
+ }
2904
+ if (input === "x" && selectedTask) {
2905
+ if (selectedTask.state === "delayed") {
2906
+ handleChangeState("todo");
2907
+ } else {
2908
+ handleChangeState("delayed");
2909
+ }
2910
+ return;
2911
+ }
2912
+ if (input === "s" && selectedTask) {
2913
+ try {
2914
+ if (selectedTask.startTime && !selectedTask.endTime) {
2915
+ const updated = taskService.updateTask(tasks, selectedTaskId, {
2916
+ startTime: void 0
2917
+ });
2918
+ setTasks(updated);
2919
+ const updatedTimeline = timelineService.removeLastEventByType(
2920
+ timeline,
2921
+ selectedTaskId,
2922
+ "started" /* STARTED */
2923
+ );
2924
+ setTimeline(updatedTimeline);
2925
+ } else {
2926
+ const updated = taskService.startTask(tasks, selectedTaskId);
2927
+ setTasks(updated);
2928
+ const event = timelineService.createEvent(
2929
+ selectedTaskId,
2930
+ selectedTask.title,
2931
+ "started" /* STARTED */,
2932
+ /* @__PURE__ */ new Date()
2933
+ );
2934
+ const updatedTimeline = timelineService.addEvent(timeline, event);
2935
+ setTimeline(updatedTimeline);
2936
+ }
2937
+ } catch (err) {
2938
+ console.error("Error toggling task start:", err);
2939
+ }
2940
+ return;
2941
+ }
2942
+ if (key.return && selectedTask) {
2943
+ handleToggleExpand();
2944
+ return;
2945
+ }
2946
+ if (key.tab && selectedTask) {
2947
+ handleAddSubtask();
2948
+ return;
2949
+ }
2950
+ },
2951
+ { isActive: isFocused && editMode === "none" }
2952
+ );
2953
+ return /* @__PURE__ */ jsx11(Pane, { title: "Tasks", isFocused, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", flexGrow: 1, children: [
2954
+ /* @__PURE__ */ jsx11(
2955
+ TaskHeader,
2956
+ {
2957
+ selectedDate: new Date(selectedDate.year, selectedDate.month, selectedDate.day),
2958
+ completionPercentage: stats.percentage
2959
+ }
2960
+ ),
2961
+ editMode === "add" && /* @__PURE__ */ jsxs7(Box7, { marginY: 1, children: [
2962
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.focusIndicator, children: "> " }),
2963
+ /* @__PURE__ */ jsx11(
2964
+ TextInput,
2965
+ {
2966
+ defaultValue: "",
2967
+ placeholder: "Enter task name...",
2968
+ onChange: (val) => {
2969
+ inputValueRef.current = val;
2970
+ },
2971
+ onSubmit: handleSubmitEdit
2972
+ },
2973
+ `add-${inputKey}`
2974
+ )
2975
+ ] }),
2976
+ editMode === "addSubtask" && /* @__PURE__ */ jsxs7(Box7, { marginY: 1, children: [
2977
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.focusIndicator, children: "> " }),
2978
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, children: " " }),
2979
+ /* @__PURE__ */ jsx11(
2980
+ TextInput,
2981
+ {
2982
+ defaultValue: "",
2983
+ placeholder: "Enter subtask name...",
2984
+ onChange: (val) => {
2985
+ inputValueRef.current = val;
2986
+ },
2987
+ onSubmit: handleSubmitEdit
2988
+ },
2989
+ `subtask-${inputKey}`
2990
+ )
2991
+ ] }),
2992
+ dayTasks.length === 0 && editMode !== "add" && editMode !== "addSubtask" ? /* @__PURE__ */ jsx11(Box7, { marginY: 1, children: /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "No tasks. Press 'a' to add one." }) }) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginY: 1, paddingRight: 2, children: [
2993
+ scrollOffset > 0 && /* @__PURE__ */ jsx11(Box7, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
2994
+ flatTasks.slice(scrollOffset, scrollOffset + visibleRows).map(({ task, depth }, sliceIndex) => {
2995
+ const index = scrollOffset + sliceIndex;
2996
+ const isSelected = index === selectedIndex;
2997
+ const isExpanded = expandedIds.has(task.id);
2998
+ const isEditing = editMode === "edit" && isSelected;
2999
+ if (isEditing) {
3000
+ return /* @__PURE__ */ jsxs7(Box7, { children: [
3001
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.focusIndicator, children: "> " }),
3002
+ /* @__PURE__ */ jsx11(
3003
+ TextInput,
3004
+ {
3005
+ defaultValue: editValue,
3006
+ onChange: (val) => {
3007
+ inputValueRef.current = val;
3008
+ },
3009
+ onSubmit: handleSubmitEdit
3010
+ },
3011
+ `edit-${inputKey}`
3012
+ )
3013
+ ] }, task.id);
3014
+ }
3015
+ return /* @__PURE__ */ jsxs7(Box7, { children: [
3016
+ /* @__PURE__ */ jsx11(
3017
+ Text5,
3018
+ {
3019
+ color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
3020
+ children: isSelected ? ">" : " "
3021
+ }
3022
+ ),
3023
+ /* @__PURE__ */ jsx11(Text5, { children: " " }),
3024
+ /* @__PURE__ */ jsx11(Text5, { children: " ".repeat(depth) }),
3025
+ /* @__PURE__ */ jsx11(
3026
+ Text5,
3027
+ {
3028
+ color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
3029
+ children: getCheckbox(task.state)
3030
+ }
3031
+ ),
3032
+ /* @__PURE__ */ jsx11(Text5, { children: " " }),
3033
+ task.children.length > 0 && /* @__PURE__ */ jsxs7(Fragment, { children: [
3034
+ /* @__PURE__ */ jsx11(Text5, { children: isExpanded ? "\u25BC" : "\u25B6" }),
3035
+ /* @__PURE__ */ jsx11(Text5, { children: " " })
3036
+ ] }),
3037
+ /* @__PURE__ */ jsx11(
3038
+ Text5,
3039
+ {
3040
+ color: isSelected ? theme.colors.focusIndicator : getStateColor(task.state, theme),
3041
+ strikethrough: task.state === "completed",
3042
+ dimColor: task.state === "delayed" && !isSelected,
3043
+ children: task.title
3044
+ }
3045
+ ),
3046
+ task.startTime && !task.endTime && /* @__PURE__ */ jsxs7(
3047
+ Text5,
3048
+ {
3049
+ color: isSelected ? theme.colors.focusIndicator : theme.colors.timelineEventStarted,
3050
+ children: [
3051
+ " ",
3052
+ "\u25B6"
3053
+ ]
3054
+ }
3055
+ )
3056
+ ] }, task.id);
3057
+ }),
3058
+ scrollOffset + visibleRows < flatTasks.length && /* @__PURE__ */ jsx11(Box7, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
3059
+ ] }),
3060
+ /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
3061
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "j/k: navigate a: add Tab: add subtask e: edit d: delete" }),
3062
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "Space: complete D: delegate x: delay s: start" }),
3063
+ /* @__PURE__ */ jsx11(Text5, { color: theme.colors.keyboardHint, dimColor: true, children: "\u2190/\u2192: collapse/expand Cmd+\u2190/\u2192: collapse/expand all" })
3064
+ ] })
3065
+ ] }) });
3066
+ };
3067
+ function getCheckbox(state) {
3068
+ switch (state) {
3069
+ case "completed":
3070
+ return "[\u2713]";
3071
+ case "delegated":
3072
+ return "[\u2192]";
3073
+ case "delayed":
3074
+ return "[\u2016]";
3075
+ default:
3076
+ return "[ ]";
3077
+ }
3078
+ }
3079
+ function getStateColor(state, theme) {
3080
+ const colors = {
3081
+ todo: theme.colors.taskStateTodo,
3082
+ completed: theme.colors.taskStateCompleted,
3083
+ delegated: theme.colors.taskStateDelegated,
3084
+ delayed: theme.colors.taskStateDelayed
3085
+ };
3086
+ return colors[state] || theme.colors.foreground;
3087
+ }
3088
+
3089
+ // src/components/timeline/TimelinePane.tsx
3090
+ import { useState as useState7, useEffect as useEffect8, useMemo as useMemo2 } from "react";
3091
+ import { Box as Box9, Text as Text7, useInput as useInput4 } from "ink";
3092
+
3093
+ // src/components/timeline/TimelineEntry.tsx
3094
+ import { Box as Box8, Text as Text6 } from "ink";
3095
+ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
3096
+ var TimelineEntry = ({
3097
+ event,
3098
+ isLast,
3099
+ hasNextSameTask
3100
+ }) => {
3101
+ const { theme } = useTheme();
3102
+ const hours = event.timestamp.getHours();
3103
+ const minutes = event.timestamp.getMinutes();
3104
+ const ampm = hours >= 12 ? "pm" : "am";
3105
+ const hour12 = hours % 12 || 12;
3106
+ const timeStr = `${hour12}:${minutes.toString().padStart(2, "0")} ${ampm}`;
3107
+ const typeStr = event.type.charAt(0).toUpperCase() + event.type.slice(1);
3108
+ const eventTypeColors = {
3109
+ created: theme.colors.foreground,
3110
+ started: theme.colors.foreground,
3111
+ completed: theme.colors.taskStateCompleted,
3112
+ delegated: theme.colors.taskStateDelegated,
3113
+ delayed: theme.colors.taskStateDelayed,
3114
+ updated: theme.colors.foreground
3115
+ };
3116
+ const color = eventTypeColors[event.type] || theme.colors.foreground;
3117
+ const isFilledCircle = ["completed", "delegated", "delayed"].includes(
3118
+ event.type
3119
+ );
3120
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
3121
+ /* @__PURE__ */ jsxs8(Box8, { children: [
3122
+ /* @__PURE__ */ jsx12(Box8, { width: 3, justifyContent: "center", children: /* @__PURE__ */ jsx12(Text6, { color, children: isFilledCircle ? "\u25CF" : "\u25CB" }) }),
3123
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", flexGrow: 1, children: [
3124
+ /* @__PURE__ */ jsx12(Box8, { children: /* @__PURE__ */ jsxs8(Text6, { children: [
3125
+ /* @__PURE__ */ jsxs8(Text6, { color, bold: true, children: [
3126
+ typeStr,
3127
+ ":"
3128
+ ] }),
3129
+ /* @__PURE__ */ jsxs8(Text6, { color: theme.colors.foreground, children: [
3130
+ " ",
3131
+ event.taskTitle
3132
+ ] })
3133
+ ] }) }),
3134
+ /* @__PURE__ */ jsx12(Box8, { children: /* @__PURE__ */ jsx12(Text6, { color: theme.colors.keyboardHint, dimColor: true, children: timeStr }) })
3135
+ ] })
3136
+ ] }),
3137
+ !isLast && /* @__PURE__ */ jsx12(Box8, { children: /* @__PURE__ */ jsx12(Box8, { width: 3, justifyContent: "center", children: /* @__PURE__ */ jsx12(Text6, { color: hasNextSameTask ? color : theme.colors.border, children: "\u2502" }) }) })
3138
+ ] });
3139
+ };
3140
+
3141
+ // src/components/timeline/TimelinePane.tsx
3142
+ import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3143
+ var TimelinePane = () => {
3144
+ const { theme } = useTheme();
3145
+ const { selectedDate, timeline, activePane, isModalOpen, isInputMode } = useApp();
3146
+ const isFocused = activePane === "timeline" && !isModalOpen;
3147
+ const [scrollOffset, setScrollOffset] = useState7(0);
3148
+ const { height: terminalHeight } = useTerminalSize();
3149
+ const visibleRows = useMemo2(() => {
3150
+ return Math.max(5, terminalHeight - 10);
3151
+ }, [terminalHeight]);
3152
+ const dateStr = getDateString(
3153
+ new Date(selectedDate.year, selectedDate.month, selectedDate.day)
3154
+ );
3155
+ const dayEvents = timeline[dateStr] || [];
3156
+ const sortedEvents = useMemo2(() => {
3157
+ const eventsByTask = /* @__PURE__ */ new Map();
3158
+ dayEvents.forEach((event) => {
3159
+ const taskEvents = eventsByTask.get(event.taskId) || [];
3160
+ taskEvents.push(event);
3161
+ eventsByTask.set(event.taskId, taskEvents);
3162
+ });
3163
+ eventsByTask.forEach((events) => {
3164
+ events.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
3165
+ });
3166
+ const taskGroups = Array.from(eventsByTask.entries()).sort(
3167
+ ([, eventsA], [, eventsB]) => {
3168
+ const earliestA = eventsA[0]?.timestamp.getTime() || 0;
3169
+ const earliestB = eventsB[0]?.timestamp.getTime() || 0;
3170
+ return earliestA - earliestB;
3171
+ }
3172
+ );
3173
+ return taskGroups.flatMap(([, events]) => events);
3174
+ }, [dayEvents]);
3175
+ useEffect8(() => {
3176
+ setScrollOffset(0);
3177
+ }, [dateStr]);
3178
+ useInput4(
3179
+ (input, key) => {
3180
+ if (!isFocused) return;
3181
+ if (input === "j" || key.downArrow) {
3182
+ setScrollOffset(
3183
+ (prev) => Math.min(prev + 1, Math.max(0, sortedEvents.length - visibleRows))
3184
+ );
3185
+ }
3186
+ if (input === "k" || key.upArrow) {
3187
+ setScrollOffset((prev) => Math.max(prev - 1, 0));
3188
+ }
3189
+ if (input === "d" && key.ctrl) {
3190
+ setScrollOffset(
3191
+ (prev) => Math.min(
3192
+ prev + Math.floor(visibleRows / 2),
3193
+ Math.max(0, sortedEvents.length - visibleRows)
3194
+ )
3195
+ );
3196
+ }
3197
+ if (input === "u" && key.ctrl) {
3198
+ setScrollOffset(
3199
+ (prev) => Math.max(prev - Math.floor(visibleRows / 2), 0)
3200
+ );
3201
+ }
3202
+ },
3203
+ { isActive: isFocused && !isInputMode }
3204
+ );
3205
+ const visibleEvents = sortedEvents.slice(
3206
+ scrollOffset,
3207
+ scrollOffset + visibleRows
3208
+ );
3209
+ const canScrollUp = scrollOffset > 0;
3210
+ const canScrollDown = scrollOffset + visibleRows < sortedEvents.length;
3211
+ return /* @__PURE__ */ jsx13(Pane, { title: "Timeline", isFocused, children: /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", flexGrow: 1, children: [
3212
+ sortedEvents.length === 0 ? /* @__PURE__ */ jsxs9(Box9, { marginY: 1, flexDirection: "column", paddingX: 1, children: [
3213
+ /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "No activities yet." }),
3214
+ /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "Press 's' to start a task." })
3215
+ ] }) : /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
3216
+ canScrollUp && /* @__PURE__ */ jsx13(Box9, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
3217
+ /* @__PURE__ */ jsx13(Box9, { flexDirection: "column", children: visibleEvents.map((event, index) => {
3218
+ const globalIndex = scrollOffset + index;
3219
+ const isLast = globalIndex === sortedEvents.length - 1;
3220
+ const nextEvent = sortedEvents[globalIndex + 1];
3221
+ const hasNextSameTask = nextEvent && nextEvent.taskId === event.taskId;
3222
+ return /* @__PURE__ */ jsx13(
3223
+ TimelineEntry,
3224
+ {
3225
+ event,
3226
+ isLast,
3227
+ hasNextSameTask
3228
+ },
3229
+ event.id
3230
+ );
3231
+ }) }),
3232
+ canScrollDown && /* @__PURE__ */ jsx13(Box9, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
3233
+ ] }),
3234
+ /* @__PURE__ */ jsx13(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text7, { color: theme.colors.keyboardHint, dimColor: true, children: "j/k: scroll" }) })
3235
+ ] }) });
3236
+ };
3237
+
3238
+ // src/components/common/HelpDialog.tsx
3239
+ import { Box as Box12, Text as Text8 } from "ink";
3240
+
3241
+ // src/components/common/Modal.tsx
3242
+ import { Box as Box11, useStdout as useStdout3 } from "ink";
3243
+
3244
+ // src/components/common/FullscreenBackground.tsx
3245
+ import { Box as Box10, useStdout as useStdout2 } from "ink";
3246
+ import { jsx as jsx14 } from "react/jsx-runtime";
3247
+ var FullscreenBackground = ({
3248
+ children,
3249
+ backgroundColor
3250
+ }) => {
3251
+ const { stdout } = useStdout2();
3252
+ const width = stdout?.columns || 100;
3253
+ const height = stdout?.rows || 30;
3254
+ return /* @__PURE__ */ jsx14(
3255
+ Box10,
3256
+ {
3257
+ flexDirection: "column",
3258
+ width,
3259
+ height,
3260
+ backgroundColor,
3261
+ children
3262
+ }
3263
+ );
3264
+ };
3265
+
3266
+ // src/components/common/Modal.tsx
3267
+ import { jsx as jsx15 } from "react/jsx-runtime";
3268
+ var Modal = ({ children }) => {
3269
+ const { theme } = useTheme();
3270
+ const { stdout } = useStdout3();
3271
+ const width = stdout?.columns || 100;
3272
+ const height = stdout?.rows || 30;
3273
+ return /* @__PURE__ */ jsx15(
3274
+ FullscreenBackground,
3275
+ {
3276
+ backgroundColor: theme.colors.modalOverlay || "black",
3277
+ children: /* @__PURE__ */ jsx15(
3278
+ Box11,
3279
+ {
3280
+ flexDirection: "column",
3281
+ width,
3282
+ height,
3283
+ justifyContent: "center",
3284
+ alignItems: "center",
3285
+ children
3286
+ }
3287
+ )
3288
+ }
3289
+ );
3290
+ };
3291
+
3292
+ // src/components/common/HelpDialog.tsx
3293
+ import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
3294
+ var HelpDialog = () => {
3295
+ const { theme } = useTheme();
3296
+ const shortcuts = [
3297
+ { key: "Ctrl+C (twice)", action: "Quit application" },
3298
+ { key: "?", action: "Toggle help dialog" },
3299
+ { key: "Shift+;", action: "Show month overview" },
3300
+ { key: "t", action: "Select theme" },
3301
+ { key: "1", action: "Focus calendar pane" },
3302
+ { key: "2 / Tab", action: "Focus tasks pane" },
3303
+ { key: "3 / Shift+Tab", action: "Focus timeline pane" },
3304
+ { key: "", action: "" },
3305
+ { key: "Calendar Pane", action: "" },
3306
+ { key: "h/l \u2190/\u2192", action: "Navigate days" },
3307
+ { key: "j/k \u2193/\u2191", action: "Navigate weeks" },
3308
+ { key: "n/p", action: "Next/prev month" },
3309
+ { key: "T", action: "Go to today" },
3310
+ { key: "", action: "" },
3311
+ { key: "Tasks Pane", action: "" },
3312
+ { key: "j/k \u2193/\u2191", action: "Navigate tasks" },
3313
+ { key: "a", action: "Add new task" },
3314
+ { key: "e", action: "Edit task" },
3315
+ { key: "d", action: "Delete task" },
3316
+ { key: "Space", action: "Toggle completion" },
3317
+ { key: "s", action: "Start task" },
3318
+ { key: "D", action: "Mark delegated" },
3319
+ { key: "x", action: "Mark delayed/cancelled" },
3320
+ { key: "Enter", action: "Expand/collapse subtasks" },
3321
+ { key: "", action: "" },
3322
+ { key: "Timeline Pane", action: "" },
3323
+ { key: "j/k", action: "Scroll timeline" },
3324
+ { key: "Shift+C", action: "Clear timeline" }
3325
+ ];
3326
+ return /* @__PURE__ */ jsx16(Modal, { children: /* @__PURE__ */ jsxs10(
3327
+ Box12,
3328
+ {
3329
+ flexDirection: "column",
3330
+ borderStyle: "double",
3331
+ borderColor: theme.colors.helpDialogBorder,
3332
+ paddingX: 2,
3333
+ paddingY: 1,
3334
+ backgroundColor: theme.colors.modalBackground || theme.colors.background,
3335
+ children: [
3336
+ /* @__PURE__ */ jsx16(Text8, { bold: true, color: theme.colors.calendarHeader, children: "Keyboard Shortcuts" }),
3337
+ /* @__PURE__ */ jsx16(Box12, { flexDirection: "column", marginTop: 1, children: shortcuts.map((item, idx) => /* @__PURE__ */ jsx16(Box12, { marginY: 0, children: item.key ? /* @__PURE__ */ jsxs10(Fragment2, { children: [
3338
+ /* @__PURE__ */ jsx16(Box12, { width: 20, children: /* @__PURE__ */ jsx16(Text8, { color: theme.colors.timelineEventStarted, children: item.key }) }),
3339
+ /* @__PURE__ */ jsx16(Text8, { color: theme.colors.foreground, children: item.action })
3340
+ ] }) : /* @__PURE__ */ jsx16(Text8, { color: theme.colors.separator, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }) }, idx)) }),
3341
+ /* @__PURE__ */ jsx16(Box12, { marginY: 1, children: /* @__PURE__ */ jsx16(Text8, { color: theme.colors.keyboardHint, dimColor: true, children: "Press '?' to close" }) })
3342
+ ]
3343
+ }
3344
+ ) });
3345
+ };
3346
+
3347
+ // src/components/common/ThemeDialog.tsx
3348
+ import { useState as useState8, useMemo as useMemo3, useEffect as useEffect9 } from "react";
3349
+ import { Box as Box13, Text as Text9, useInput as useInput5 } from "ink";
3350
+ import TextInput2 from "ink-text-input";
3351
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
3352
+ var ThemeDialog = () => {
3353
+ const { theme, setTheme, themeName } = useTheme();
3354
+ const { setShowThemeDialog } = useApp();
3355
+ const [searchQuery, setSearchQuery] = useState8("");
3356
+ const [focusMode, setFocusMode] = useState8("search");
3357
+ const lightThemes2 = useMemo3(() => getLightThemeNames(), []);
3358
+ const darkThemes2 = useMemo3(() => getDarkThemeNames(), []);
3359
+ const allThemes = useMemo3(() => {
3360
+ const query = searchQuery.toLowerCase();
3361
+ const filteredLightThemes = lightThemes2.filter(
3362
+ (t) => t.toLowerCase().includes(query)
3363
+ );
3364
+ const filteredDarkThemes = darkThemes2.filter(
3365
+ (t) => t.toLowerCase().includes(query)
3366
+ );
3367
+ const items = [];
3368
+ if (filteredLightThemes.length > 0) {
3369
+ items.push({ type: "separator", value: "Light Themes" });
3370
+ filteredLightThemes.forEach(
3371
+ (t) => items.push({ type: "theme", value: t })
3372
+ );
3373
+ }
3374
+ if (filteredDarkThemes.length > 0) {
3375
+ items.push({ type: "separator", value: "Dark Themes" });
3376
+ filteredDarkThemes.forEach(
3377
+ (t) => items.push({ type: "theme", value: t })
3378
+ );
3379
+ }
3380
+ return items;
3381
+ }, [lightThemes2, darkThemes2, searchQuery]);
3382
+ const themeItems = useMemo3(
3383
+ () => allThemes.filter((item) => item.type === "theme"),
3384
+ [allThemes]
3385
+ );
3386
+ const initialIndex = useMemo3(() => {
3387
+ const idx = themeItems.findIndex((item) => item.value === themeName);
3388
+ return idx >= 0 ? idx : 0;
3389
+ }, [themeItems, themeName]);
3390
+ const [selectedIndex, setSelectedIndex] = useState8(initialIndex);
3391
+ useEffect9(() => {
3392
+ setSelectedIndex(0);
3393
+ }, [searchQuery]);
3394
+ useInput5(
3395
+ (input, key) => {
3396
+ if (key.escape) {
3397
+ setShowThemeDialog(false);
3398
+ return;
3399
+ }
3400
+ if (focusMode === "search") {
3401
+ if (key.return && themeItems.length > 0) {
3402
+ setTheme(themeItems[0].value);
3403
+ setShowThemeDialog(false);
3404
+ return;
3405
+ }
3406
+ if (key.downArrow && themeItems.length > 0) {
3407
+ setFocusMode("list");
3408
+ setSelectedIndex(0);
3409
+ return;
3410
+ }
3411
+ } else {
3412
+ if (key.upArrow || input === "k") {
3413
+ if (selectedIndex > 0) {
3414
+ setSelectedIndex((prev) => prev - 1);
3415
+ } else {
3416
+ setFocusMode("search");
3417
+ }
3418
+ return;
3419
+ }
3420
+ if (key.downArrow || input === "j") {
3421
+ setSelectedIndex(
3422
+ (prev) => prev < themeItems.length - 1 ? prev + 1 : 0
3423
+ );
3424
+ return;
3425
+ }
3426
+ if (key.return && themeItems.length > 0) {
3427
+ setTheme(themeItems[selectedIndex].value);
3428
+ setShowThemeDialog(false);
3429
+ return;
3430
+ }
3431
+ }
3432
+ },
3433
+ { isActive: true }
3434
+ );
3435
+ const selectedThemeName = themeItems[selectedIndex]?.value;
3436
+ const formatThemeName = (name) => {
3437
+ return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
3438
+ };
3439
+ return /* @__PURE__ */ jsx17(Modal, { children: /* @__PURE__ */ jsxs11(
3440
+ Box13,
3441
+ {
3442
+ flexDirection: "column",
3443
+ borderStyle: "double",
3444
+ borderColor: theme.colors.helpDialogBorder,
3445
+ paddingX: 2,
3446
+ paddingY: 1,
3447
+ width: 44,
3448
+ backgroundColor: theme.colors.modalBackground || theme.colors.background,
3449
+ children: [
3450
+ /* @__PURE__ */ jsx17(Text9, { bold: true, color: theme.colors.calendarHeader, underline: true, children: "Select Theme" }),
3451
+ /* @__PURE__ */ jsxs11(Box13, { marginTop: 1, flexDirection: "row", alignItems: "center", children: [
3452
+ /* @__PURE__ */ jsxs11(Text9, { color: theme.colors.foreground, dimColor: true, children: [
3453
+ "Search:",
3454
+ " "
3455
+ ] }),
3456
+ /* @__PURE__ */ jsx17(Text9, { color: theme.colors.foreground, children: /* @__PURE__ */ jsx17(
3457
+ TextInput2,
3458
+ {
3459
+ value: searchQuery,
3460
+ onChange: setSearchQuery,
3461
+ focus: focusMode === "search",
3462
+ placeholder: "Type to filter..."
3463
+ }
3464
+ ) })
3465
+ ] }),
3466
+ /* @__PURE__ */ jsx17(Box13, { flexDirection: "column", marginTop: 1, children: allThemes.map((item, idx) => {
3467
+ if (item.type === "separator") {
3468
+ return /* @__PURE__ */ jsx17(
3469
+ Box13,
3470
+ {
3471
+ marginTop: idx > 0 ? 1 : 0,
3472
+ marginBottom: 0,
3473
+ children: /* @__PURE__ */ jsx17(Text9, { bold: true, color: theme.colors.calendarHeader, dimColor: true, children: item.value })
3474
+ },
3475
+ `sep-${idx}`
3476
+ );
3477
+ }
3478
+ const isSelected = item.value === selectedThemeName;
3479
+ const isCurrent = item.value === themeName;
3480
+ return /* @__PURE__ */ jsx17(Box13, { paddingLeft: 1, children: /* @__PURE__ */ jsxs11(
3481
+ Text9,
3482
+ {
3483
+ color: isSelected ? theme.colors.focusIndicator : theme.colors.foreground,
3484
+ bold: isSelected,
3485
+ children: [
3486
+ isSelected ? "\u279C " : " ",
3487
+ formatThemeName(item.value),
3488
+ isCurrent ? " (current)" : ""
3489
+ ]
3490
+ }
3491
+ ) }, item.value);
3492
+ }) }),
3493
+ /* @__PURE__ */ jsx17(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx17(Text9, { color: theme.colors.keyboardHint, dimColor: true, children: focusMode === "search" ? "Type to search \u2022 \u2193 to navigate list \u2022 Esc to close" : "\u2191/\u2193 or k/j to navigate \u2022 Enter to select \u2022 Esc to close" }) })
3494
+ ]
3495
+ }
3496
+ ) });
3497
+ };
3498
+
3499
+ // src/components/common/ClearTimelineDialog.tsx
3500
+ import { Box as Box14, Text as Text10, useInput as useInput6 } from "ink";
3501
+ import { format as format2 } from "date-fns";
3502
+ import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
3503
+ var ClearTimelineDialog = () => {
3504
+ const { theme } = useTheme();
3505
+ const {
3506
+ selectedDate,
3507
+ timeline,
3508
+ setShowClearTimelineDialog,
3509
+ clearTimelineForDate
3510
+ } = useApp();
3511
+ const date = new Date(selectedDate.year, selectedDate.month, selectedDate.day);
3512
+ const dateStr = getDateString(date);
3513
+ const formattedDate = format2(date, "MMMM do, yyyy");
3514
+ const eventCount = (timeline[dateStr] || []).length;
3515
+ const handleConfirm = () => {
3516
+ clearTimelineForDate(dateStr);
3517
+ setShowClearTimelineDialog(false);
3518
+ };
3519
+ const handleCancel = () => {
3520
+ setShowClearTimelineDialog(false);
3521
+ };
3522
+ useInput6((input, key) => {
3523
+ if (input.toLowerCase() === "y" || key.return) {
3524
+ handleConfirm();
3525
+ } else if (input.toLowerCase() === "n" || key.escape) {
3526
+ handleCancel();
3527
+ }
3528
+ });
3529
+ return /* @__PURE__ */ jsx18(Modal, { children: /* @__PURE__ */ jsxs12(
3530
+ Box14,
3531
+ {
3532
+ flexDirection: "column",
3533
+ borderStyle: "double",
3534
+ borderColor: theme.colors.taskStateDelayed,
3535
+ paddingX: 4,
3536
+ paddingY: 2,
3537
+ backgroundColor: theme.colors.modalBackground || theme.colors.background,
3538
+ children: [
3539
+ /* @__PURE__ */ jsx18(Box14, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx18(Text10, { bold: true, color: theme.colors.taskStateDelayed, children: "Clear Timeline" }) }),
3540
+ /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", marginY: 1, children: [
3541
+ /* @__PURE__ */ jsx18(Text10, { color: theme.colors.foreground, children: "You are about to clear the timeline for" }),
3542
+ /* @__PURE__ */ jsx18(Box14, { justifyContent: "center", marginY: 1, children: /* @__PURE__ */ jsx18(Text10, { bold: true, color: theme.colors.calendarHeader, children: formattedDate }) }),
3543
+ eventCount > 0 ? /* @__PURE__ */ jsxs12(Text10, { color: theme.colors.keyboardHint, children: [
3544
+ "This will remove ",
3545
+ eventCount,
3546
+ " event",
3547
+ eventCount !== 1 ? "s" : "",
3548
+ " from the timeline."
3549
+ ] }) : /* @__PURE__ */ jsx18(Text10, { color: theme.colors.keyboardHint, dimColor: true, children: "The timeline is already empty." })
3550
+ ] }),
3551
+ /* @__PURE__ */ jsxs12(Box14, { marginTop: 2, justifyContent: "center", children: [
3552
+ /* @__PURE__ */ jsx18(Text10, { color: theme.colors.foreground, children: "Are you sure? " }),
3553
+ /* @__PURE__ */ jsx18(Text10, { color: theme.colors.taskStateCompleted, bold: true, children: "[Y]es" }),
3554
+ /* @__PURE__ */ jsx18(Text10, { color: theme.colors.foreground, children: " / " }),
3555
+ /* @__PURE__ */ jsx18(Text10, { color: theme.colors.taskStateDelayed, bold: true, children: "[N]o" })
3556
+ ] }),
3557
+ /* @__PURE__ */ jsx18(Box14, { marginTop: 2, justifyContent: "center", children: /* @__PURE__ */ jsx18(Text10, { color: theme.colors.keyboardHint, dimColor: true, children: "Press Y to confirm, N or Esc to cancel" }) })
3558
+ ]
3559
+ }
3560
+ ) });
3561
+ };
3562
+
3563
+ // src/components/overview/OverviewScreen.tsx
3564
+ import React8, { useMemo as useMemo4 } from "react";
3565
+ import { Box as Box15, Text as Text11, useInput as useInput7 } from "ink";
3566
+ import { startOfMonth as startOfMonth2, endOfMonth as endOfMonth2, eachDayOfInterval as eachDayOfInterval2 } from "date-fns";
3567
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
3568
+ var OverviewScreen = () => {
3569
+ const { theme } = useTheme();
3570
+ const { tasks, overviewMonth, setOverviewMonth, setShowOverview } = useApp();
3571
+ const [scrollOffset, setScrollOffset] = React8.useState(0);
3572
+ const { height: terminalHeight } = useTerminalSize();
3573
+ const visibleRows = useMemo4(() => {
3574
+ return Math.max(2, Math.floor((terminalHeight - 9) / 3));
3575
+ }, [terminalHeight]);
3576
+ const monthDates = useMemo4(() => {
3577
+ const monthStart = startOfMonth2(
3578
+ new Date(overviewMonth.year, overviewMonth.month, 1)
3579
+ );
3580
+ const monthEnd = endOfMonth2(monthStart);
3581
+ return eachDayOfInterval2({ start: monthStart, end: monthEnd });
3582
+ }, [overviewMonth]);
3583
+ const tasksByDate = useMemo4(() => {
3584
+ const grouped = {};
3585
+ monthDates.forEach((date) => {
3586
+ const dateStr = getDateString(date);
3587
+ grouped[dateStr] = tasks[dateStr] || [];
3588
+ });
3589
+ return grouped;
3590
+ }, [monthDates, tasks]);
3591
+ const handlePrevMonth = () => {
3592
+ const newMonth = overviewMonth.month - 1;
3593
+ if (newMonth < 0) {
3594
+ setOverviewMonth({ year: overviewMonth.year - 1, month: 11 });
3595
+ } else {
3596
+ setOverviewMonth({ ...overviewMonth, month: newMonth });
3597
+ }
3598
+ };
3599
+ const handleNextMonth = () => {
3600
+ const newMonth = overviewMonth.month + 1;
3601
+ if (newMonth > 11) {
3602
+ setOverviewMonth({ year: overviewMonth.year + 1, month: 0 });
3603
+ } else {
3604
+ setOverviewMonth({ ...overviewMonth, month: newMonth });
3605
+ }
3606
+ };
3607
+ React8.useEffect(() => {
3608
+ setScrollOffset(0);
3609
+ }, [overviewMonth]);
3610
+ useInput7((input, key) => {
3611
+ if (key.escape) {
3612
+ setShowOverview(false);
3613
+ return;
3614
+ }
3615
+ if (input === "n" || key.rightArrow) {
3616
+ handleNextMonth();
3617
+ return;
3618
+ }
3619
+ if (input === "p" || key.leftArrow) {
3620
+ handlePrevMonth();
3621
+ return;
3622
+ }
3623
+ if (input === "j" || key.downArrow) {
3624
+ setScrollOffset(
3625
+ (prev) => Math.min(prev + 1, Math.max(0, rows - visibleRows))
3626
+ );
3627
+ return;
3628
+ }
3629
+ if (input === "k" || key.upArrow) {
3630
+ setScrollOffset((prev) => Math.max(prev - 1, 0));
3631
+ return;
3632
+ }
3633
+ });
3634
+ const monthName = formatDate(
3635
+ new Date(overviewMonth.year, overviewMonth.month, 1),
3636
+ "MMMM yyyy"
3637
+ );
3638
+ const columns = 4;
3639
+ const rows = Math.ceil(monthDates.length / columns);
3640
+ const visibleRowData = Array.from({ length: rows }).slice(
3641
+ scrollOffset,
3642
+ scrollOffset + visibleRows
3643
+ );
3644
+ const canScrollUp = scrollOffset > 0;
3645
+ const canScrollDown = scrollOffset + visibleRows < rows;
3646
+ return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", padding: 1, width: "100%", height: "100%", children: [
3647
+ /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", marginBottom: 1, children: [
3648
+ /* @__PURE__ */ jsx19(Text11, { bold: true, color: theme.colors.focusIndicator, children: "Overview" }),
3649
+ /* @__PURE__ */ jsx19(Text11, { color: theme.colors.foreground, children: monthName })
3650
+ ] }),
3651
+ /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", flexGrow: 1, children: [
3652
+ canScrollUp && /* @__PURE__ */ jsx19(Box15, { justifyContent: "center", marginBottom: 1, children: /* @__PURE__ */ jsx19(Text11, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more above --" }) }),
3653
+ visibleRowData.map((_, index) => {
3654
+ const rowIndex = scrollOffset + index;
3655
+ return /* @__PURE__ */ jsx19(Box15, { flexDirection: "row", marginBottom: 1, children: Array.from({ length: columns }).map((_2, colIndex) => {
3656
+ const dateIndex = rowIndex * columns + colIndex;
3657
+ const date = monthDates[dateIndex];
3658
+ if (!date) {
3659
+ return /* @__PURE__ */ jsx19(
3660
+ Box15,
3661
+ {
3662
+ flexDirection: "column",
3663
+ flexGrow: 1,
3664
+ flexBasis: 0,
3665
+ marginRight: colIndex === columns - 1 ? 0 : 2
3666
+ },
3667
+ `empty-${colIndex}`
3668
+ );
3669
+ }
3670
+ const dateStr = getDateString(date);
3671
+ const dayTasks = tasksByDate[dateStr] || [];
3672
+ const flatTasksWithDepth = [];
3673
+ const traverse = (taskList, depth) => {
3674
+ for (const task of taskList) {
3675
+ flatTasksWithDepth.push({ task, depth });
3676
+ traverse(task.children, depth + 1);
3677
+ }
3678
+ };
3679
+ traverse(dayTasks, 0);
3680
+ return /* @__PURE__ */ jsxs13(
3681
+ Box15,
3682
+ {
3683
+ flexDirection: "column",
3684
+ flexGrow: 1,
3685
+ flexBasis: 0,
3686
+ marginRight: colIndex === columns - 1 ? 0 : 2,
3687
+ children: [
3688
+ /* @__PURE__ */ jsx19(Text11, { bold: true, color: theme.colors.calendarSelected, children: formatDate(date, "do MMM") }),
3689
+ /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
3690
+ flatTasksWithDepth.length === 0 ? /* @__PURE__ */ jsx19(Text11, { dimColor: true, color: theme.colors.keyboardHint, children: "No tasks" }) : flatTasksWithDepth.slice(0, 10).map(({ task, depth }) => /* @__PURE__ */ jsx19(
3691
+ TaskItem,
3692
+ {
3693
+ task,
3694
+ theme,
3695
+ depth
3696
+ },
3697
+ task.id
3698
+ )),
3699
+ flatTasksWithDepth.length > 10 && /* @__PURE__ */ jsxs13(Text11, { dimColor: true, color: theme.colors.keyboardHint, children: [
3700
+ "+",
3701
+ flatTasksWithDepth.length - 10,
3702
+ " more..."
3703
+ ] })
3704
+ ] })
3705
+ ]
3706
+ },
3707
+ dateStr
3708
+ );
3709
+ }) }, rowIndex);
3710
+ }),
3711
+ canScrollDown && /* @__PURE__ */ jsx19(Box15, { justifyContent: "center", marginTop: 1, children: /* @__PURE__ */ jsx19(Text11, { color: theme.colors.keyboardHint, dimColor: true, children: "-- more below --" }) })
3712
+ ] }),
3713
+ /* @__PURE__ */ jsx19(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text11, { color: theme.colors.keyboardHint, dimColor: true, children: "n/p or \u2190/\u2192: month | j/k or \u2193/\u2191: scroll | Esc: close | Shift+;: toggle" }) })
3714
+ ] });
3715
+ };
3716
+ var TaskItem = ({ task, theme, depth }) => {
3717
+ const checkbox = getCheckbox2(task.state);
3718
+ const color = getStateColor2(task.state, theme);
3719
+ return /* @__PURE__ */ jsxs13(Box15, { children: [
3720
+ /* @__PURE__ */ jsxs13(Text11, { color, children: [
3721
+ checkbox,
3722
+ " "
3723
+ ] }),
3724
+ depth > 0 && /* @__PURE__ */ jsx19(Text11, { children: " ".repeat(depth) }),
3725
+ /* @__PURE__ */ jsx19(
3726
+ Text11,
3727
+ {
3728
+ color,
3729
+ strikethrough: task.state === "completed",
3730
+ dimColor: task.state === "delayed",
3731
+ children: task.title.length > 35 ? task.title.slice(0, 32) + "..." : task.title
3732
+ }
3733
+ )
3734
+ ] });
3735
+ };
3736
+ function getCheckbox2(state) {
3737
+ switch (state) {
3738
+ case "completed":
3739
+ return "[\u2713]";
3740
+ case "delegated":
3741
+ return "[\u2192]";
3742
+ case "delayed":
3743
+ return "[\u2016]";
3744
+ default:
3745
+ return "[ ]";
3746
+ }
3747
+ }
3748
+ function getStateColor2(state, theme) {
3749
+ const colors = {
3750
+ todo: theme.colors.taskStateTodo,
3751
+ completed: theme.colors.taskStateCompleted,
3752
+ delegated: theme.colors.taskStateDelegated,
3753
+ delayed: theme.colors.taskStateDelayed
3754
+ };
3755
+ return colors[state] || theme.colors.foreground;
3756
+ }
3757
+
3758
+ // src/App.tsx
3759
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
3760
+ var AppContent = () => {
3761
+ const {
3762
+ showHelp,
3763
+ showOverview,
3764
+ exitConfirmation,
3765
+ activePane,
3766
+ showThemeDialog,
3767
+ showClearTimelineDialog
3768
+ } = useApp();
3769
+ const { theme } = useTheme();
3770
+ useKeyboardNav();
3771
+ const { width, height } = useTerminalSize();
3772
+ if (showThemeDialog) {
3773
+ return /* @__PURE__ */ jsx20(ThemeDialog, {});
3774
+ }
3775
+ if (showHelp) {
3776
+ return /* @__PURE__ */ jsx20(HelpDialog, {});
3777
+ }
3778
+ if (showClearTimelineDialog) {
3779
+ return /* @__PURE__ */ jsx20(ClearTimelineDialog, {});
3780
+ }
3781
+ return /* @__PURE__ */ jsx20(FullscreenBackground, { backgroundColor: theme.colors.background || "black", children: /* @__PURE__ */ jsxs14(Box16, { flexDirection: "column", width, height, padding: 1, backgroundColor: theme.colors.background, children: [
3782
+ showOverview ? /* @__PURE__ */ jsx20(OverviewScreen, {}) : /* @__PURE__ */ jsx20(
3783
+ ThreeColumnLayout,
3784
+ {
3785
+ leftPane: /* @__PURE__ */ jsx20(CalendarPane, {}),
3786
+ centerPane: /* @__PURE__ */ jsx20(TasksPane, {}),
3787
+ rightPane: /* @__PURE__ */ jsx20(TimelinePane, {}),
3788
+ activePane,
3789
+ height: height - 2
3790
+ }
3791
+ ),
3792
+ exitConfirmation && /* @__PURE__ */ jsx20(Box16, { width: "100%", justifyContent: "center", paddingY: 1, children: /* @__PURE__ */ jsxs14(Text12, { backgroundColor: "red", color: "white", bold: true, children: [
3793
+ " ",
3794
+ "Press Ctrl+C again to exit Epoch",
3795
+ " "
3796
+ ] }) })
3797
+ ] }) });
3798
+ };
3799
+ var App = () => {
3800
+ return /* @__PURE__ */ jsx20(StorageProvider, { children: /* @__PURE__ */ jsx20(ThemeProvider, { initialTheme: "dark", children: /* @__PURE__ */ jsx20(AppProvider, { children: /* @__PURE__ */ jsx20(AppContent, {}) }) }) });
3801
+ };
3802
+ var App_default = App;
3803
+
3804
+ // src/index.tsx
3805
+ import { jsx as jsx21 } from "react/jsx-runtime";
5
3806
  console.clear();
6
- const app = render(_jsx(App, {}), { exitOnCtrlC: false });
7
- // Make the app instance globally accessible for clean exit
3807
+ var app = render(/* @__PURE__ */ jsx21(App_default, {}), { exitOnCtrlC: false });
8
3808
  global.__inkApp = app;