floq 0.2.0 → 0.2.2

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.
@@ -4,6 +4,8 @@ import { Box, Text, useInput } from 'ink';
4
4
  import { t } from '../../i18n/index.js';
5
5
  import { useTheme } from '../theme/index.js';
6
6
  import { parseChangelog } from '../../changelog.js';
7
+ import { loadConfig, isTursoEnabled, getTursoConfig, getDbPath } from '../../config.js';
8
+ import { CONFIG_FILE, DATA_DIR } from '../../paths.js';
7
9
  const VISIBLE_LINES = 12;
8
10
  export function HelpModal({ onClose, isKanban = false }) {
9
11
  const [activeTab, setActiveTab] = useState('keybindings');
@@ -27,10 +29,14 @@ export function HelpModal({ onClose, isKanban = false }) {
27
29
  return items;
28
30
  }, []);
29
31
  const maxScroll = Math.max(0, changelogItems.length - VISIBLE_LINES);
32
+ const tabs = ['keybindings', 'info', 'whatsNew'];
30
33
  useInput((input, key) => {
31
34
  // Tab key detection (key.tab or raw tab character)
32
35
  if (key.tab || input === '\t') {
33
- setActiveTab(prev => prev === 'keybindings' ? 'whatsNew' : 'keybindings');
36
+ setActiveTab(prev => {
37
+ const currentIndex = tabs.indexOf(prev);
38
+ return tabs[(currentIndex + 1) % tabs.length];
39
+ });
34
40
  setScrollOffset(0);
35
41
  return;
36
42
  }
@@ -41,18 +47,29 @@ export function HelpModal({ onClose, isKanban = false }) {
41
47
  return;
42
48
  }
43
49
  if (input === '2') {
50
+ setActiveTab('info');
51
+ setScrollOffset(0);
52
+ return;
53
+ }
54
+ if (input === '3') {
44
55
  setActiveTab('whatsNew');
45
56
  setScrollOffset(0);
46
57
  return;
47
58
  }
48
59
  // Arrow keys and h/l for tab switching
49
60
  if (input === 'h' || key.leftArrow) {
50
- setActiveTab('keybindings');
61
+ setActiveTab(prev => {
62
+ const currentIndex = tabs.indexOf(prev);
63
+ return tabs[(currentIndex - 1 + tabs.length) % tabs.length];
64
+ });
51
65
  setScrollOffset(0);
52
66
  return;
53
67
  }
54
68
  if (input === 'l' || key.rightArrow) {
55
- setActiveTab('whatsNew');
69
+ setActiveTab(prev => {
70
+ const currentIndex = tabs.indexOf(prev);
71
+ return tabs[(currentIndex + 1) % tabs.length];
72
+ });
56
73
  setScrollOffset(0);
57
74
  return;
58
75
  }
@@ -73,7 +90,7 @@ export function HelpModal({ onClose, isKanban = false }) {
73
90
  }
74
91
  });
75
92
  const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
76
- return (_jsxs(Box, { flexDirection: "column", borderStyle: theme.borders.modal, borderColor: theme.colors.borderActive, paddingX: 2, paddingY: 1, children: [_jsx(Box, { justifyContent: "center", marginBottom: 1, children: _jsxs(Box, { children: [_jsxs(Text, { bold: activeTab === 'keybindings', color: activeTab === 'keybindings' ? theme.colors.secondary : theme.colors.textMuted, inverse: activeTab === 'keybindings', children: [' ', formatTitle(help.keybindingsTab), ' '] }), _jsx(Text, { color: theme.colors.textMuted, children: " \u2502 " }), _jsxs(Text, { bold: activeTab === 'whatsNew', color: activeTab === 'whatsNew' ? theme.colors.secondary : theme.colors.textMuted, inverse: activeTab === 'whatsNew', children: [' ', formatTitle(help.whatsNewTab), ' '] })] }) }), activeTab === 'keybindings' ? (isKanban ? (_jsx(KanbanKeybindingsContent, {})) : (_jsx(GTDKeybindingsContent, {}))) : (_jsx(WhatsNewContent, { items: changelogItems, scrollOffset: scrollOffset, visibleLines: VISIBLE_LINES, maxScroll: maxScroll })), _jsx(Box, { justifyContent: "center", marginTop: 1, children: _jsx(Text, { color: theme.colors.textMuted, children: activeTab === 'whatsNew' && maxScroll > 0
93
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: theme.borders.modal, borderColor: theme.colors.borderActive, paddingX: 2, paddingY: 1, children: [_jsx(Box, { justifyContent: "center", marginBottom: 1, children: _jsxs(Box, { children: [_jsxs(Text, { bold: activeTab === 'keybindings', color: activeTab === 'keybindings' ? theme.colors.secondary : theme.colors.textMuted, inverse: activeTab === 'keybindings', children: [' ', formatTitle(help.keybindingsTab), ' '] }), _jsx(Text, { color: theme.colors.textMuted, children: " \u2502 " }), _jsxs(Text, { bold: activeTab === 'info', color: activeTab === 'info' ? theme.colors.secondary : theme.colors.textMuted, inverse: activeTab === 'info', children: [' ', formatTitle(help.infoTab), ' '] }), _jsx(Text, { color: theme.colors.textMuted, children: " \u2502 " }), _jsxs(Text, { bold: activeTab === 'whatsNew', color: activeTab === 'whatsNew' ? theme.colors.secondary : theme.colors.textMuted, inverse: activeTab === 'whatsNew', children: [' ', formatTitle(help.whatsNewTab), ' '] })] }) }), activeTab === 'keybindings' ? (isKanban ? (_jsx(KanbanKeybindingsContent, {})) : (_jsx(GTDKeybindingsContent, {}))) : activeTab === 'info' ? (_jsx(InfoContent, {})) : (_jsx(WhatsNewContent, { items: changelogItems, scrollOffset: scrollOffset, visibleLines: VISIBLE_LINES, maxScroll: maxScroll })), _jsx(Box, { justifyContent: "center", marginTop: 1, children: _jsx(Text, { color: theme.colors.textMuted, children: activeTab === 'whatsNew' && maxScroll > 0
77
94
  ? `j/k: scroll | ${help.tabHint} | ${help.closeHint}`
78
95
  : `${help.tabHint} | ${help.closeHint}` }) })] }));
79
96
  }
@@ -82,14 +99,34 @@ function GTDKeybindingsContent() {
82
99
  const help = i18n.tui.help;
83
100
  const theme = useTheme();
84
101
  const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
85
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-6" }), " ", help.tabSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.prevNextTab] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "n" }), " ", help.moveToNext] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "s" }), " ", help.moveToSomeday] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "w" }), " ", help.moveToWaiting] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "i" }), " ", help.moveToInbox] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "r" }), " ", help.refresh] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.projects) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "p" }), " ", help.makeProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "P" }), " ", help.linkToProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.openProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Esc/b" }), " ", help.backFromProject] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
102
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-6" }), " ", help.tabSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.prevNextTab] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "n" }), " ", help.moveToNext] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "s" }), " ", help.moveToSomeday] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "w" }), " ", help.moveToWaiting] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "i" }), " ", help.moveToInbox] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "r" }), " ", help.refresh] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.projects) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "p" }), " ", help.makeProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "P" }), " ", help.linkToProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.openProject] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Esc/b" }), " ", help.backFromProject] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
86
103
  }
87
104
  function KanbanKeybindingsContent() {
88
105
  const i18n = t();
89
106
  const help = i18n.tui.kanbanHelp;
90
107
  const theme = useTheme();
91
108
  const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
92
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.columnSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-3" }), " ", help.columnDirect] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.moveRight] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "BS" }), " ", help.moveLeft] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
109
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.navigation) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "h/l \u2190/\u2192" }), " ", help.columnSwitch] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "1-3" }), " ", help.columnDirect] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "j/k \u2191/\u2193" }), " ", help.taskSelect] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.actions) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "a" }), " ", help.addTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "d" }), " ", help.completeTask] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "Enter" }), " ", help.moveRight] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "BS" }), " ", help.moveLeft] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "T" }), " ", help.changeTheme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "V" }), " ", help.changeViewMode] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "L" }), " ", help.changeLanguage] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(help.other) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "/" }), " ", help.searchTasks] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "?" }), " ", help.showHelp] }), _jsxs(Text, { color: theme.colors.text, children: [_jsx(Text, { color: theme.colors.textHighlight, children: "q" }), " ", help.quit] })] })] })] }));
110
+ }
111
+ function InfoContent() {
112
+ const i18n = t();
113
+ const info = i18n.tui.info;
114
+ const theme = useTheme();
115
+ const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
116
+ const config = loadConfig();
117
+ const tursoEnabled = isTursoEnabled();
118
+ const tursoConfig = tursoEnabled ? getTursoConfig() : undefined;
119
+ const dbPath = getDbPath();
120
+ // Get Turso host for display
121
+ const tursoUrl = tursoConfig ? (() => {
122
+ try {
123
+ return new URL(tursoConfig.url).host;
124
+ }
125
+ catch {
126
+ return tursoConfig.url;
127
+ }
128
+ })() : '';
129
+ return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(info.settings) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.theme, ":"] }), " ", config.theme] }), _jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.language, ":"] }), " ", config.locale] }), _jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.viewMode, ":"] }), " ", config.viewMode] })] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(info.database) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.dbType, ":"] }), " ", tursoEnabled ? info.turso : info.local] }), _jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.dbPath, ":"] }), " ", dbPath] }), tursoEnabled && tursoUrl && (_jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.tursoUrl, ":"] }), " ", tursoUrl] }))] })] }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: theme.colors.accent, children: formatTitle(info.paths) }), _jsxs(Box, { paddingLeft: 2, flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.configFile, ":"] }), " ", CONFIG_FILE] }), _jsxs(Text, { color: theme.colors.text, children: [_jsxs(Text, { color: theme.colors.textHighlight, children: [info.dataDir, ":"] }), " ", DATA_DIR] })] })] })] }));
93
130
  }
94
131
  function WhatsNewContent({ items, scrollOffset, visibleLines, maxScroll }) {
95
132
  const i18n = t();
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
+ type SettingsMode = 'none' | 'theme-select' | 'mode-select' | 'lang-select';
2
3
  interface KanbanBoardProps {
3
4
  onSwitchToGtd?: () => void;
5
+ onOpenSettings?: (mode: SettingsMode) => void;
4
6
  }
5
- export declare function KanbanBoard({ onSwitchToGtd }: KanbanBoardProps): React.ReactElement;
7
+ export declare function KanbanBoard({ onSwitchToGtd, onOpenSettings }: KanbanBoardProps): React.ReactElement;
6
8
  export {};
@@ -12,10 +12,10 @@ import { SearchResults } from './SearchResults.js';
12
12
  import { getDb, schema } from '../../db/index.js';
13
13
  import { t, fmt } from '../../i18n/index.js';
14
14
  import { useTheme } from '../theme/index.js';
15
- import { isTursoEnabled, getTursoConfig } from '../../config.js';
15
+ import { isTursoEnabled } from '../../config.js';
16
16
  import { VERSION } from '../../version.js';
17
17
  const COLUMNS = ['todo', 'doing', 'done'];
18
- export function KanbanBoard({ onSwitchToGtd }) {
18
+ export function KanbanBoard({ onSwitchToGtd, onOpenSettings }) {
19
19
  const theme = useTheme();
20
20
  const { exit } = useApp();
21
21
  const [mode, setMode] = useState('normal');
@@ -366,6 +366,21 @@ export function KanbanBoard({ onSwitchToGtd }) {
366
366
  setSearchResultIndex(0);
367
367
  return;
368
368
  }
369
+ // Settings: Theme selector
370
+ if (input === 'T' && onOpenSettings) {
371
+ onOpenSettings('theme-select');
372
+ return;
373
+ }
374
+ // Settings: Mode selector
375
+ if (input === 'V' && onOpenSettings) {
376
+ onOpenSettings('mode-select');
377
+ return;
378
+ }
379
+ // Settings: Language selector
380
+ if (input === 'L' && onOpenSettings) {
381
+ onOpenSettings('lang-select');
382
+ return;
383
+ }
369
384
  // Quit
370
385
  if (input === 'q' || (key.ctrl && input === 'c')) {
371
386
  exit();
@@ -476,19 +491,9 @@ export function KanbanBoard({ onSwitchToGtd }) {
476
491
  const formatTitle = (title) => theme.style.headerUppercase ? title.toUpperCase() : title;
477
492
  // Turso connection info
478
493
  const tursoEnabled = isTursoEnabled();
479
- const tursoHost = tursoEnabled ? (() => {
480
- const config = getTursoConfig();
481
- if (config) {
482
- try {
483
- return new URL(config.url).host;
484
- }
485
- catch {
486
- return config.url;
487
- }
488
- }
489
- return '';
490
- })() : '';
491
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, color: theme.colors.primary, children: formatTitle(i18n.tui.title) }), _jsx(Text, { color: theme.colors.accent, children: " [KANBAN]" }), _jsx(Text, { color: theme.colors.textMuted, children: theme.name === 'modern' ? ` v${VERSION}` : ` VER ${VERSION}` }), tursoEnabled && (_jsxs(Text, { color: theme.colors.accent, children: [theme.name === 'modern' ? ' ☁️ ' : ' [SYNC] ', tursoHost] })), !tursoEnabled && (_jsx(Text, { color: theme.colors.textMuted, children: theme.name === 'modern' ? ' 💾 local' : ' [LOCAL]' }))] }), _jsx(Text, { color: theme.colors.textMuted, children: i18n.tui.helpHint })] }), (mode === 'task-detail' || mode === 'add-comment' || mode === 'select-project') && selectedTask ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: theme.colors.accent, bold: true, children: [theme.name === 'modern' ? '📋 ' : '>> ', i18n.tui.taskDetailTitle || 'Task Details'] }), _jsxs(Text, { color: theme.colors.textMuted, children: [" (Esc/b: ", i18n.tui.back || 'back', ", ", i18n.tui.commentHint || 'i: add comment', ")"] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: theme.borders.list, borderColor: theme.colors.border, paddingX: 1, paddingY: 1, marginBottom: 1, children: [_jsx(Text, { color: theme.colors.text, bold: true, children: selectedTask.title }), selectedTask.description && (_jsx(Text, { color: theme.colors.textMuted, children: selectedTask.description })), _jsxs(Text, { color: theme.colors.textMuted, children: [i18n.status[selectedTask.status], selectedTask.waitingFor && ` - ${selectedTask.waitingFor}`, selectedTask.dueDate && ` (${selectedTask.dueDate.toLocaleDateString()})`] })] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.colors.secondary, bold: true, children: [i18n.tui.comments || 'Comments', " (", taskComments.length, ")"] }) }), _jsx(Box, { flexDirection: "column", borderStyle: theme.borders.list, borderColor: theme.colors.border, paddingX: 1, paddingY: 1, minHeight: 5, children: taskComments.length === 0 ? (_jsx(Text, { color: theme.colors.textMuted, italic: true, children: i18n.tui.noComments || 'No comments yet' })) : (taskComments.map((comment, index) => {
494
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, color: theme.colors.primary, children: formatTitle(i18n.tui.title) }), _jsx(Text, { color: theme.colors.accent, children: " [KANBAN]" }), _jsx(Text, { color: theme.colors.textMuted, children: theme.name === 'modern' ? ` v${VERSION}` : ` VER ${VERSION}` }), _jsx(Text, { color: tursoEnabled ? theme.colors.accent : theme.colors.textMuted, children: theme.name === 'modern'
495
+ ? (tursoEnabled ? ' ☁️ turso' : ' 💾 local')
496
+ : (tursoEnabled ? ' [DB]TURSO' : ' [DB]local') })] }), _jsx(Text, { color: theme.colors.textMuted, children: i18n.tui.helpHint })] }), (mode === 'task-detail' || mode === 'add-comment' || mode === 'select-project') && selectedTask ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: theme.colors.accent, bold: true, children: [theme.name === 'modern' ? '📋 ' : '>> ', i18n.tui.taskDetailTitle || 'Task Details'] }), _jsxs(Text, { color: theme.colors.textMuted, children: [" (Esc/b: ", i18n.tui.back || 'back', ", ", i18n.tui.commentHint || 'i: add comment', ")"] })] }), _jsxs(Box, { flexDirection: "column", borderStyle: theme.borders.list, borderColor: theme.colors.border, paddingX: 1, paddingY: 1, marginBottom: 1, children: [_jsx(Text, { color: theme.colors.text, bold: true, children: selectedTask.title }), selectedTask.description && (_jsx(Text, { color: theme.colors.textMuted, children: selectedTask.description })), _jsxs(Text, { color: theme.colors.textMuted, children: [i18n.status[selectedTask.status], selectedTask.waitingFor && ` - ${selectedTask.waitingFor}`, selectedTask.dueDate && ` (${selectedTask.dueDate.toLocaleDateString()})`] })] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: theme.colors.secondary, bold: true, children: [i18n.tui.comments || 'Comments', " (", taskComments.length, ")"] }) }), _jsx(Box, { flexDirection: "column", borderStyle: theme.borders.list, borderColor: theme.colors.border, paddingX: 1, paddingY: 1, minHeight: 5, children: taskComments.length === 0 ? (_jsx(Text, { color: theme.colors.textMuted, italic: true, children: i18n.tui.noComments || 'No comments yet' })) : (taskComments.map((comment, index) => {
492
497
  const isSelected = index === selectedCommentIndex && mode === 'task-detail';
493
498
  return (_jsxs(Box, { flexDirection: "row", marginBottom: 1, children: [_jsx(Text, { color: isSelected ? theme.colors.textSelected : theme.colors.textMuted, children: isSelected ? theme.style.selectedPrefix : theme.style.unselectedPrefix }), _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: theme.colors.textMuted, children: ["[", comment.createdAt.toLocaleString(), "]"] }), _jsx(Text, { color: isSelected ? theme.colors.textSelected : theme.colors.text, bold: isSelected, children: comment.content })] })] }, comment.id));
494
499
  })) }), mode === 'add-comment' && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: theme.colors.secondary, bold: true, children: i18n.tui.addComment || 'New comment: ' }), _jsx(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleInputSubmit, placeholder: "" }), _jsxs(Text, { color: theme.colors.textMuted, children: [" ", i18n.tui.inputHelp] })] })), mode === 'select-project' && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: theme.colors.secondary, bold: true, children: [i18n.tui.selectProject || 'Select project for', ": ", selectedTask.title] }), _jsx(Box, { flexDirection: "column", marginTop: 1, borderStyle: theme.borders.list, borderColor: theme.colors.borderActive, paddingX: 1, children: projects.map((project, index) => (_jsxs(Text, { color: index === projectSelectIndex ? theme.colors.textSelected : theme.colors.text, bold: index === projectSelectIndex, children: [index === projectSelectIndex ? theme.style.selectedPrefix : theme.style.unselectedPrefix, project.title] }, project.id))) }), _jsx(Text, { color: theme.colors.textMuted, children: i18n.tui.selectProjectHelp || 'j/k: select, Enter: confirm, Esc: cancel' })] }))] })) : mode === 'search' ? (_jsx(_Fragment, { children: searchQuery && (_jsx(SearchResults, { results: searchResults, selectedIndex: searchResultIndex, query: searchQuery })) })) : (_jsxs(_Fragment, { children: [_jsx(Box, { marginBottom: 1, children: COLUMNS.map((column, index) => (_jsx(Box, { flexGrow: 1, flexBasis: 0, marginRight: index < 2 ? 1 : 0, children: _jsxs(Text, { color: currentColumnIndex === index ? theme.colors.textHighlight : theme.colors.textMuted, children: [index + 1, ":"] }) }, column))) }), _jsx(Box, { flexDirection: "row", children: COLUMNS.map((column, index) => (_jsx(KanbanColumn, { title: getColumnLabel(column), tasks: tasks[column], isActive: index === currentColumnIndex, selectedTaskIndex: selectedTaskIndices[column], columnIndex: index }, column))) })] })), mode === 'add' && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: theme.colors.secondary, bold: true, children: i18n.tui.newTask }), _jsx(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleInputSubmit, placeholder: i18n.tui.placeholder }), _jsxs(Text, { color: theme.colors.textMuted, children: [" ", i18n.tui.inputHelp] })] })), mode === 'search' && (_jsx(SearchBar, { value: searchQuery, onChange: handleSearchChange, onSubmit: handleInputSubmit })), message && mode === 'normal' && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.colors.textHighlight, children: message }) })), _jsx(Box, { marginTop: 1, children: mode === 'select-project' ? (_jsx(Text, { color: theme.colors.textMuted, children: i18n.tui.selectProjectHelp || 'j/k: select, Enter: confirm, Esc: cancel' })) : (mode === 'task-detail' || mode === 'add-comment') ? (theme.style.showFunctionKeys ? (_jsx(FunctionKeyBar, { keys: [
@@ -15,6 +15,16 @@ export declare const solarizedLightTheme: Theme;
15
15
  export declare const synthwaveTheme: Theme;
16
16
  export declare const paperTheme: Theme;
17
17
  export declare const coffeeTheme: Theme;
18
+ export declare const nordTheme: Theme;
19
+ export declare const draculaTheme: Theme;
20
+ export declare const monokaiTheme: Theme;
21
+ export declare const gruvboxTheme: Theme;
22
+ export declare const tokyoNightTheme: Theme;
23
+ export declare const catppuccinTheme: Theme;
24
+ export declare const oceanTheme: Theme;
25
+ export declare const sakuraTheme: Theme;
26
+ export declare const msxTheme: Theme;
27
+ export declare const pc98Theme: Theme;
18
28
  export declare const themes: Record<ThemeName, Theme>;
19
29
  export declare const VALID_THEMES: ThemeName[];
20
30
  export declare function getTheme(name: ThemeName): Theme;
@@ -611,6 +611,396 @@ export const coffeeTheme = {
611
611
  loadingChars: ['☕', '○'],
612
612
  },
613
613
  };
614
+ // Nord - Arctic, north-bluish color palette
615
+ export const nordTheme = {
616
+ name: 'nord',
617
+ displayName: 'Nord',
618
+ colors: {
619
+ primary: '#88c0d0',
620
+ secondary: '#81a1c1',
621
+ accent: '#ebcb8b',
622
+ muted: '#4c566a',
623
+ border: '#4c566a',
624
+ borderActive: '#88c0d0',
625
+ background: '#2e3440',
626
+ statusInbox: '#88c0d0',
627
+ statusNext: '#a3be8c',
628
+ statusWaiting: '#ebcb8b',
629
+ statusSomeday: '#b48ead',
630
+ statusDone: '#4c566a',
631
+ text: '#eceff4',
632
+ textMuted: '#4c566a',
633
+ textSelected: '#88c0d0',
634
+ textHighlight: '#a3be8c',
635
+ fnKeyLabel: '#3b4252',
636
+ fnKeyText: '#d8dee9',
637
+ },
638
+ borders: {
639
+ main: 'round',
640
+ modal: 'round',
641
+ list: 'single',
642
+ },
643
+ style: {
644
+ selectedPrefix: '❯ ',
645
+ unselectedPrefix: ' ',
646
+ tabActiveInverse: true,
647
+ tabBrackets: ['', ''],
648
+ headerUppercase: false,
649
+ showFunctionKeys: false,
650
+ loadingChars: ['●', '○'],
651
+ },
652
+ };
653
+ // Dracula - Dark theme with vibrant colors
654
+ export const draculaTheme = {
655
+ name: 'dracula',
656
+ displayName: 'Dracula',
657
+ colors: {
658
+ primary: '#bd93f9',
659
+ secondary: '#8be9fd',
660
+ accent: '#ff79c6',
661
+ muted: '#6272a4',
662
+ border: '#6272a4',
663
+ borderActive: '#bd93f9',
664
+ background: '#282a36',
665
+ statusInbox: '#8be9fd',
666
+ statusNext: '#50fa7b',
667
+ statusWaiting: '#ffb86c',
668
+ statusSomeday: '#ff79c6',
669
+ statusDone: '#6272a4',
670
+ text: '#f8f8f2',
671
+ textMuted: '#6272a4',
672
+ textSelected: '#bd93f9',
673
+ textHighlight: '#50fa7b',
674
+ fnKeyLabel: '#44475a',
675
+ fnKeyText: '#f8f8f2',
676
+ },
677
+ borders: {
678
+ main: 'round',
679
+ modal: 'round',
680
+ list: 'single',
681
+ },
682
+ style: {
683
+ selectedPrefix: '▸ ',
684
+ unselectedPrefix: ' ',
685
+ tabActiveInverse: true,
686
+ tabBrackets: ['', ''],
687
+ headerUppercase: false,
688
+ showFunctionKeys: false,
689
+ loadingChars: ['◆', '◇'],
690
+ },
691
+ };
692
+ // Monokai - Classic editor theme with vibrant syntax colors
693
+ export const monokaiTheme = {
694
+ name: 'monokai',
695
+ displayName: 'Monokai',
696
+ colors: {
697
+ primary: '#f92672',
698
+ secondary: '#66d9ef',
699
+ accent: '#a6e22e',
700
+ muted: '#75715e',
701
+ border: '#75715e',
702
+ borderActive: '#f92672',
703
+ background: '#272822',
704
+ statusInbox: '#66d9ef',
705
+ statusNext: '#a6e22e',
706
+ statusWaiting: '#e6db74',
707
+ statusSomeday: '#ae81ff',
708
+ statusDone: '#75715e',
709
+ text: '#f8f8f2',
710
+ textMuted: '#75715e',
711
+ textSelected: '#f92672',
712
+ textHighlight: '#a6e22e',
713
+ fnKeyLabel: '#3e3d32',
714
+ fnKeyText: '#f8f8f2',
715
+ },
716
+ borders: {
717
+ main: 'single',
718
+ modal: 'round',
719
+ list: 'single',
720
+ },
721
+ style: {
722
+ selectedPrefix: '» ',
723
+ unselectedPrefix: ' ',
724
+ tabActiveInverse: true,
725
+ tabBrackets: ['', ''],
726
+ headerUppercase: false,
727
+ showFunctionKeys: false,
728
+ loadingChars: ['▓', '░'],
729
+ },
730
+ };
731
+ // Gruvbox - Retro groove color scheme
732
+ export const gruvboxTheme = {
733
+ name: 'gruvbox',
734
+ displayName: 'Gruvbox',
735
+ colors: {
736
+ primary: '#fe8019',
737
+ secondary: '#fabd2f',
738
+ accent: '#b8bb26',
739
+ muted: '#665c54',
740
+ border: '#665c54',
741
+ borderActive: '#fe8019',
742
+ background: '#282828',
743
+ statusInbox: '#83a598',
744
+ statusNext: '#b8bb26',
745
+ statusWaiting: '#fabd2f',
746
+ statusSomeday: '#d3869b',
747
+ statusDone: '#665c54',
748
+ text: '#ebdbb2',
749
+ textMuted: '#928374',
750
+ textSelected: '#fe8019',
751
+ textHighlight: '#b8bb26',
752
+ fnKeyLabel: '#3c3836',
753
+ fnKeyText: '#ebdbb2',
754
+ },
755
+ borders: {
756
+ main: 'single',
757
+ modal: 'single',
758
+ list: 'single',
759
+ },
760
+ style: {
761
+ selectedPrefix: '▶ ',
762
+ unselectedPrefix: ' ',
763
+ tabActiveInverse: true,
764
+ tabBrackets: ['[', ']'],
765
+ headerUppercase: false,
766
+ showFunctionKeys: false,
767
+ loadingChars: ['█', '░'],
768
+ },
769
+ };
770
+ // Tokyo Night - A clean dark theme inspired by Tokyo's night lights
771
+ export const tokyoNightTheme = {
772
+ name: 'tokyo-night',
773
+ displayName: 'Tokyo Night',
774
+ colors: {
775
+ primary: '#7aa2f7',
776
+ secondary: '#bb9af7',
777
+ accent: '#7dcfff',
778
+ muted: '#565f89',
779
+ border: '#565f89',
780
+ borderActive: '#7aa2f7',
781
+ background: '#1a1b26',
782
+ statusInbox: '#7aa2f7',
783
+ statusNext: '#9ece6a',
784
+ statusWaiting: '#e0af68',
785
+ statusSomeday: '#bb9af7',
786
+ statusDone: '#565f89',
787
+ text: '#c0caf5',
788
+ textMuted: '#565f89',
789
+ textSelected: '#7dcfff',
790
+ textHighlight: '#9ece6a',
791
+ fnKeyLabel: '#24283b',
792
+ fnKeyText: '#c0caf5',
793
+ },
794
+ borders: {
795
+ main: 'round',
796
+ modal: 'round',
797
+ list: 'single',
798
+ },
799
+ style: {
800
+ selectedPrefix: '› ',
801
+ unselectedPrefix: ' ',
802
+ tabActiveInverse: true,
803
+ tabBrackets: ['', ''],
804
+ headerUppercase: false,
805
+ showFunctionKeys: false,
806
+ loadingChars: ['◉', '◎'],
807
+ },
808
+ };
809
+ // Catppuccin - Soothing pastel theme (Mocha variant)
810
+ export const catppuccinTheme = {
811
+ name: 'catppuccin',
812
+ displayName: 'Catppuccin',
813
+ colors: {
814
+ primary: '#cba6f7',
815
+ secondary: '#89b4fa',
816
+ accent: '#f5c2e7',
817
+ muted: '#6c7086',
818
+ border: '#6c7086',
819
+ borderActive: '#cba6f7',
820
+ background: '#1e1e2e',
821
+ statusInbox: '#89b4fa',
822
+ statusNext: '#a6e3a1',
823
+ statusWaiting: '#f9e2af',
824
+ statusSomeday: '#f5c2e7',
825
+ statusDone: '#6c7086',
826
+ text: '#cdd6f4',
827
+ textMuted: '#6c7086',
828
+ textSelected: '#cba6f7',
829
+ textHighlight: '#a6e3a1',
830
+ fnKeyLabel: '#313244',
831
+ fnKeyText: '#cdd6f4',
832
+ },
833
+ borders: {
834
+ main: 'round',
835
+ modal: 'round',
836
+ list: 'single',
837
+ },
838
+ style: {
839
+ selectedPrefix: '◆ ',
840
+ unselectedPrefix: ' ',
841
+ tabActiveInverse: true,
842
+ tabBrackets: ['', ''],
843
+ headerUppercase: false,
844
+ showFunctionKeys: false,
845
+ loadingChars: ['●', '○'],
846
+ },
847
+ };
848
+ // Ocean - Deep sea inspired blue theme
849
+ export const oceanTheme = {
850
+ name: 'ocean',
851
+ displayName: 'Ocean',
852
+ colors: {
853
+ primary: '#00b4d8',
854
+ secondary: '#0077b6',
855
+ accent: '#90e0ef',
856
+ muted: '#023e8a',
857
+ border: '#0077b6',
858
+ borderActive: '#00b4d8',
859
+ background: '#03045e',
860
+ statusInbox: '#00b4d8',
861
+ statusNext: '#48cae4',
862
+ statusWaiting: '#90e0ef',
863
+ statusSomeday: '#ade8f4',
864
+ statusDone: '#023e8a',
865
+ text: '#caf0f8',
866
+ textMuted: '#0077b6',
867
+ textSelected: '#90e0ef',
868
+ textHighlight: '#48cae4',
869
+ fnKeyLabel: '#023e8a',
870
+ fnKeyText: '#caf0f8',
871
+ },
872
+ borders: {
873
+ main: 'round',
874
+ modal: 'round',
875
+ list: 'single',
876
+ },
877
+ style: {
878
+ selectedPrefix: '≋ ',
879
+ unselectedPrefix: ' ',
880
+ tabActiveInverse: true,
881
+ tabBrackets: ['〔', '〕'],
882
+ headerUppercase: false,
883
+ showFunctionKeys: false,
884
+ loadingChars: ['◐', '◑'],
885
+ },
886
+ };
887
+ // Sakura - Cherry blossom inspired pink theme
888
+ export const sakuraTheme = {
889
+ name: 'sakura',
890
+ displayName: 'Sakura',
891
+ colors: {
892
+ primary: '#ffb7c5',
893
+ secondary: '#ff8fa3',
894
+ accent: '#ffffff',
895
+ muted: '#c9184a',
896
+ border: '#ff8fa3',
897
+ borderActive: '#ffb7c5',
898
+ background: '#590d22',
899
+ statusInbox: '#ffb7c5',
900
+ statusNext: '#ff758f',
901
+ statusWaiting: '#ffccd5',
902
+ statusSomeday: '#ff4d6d',
903
+ statusDone: '#800f2f',
904
+ text: '#fff0f3',
905
+ textMuted: '#a4133c',
906
+ textSelected: '#ffffff',
907
+ textHighlight: '#ff758f',
908
+ fnKeyLabel: '#800f2f',
909
+ fnKeyText: '#ffb7c5',
910
+ },
911
+ borders: {
912
+ main: 'round',
913
+ modal: 'round',
914
+ list: 'single',
915
+ },
916
+ style: {
917
+ selectedPrefix: '❀ ',
918
+ unselectedPrefix: ' ',
919
+ tabActiveInverse: true,
920
+ tabBrackets: ['『', '』'],
921
+ headerUppercase: false,
922
+ showFunctionKeys: false,
923
+ loadingChars: ['✿', '❀'],
924
+ },
925
+ };
926
+ // MSX - Japanese retro computer style (TMS9918 palette)
927
+ export const msxTheme = {
928
+ name: 'msx',
929
+ displayName: 'MSX',
930
+ colors: {
931
+ primary: '#40b64a',
932
+ secondary: '#5955df',
933
+ accent: '#ffffff',
934
+ muted: '#cacaca',
935
+ border: '#40b64a',
936
+ borderActive: '#73ce7c',
937
+ background: '#000000',
938
+ statusInbox: '#64daee',
939
+ statusNext: '#40b64a',
940
+ statusWaiting: '#ddce85',
941
+ statusSomeday: '#b565b3',
942
+ statusDone: '#cacaca',
943
+ text: '#40b64a',
944
+ textMuted: '#cacaca',
945
+ textSelected: '#ffffff',
946
+ textHighlight: '#73ce7c',
947
+ fnKeyLabel: '#64daee',
948
+ fnKeyText: '#000000',
949
+ },
950
+ borders: {
951
+ main: 'single',
952
+ modal: 'single',
953
+ list: 'single',
954
+ },
955
+ style: {
956
+ selectedPrefix: '> ',
957
+ unselectedPrefix: ' ',
958
+ tabActiveInverse: true,
959
+ tabBrackets: ['[', ']'],
960
+ headerUppercase: true,
961
+ showFunctionKeys: true,
962
+ loadingChars: ['■', '□'],
963
+ },
964
+ };
965
+ // PC-98 - NEC PC-9801 style
966
+ export const pc98Theme = {
967
+ name: 'pc-98',
968
+ displayName: 'PC-98',
969
+ colors: {
970
+ primary: '#ffffff',
971
+ secondary: '#00ffff',
972
+ accent: '#ffff00',
973
+ muted: '#808080',
974
+ border: '#ffffff',
975
+ borderActive: '#00ffff',
976
+ background: '#000080',
977
+ statusInbox: '#00ffff',
978
+ statusNext: '#00ff00',
979
+ statusWaiting: '#ffff00',
980
+ statusSomeday: '#ff00ff',
981
+ statusDone: '#808080',
982
+ text: '#ffffff',
983
+ textMuted: '#808080',
984
+ textSelected: '#ffff00',
985
+ textHighlight: '#00ffff',
986
+ fnKeyLabel: '#00ffff',
987
+ fnKeyText: '#ffffff',
988
+ },
989
+ borders: {
990
+ main: 'single',
991
+ modal: 'double',
992
+ list: 'single',
993
+ },
994
+ style: {
995
+ selectedPrefix: '▶ ',
996
+ unselectedPrefix: ' ',
997
+ tabActiveInverse: true,
998
+ tabBrackets: ['【', '】'],
999
+ headerUppercase: false,
1000
+ showFunctionKeys: true,
1001
+ loadingChars: ['●', '○'],
1002
+ },
1003
+ };
614
1004
  export const themes = {
615
1005
  'modern': modernTheme,
616
1006
  'norton-commander': nortonCommanderTheme,
@@ -628,6 +1018,16 @@ export const themes = {
628
1018
  'synthwave': synthwaveTheme,
629
1019
  'paper': paperTheme,
630
1020
  'coffee': coffeeTheme,
1021
+ 'nord': nordTheme,
1022
+ 'dracula': draculaTheme,
1023
+ 'monokai': monokaiTheme,
1024
+ 'gruvbox': gruvboxTheme,
1025
+ 'tokyo-night': tokyoNightTheme,
1026
+ 'catppuccin': catppuccinTheme,
1027
+ 'ocean': oceanTheme,
1028
+ 'sakura': sakuraTheme,
1029
+ 'msx': msxTheme,
1030
+ 'pc-98': pc98Theme,
631
1031
  };
632
1032
  export const VALID_THEMES = [
633
1033
  'modern',
@@ -646,6 +1046,16 @@ export const VALID_THEMES = [
646
1046
  'synthwave',
647
1047
  'paper',
648
1048
  'coffee',
1049
+ 'nord',
1050
+ 'dracula',
1051
+ 'monokai',
1052
+ 'gruvbox',
1053
+ 'tokyo-night',
1054
+ 'catppuccin',
1055
+ 'ocean',
1056
+ 'sakura',
1057
+ 'msx',
1058
+ 'pc-98',
649
1059
  ];
650
1060
  export function getTheme(name) {
651
1061
  return themes[name] || modernTheme;