floq 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.ja.md +89 -9
  2. package/README.md +89 -9
  3. package/dist/changelog.d.ts +13 -0
  4. package/dist/changelog.js +95 -0
  5. package/dist/cli.js +44 -1
  6. package/dist/commands/comment.d.ts +2 -0
  7. package/dist/commands/comment.js +67 -0
  8. package/dist/commands/config.d.ts +4 -0
  9. package/dist/commands/config.js +123 -1
  10. package/dist/commands/setup.d.ts +1 -0
  11. package/dist/commands/setup.js +13 -0
  12. package/dist/config.d.ts +5 -0
  13. package/dist/config.js +40 -3
  14. package/dist/db/index.js +20 -0
  15. package/dist/db/schema.d.ts +83 -0
  16. package/dist/db/schema.js +6 -0
  17. package/dist/i18n/en.d.ts +237 -0
  18. package/dist/i18n/en.js +127 -3
  19. package/dist/i18n/ja.js +127 -3
  20. package/dist/index.js +14 -4
  21. package/dist/paths.d.ts +4 -0
  22. package/dist/paths.js +63 -5
  23. package/dist/ui/App.js +280 -25
  24. package/dist/ui/ModeSelector.d.ts +7 -0
  25. package/dist/ui/ModeSelector.js +37 -0
  26. package/dist/ui/SetupWizard.d.ts +6 -0
  27. package/dist/ui/SetupWizard.js +321 -0
  28. package/dist/ui/components/HelpModal.d.ts +2 -1
  29. package/dist/ui/components/HelpModal.js +118 -4
  30. package/dist/ui/components/KanbanBoard.d.ts +6 -0
  31. package/dist/ui/components/KanbanBoard.js +508 -0
  32. package/dist/ui/components/KanbanColumn.d.ts +12 -0
  33. package/dist/ui/components/KanbanColumn.js +11 -0
  34. package/dist/ui/components/ProgressBar.d.ts +7 -0
  35. package/dist/ui/components/ProgressBar.js +13 -0
  36. package/dist/ui/components/SearchBar.d.ts +8 -0
  37. package/dist/ui/components/SearchBar.js +11 -0
  38. package/dist/ui/components/SearchResults.d.ts +9 -0
  39. package/dist/ui/components/SearchResults.js +18 -0
  40. package/dist/ui/components/TaskItem.d.ts +6 -1
  41. package/dist/ui/components/TaskItem.js +3 -2
  42. package/package.json +1 -1
package/README.ja.md CHANGED
@@ -7,12 +7,16 @@ MS-DOSスタイルのテーマを備えたターミナルベースのGTD(Getti
7
7
  ## 特徴
8
8
 
9
9
  - **TUIインターフェース**: Ink(CLI用React)で構築されたインタラクティブなターミナルUI
10
- - **GTDワークフロー**: Inbox、Next Actions、Waiting For、Someday/Maybe
11
- - **プロジェクト**: タスクをプロジェクトに整理
10
+ - **GTDワークフロー**: Inbox、Next Actions、Waiting For、Someday/Maybe、Done
11
+ - **カンバンモード**: 3カラムのカンバンボード表示(TODO、Doing、Done)
12
+ - **プロジェクト**: タスクをプロジェクトに整理(進捗バー表示付き)
13
+ - **タスク検索**: `/` キーで全タスクを素早く検索
14
+ - **コメント**: タスクにメモやコメントを追加
12
15
  - **クラウド同期**: [Turso](https://turso.tech/)のembedded replicasによるオプションの同期機能
13
16
  - **テーマ**: MS-DOSノスタルジックスタイルを含む複数テーマ
14
17
  - **多言語対応**: 英語・日本語サポート
15
18
  - **Vimスタイルナビゲーション**: hjklまたは矢印キーで操作
19
+ - **セットアップウィザード**: 初回起動時の簡単設定
16
20
 
17
21
  ## インストール
18
22
 
@@ -38,11 +42,11 @@ npm link
38
42
  floq
39
43
  ```
40
44
 
41
- ### キーボードショートカット
45
+ ### キーボードショートカット(GTDモード)
42
46
 
43
47
  | キー | アクション |
44
48
  |------|-----------|
45
- | `1-5` | タブ切り替え |
49
+ | `1-6` | タブ切り替え(Inbox/Next/Waiting/Someday/Projects/Done) |
46
50
  | `h/l` または `←/→` | 前/次のタブ |
47
51
  | `j/k` または `↑/↓` | タスク選択 |
48
52
  | `a` | タスク追加 |
@@ -50,14 +54,75 @@ floq
50
54
  | `n` | Next Actionsに移動 |
51
55
  | `s` | Someday/Maybeに移動 |
52
56
  | `i` | Inboxに移動 |
57
+ | `w` | Waiting Forに移動(担当者入力) |
53
58
  | `p` | プロジェクトに変換 |
54
59
  | `P` | プロジェクトに紐付け |
55
- | `Enter` | プロジェクトを開く(Projectsタブ) |
56
- | `Esc/b` | プロジェクトから戻る |
60
+ | `Enter` | タスク詳細を開く / プロジェクトを開く |
61
+ | `Esc/b` | 戻る |
62
+ | `/` | タスク検索 |
57
63
  | `r` | 更新 |
58
64
  | `?` | ヘルプ |
59
65
  | `q` | 終了 |
60
66
 
67
+ #### プロジェクト詳細画面
68
+
69
+ | キー | アクション |
70
+ |------|-----------|
71
+ | `j/k` | タスク選択 |
72
+ | `a` | プロジェクトにタスク追加 |
73
+ | `d` | タスクを完了にする |
74
+ | `Enter` | タスク詳細を開く |
75
+ | `Esc/b` | プロジェクト一覧に戻る |
76
+
77
+ #### タスク詳細画面
78
+
79
+ | キー | アクション |
80
+ |------|-----------|
81
+ | `i` | コメント追加 |
82
+ | `d` | 選択中のコメントを削除 |
83
+ | `P` | プロジェクトに紐付け |
84
+ | `j/k` | コメント選択 |
85
+ | `Esc/b` | 一覧 / プロジェクトに戻る |
86
+
87
+ ### キーボードショートカット(カンバンモード)
88
+
89
+ | キー | アクション |
90
+ |------|-----------|
91
+ | `1-3` | カラム切り替え(TODO/Doing/Done) |
92
+ | `h/l` または `←/→` | 前/次のカラム |
93
+ | `j/k` または `↑/↓` | タスク選択 |
94
+ | `a` | タスク追加 |
95
+ | `d` | 完了にする |
96
+ | `m` | タスクを右に移動(→) |
97
+ | `Backspace` | タスクを左に移動(←) |
98
+ | `Enter` | タスク詳細を開く |
99
+ | `/` | タスク検索 |
100
+ | `r` | 更新 |
101
+ | `?` | ヘルプ |
102
+ | `q` | 終了 |
103
+
104
+ #### タスク詳細画面(カンバン)
105
+
106
+ | キー | アクション |
107
+ |------|-----------|
108
+ | `i` | コメント追加 |
109
+ | `d` | 選択中のコメントを削除 |
110
+ | `j/k` | コメント選択 |
111
+ | `Esc/b` | ボードに戻る |
112
+
113
+ ### セットアップウィザード
114
+
115
+ 初回起動時、Floqはインタラクティブなセットアップウィザードを起動します:
116
+ - 言語(英語/日本語)
117
+ - テーマ選択
118
+ - 表示モード(GTD/カンバン)
119
+
120
+ 手動でウィザードを起動することもできます:
121
+
122
+ ```bash
123
+ floq setup
124
+ ```
125
+
61
126
  ### CLIコマンド
62
127
 
63
128
  ```bash
@@ -86,6 +151,10 @@ floq project add "プロジェクト名"
86
151
  floq project list
87
152
  floq project show <id>
88
153
  floq project complete <id>
154
+
155
+ # コメント
156
+ floq comment <id> "コメント内容" # コメント追加
157
+ floq comment <id> # コメント一覧
89
158
  ```
90
159
 
91
160
  ## 設定
@@ -105,9 +174,20 @@ floq config theme
105
174
  floq config theme modern # デフォルト
106
175
  floq config theme synthwave # ネオン80sスタイル
107
176
 
177
+ # 表示モード設定(インタラクティブセレクター)
178
+ floq config mode
179
+
180
+ # または直接指定
181
+ floq config mode gtd # GTDワークフロー(デフォルト)
182
+ floq config mode kanban # カンバンボード
183
+
108
184
  # データベースパス設定
109
185
  floq config db /path/to/custom.db
110
186
  floq config db # デフォルトに戻す
187
+
188
+ # データベースリセット(全データ削除)
189
+ floq db reset # 確認あり
190
+ floq db reset --force # 確認なし
111
191
  ```
112
192
 
113
193
  ## クラウド同期(Turso)
@@ -139,7 +219,7 @@ floq config turso --disable
139
219
  - **Embedded Replicas**: ローカルSQLiteデータベースがTursoクラウドと同期
140
220
  - **オフラインサポート**: オフラインでも動作し、接続時に同期
141
221
  - **自動同期**: オンライン時は60秒ごとにバックグラウンド同期
142
- - **データベース分離**: Tursoモードは`gtd-turso.db`を使用し、ローカルDBと競合しない
222
+ - **データベース分離**: Tursoモードは`floq-turso.db`を使用し、ローカルDBと競合しない
143
223
 
144
224
  ### ステータス表示
145
225
 
@@ -173,8 +253,8 @@ floq config turso --disable
173
253
 
174
254
  ## データ保存場所
175
255
 
176
- - 設定: `~/.config/gtd-cli/config.json`
177
- - データベース: `~/.local/share/gtd-cli/gtd.db`
256
+ - 設定: `~/.config/floq/config.json`
257
+ - データベース: `~/.local/share/floq/floq.db`(Turso有効時は`floq-turso.db`)
178
258
 
179
259
  ## ライセンス
180
260
 
package/README.md CHANGED
@@ -7,12 +7,16 @@ A terminal-based GTD (Getting Things Done) task manager with MS-DOS style themes
7
7
  ## Features
8
8
 
9
9
  - **TUI Interface**: Interactive terminal UI built with Ink (React for CLI)
10
- - **GTD Workflow**: Inbox, Next Actions, Waiting For, Someday/Maybe
11
- - **Projects**: Organize tasks into projects
10
+ - **GTD Workflow**: Inbox, Next Actions, Waiting For, Someday/Maybe, Done
11
+ - **Kanban Mode**: 3-column kanban board view (TODO, Doing, Done)
12
+ - **Projects**: Organize tasks into projects with progress tracking
13
+ - **Task Search**: Quick search across all tasks with `/`
14
+ - **Comments**: Add notes and comments to tasks
12
15
  - **Cloud Sync**: Optional sync with [Turso](https://turso.tech/) using embedded replicas
13
16
  - **Themes**: Multiple themes including MS-DOS nostalgic styles
14
17
  - **i18n**: English and Japanese support
15
18
  - **Vim-style Navigation**: Use hjkl or arrow keys
19
+ - **Setup Wizard**: First-run wizard for easy configuration
16
20
 
17
21
  ## Installation
18
22
 
@@ -38,11 +42,11 @@ npm link
38
42
  floq
39
43
  ```
40
44
 
41
- ### Keyboard Shortcuts
45
+ ### Keyboard Shortcuts (GTD Mode)
42
46
 
43
47
  | Key | Action |
44
48
  |-----|--------|
45
- | `1-5` | Switch tabs |
49
+ | `1-6` | Switch tabs (Inbox/Next/Waiting/Someday/Projects/Done) |
46
50
  | `h/l` or `←/→` | Previous/Next tab |
47
51
  | `j/k` or `↑/↓` | Navigate tasks |
48
52
  | `a` | Add task |
@@ -50,14 +54,75 @@ floq
50
54
  | `n` | Move to Next Actions |
51
55
  | `s` | Move to Someday/Maybe |
52
56
  | `i` | Move to Inbox |
57
+ | `w` | Move to Waiting For (prompts for person) |
53
58
  | `p` | Convert to project |
54
59
  | `P` | Link to project |
55
- | `Enter` | Open project (on Projects tab) |
56
- | `Esc/b` | Back from project |
60
+ | `Enter` | Open task detail / Open project |
61
+ | `Esc/b` | Back |
62
+ | `/` | Search tasks |
57
63
  | `r` | Refresh |
58
64
  | `?` | Help |
59
65
  | `q` | Quit |
60
66
 
67
+ #### Project Detail View
68
+
69
+ | Key | Action |
70
+ |-----|--------|
71
+ | `j/k` | Navigate tasks |
72
+ | `a` | Add task to project |
73
+ | `d` | Mark task as done |
74
+ | `Enter` | Open task detail |
75
+ | `Esc/b` | Back to projects list |
76
+
77
+ #### Task Detail View
78
+
79
+ | Key | Action |
80
+ |-----|--------|
81
+ | `i` | Add comment |
82
+ | `d` | Delete selected comment |
83
+ | `P` | Link to project |
84
+ | `j/k` | Navigate comments |
85
+ | `Esc/b` | Back to list / project |
86
+
87
+ ### Keyboard Shortcuts (Kanban Mode)
88
+
89
+ | Key | Action |
90
+ |-----|--------|
91
+ | `1-3` | Switch columns (TODO/Doing/Done) |
92
+ | `h/l` or `←/→` | Previous/Next column |
93
+ | `j/k` or `↑/↓` | Navigate tasks |
94
+ | `a` | Add task |
95
+ | `d` | Mark as done |
96
+ | `m` | Move task right (→) |
97
+ | `Backspace` | Move task left (←) |
98
+ | `Enter` | Open task detail |
99
+ | `/` | Search tasks |
100
+ | `r` | Refresh |
101
+ | `?` | Help |
102
+ | `q` | Quit |
103
+
104
+ #### Task Detail View (Kanban)
105
+
106
+ | Key | Action |
107
+ |-----|--------|
108
+ | `i` | Add comment |
109
+ | `d` | Delete selected comment |
110
+ | `j/k` | Navigate comments |
111
+ | `Esc/b` | Back to board |
112
+
113
+ ### Setup Wizard
114
+
115
+ On first run, Floq will launch an interactive setup wizard to configure:
116
+ - Language (English/Japanese)
117
+ - Theme selection
118
+ - View mode (GTD/Kanban)
119
+
120
+ You can also run the wizard manually:
121
+
122
+ ```bash
123
+ floq setup
124
+ ```
125
+
61
126
  ### CLI Commands
62
127
 
63
128
  ```bash
@@ -86,6 +151,10 @@ floq project add "Project name"
86
151
  floq project list
87
152
  floq project show <id>
88
153
  floq project complete <id>
154
+
155
+ # Comments
156
+ floq comment <id> "Comment text" # Add comment
157
+ floq comment <id> # List comments
89
158
  ```
90
159
 
91
160
  ## Configuration
@@ -105,9 +174,20 @@ floq config theme
105
174
  floq config theme modern # Default
106
175
  floq config theme synthwave # Neon 80s aesthetic
107
176
 
177
+ # Set view mode (interactive selector)
178
+ floq config mode
179
+
180
+ # Or specify directly
181
+ floq config mode gtd # GTD workflow (default)
182
+ floq config mode kanban # Kanban board
183
+
108
184
  # Set database path
109
185
  floq config db /path/to/custom.db
110
186
  floq config db # Reset to default
187
+
188
+ # Reset database (delete all data)
189
+ floq db reset # With confirmation
190
+ floq db reset --force # Skip confirmation
111
191
  ```
112
192
 
113
193
  ## Cloud Sync (Turso)
@@ -139,7 +219,7 @@ floq config turso --disable
139
219
  - **Embedded Replicas**: Local SQLite database syncs with Turso cloud
140
220
  - **Offline Support**: Works offline, syncs when connected
141
221
  - **Auto Sync**: Background sync every 60 seconds when online
142
- - **Separate Database**: Turso mode uses `gtd-turso.db` to avoid conflicts
222
+ - **Separate Database**: Turso mode uses `floq-turso.db` to avoid conflicts
143
223
 
144
224
  ### Status Indicator
145
225
 
@@ -173,8 +253,8 @@ floq config turso --disable
173
253
 
174
254
  ## Data Storage
175
255
 
176
- - Config: `~/.config/gtd-cli/config.json`
177
- - Database: `~/.local/share/gtd-cli/gtd.db`
256
+ - Config: `~/.config/floq/config.json`
257
+ - Database: `~/.local/share/floq/floq.db` (or `floq-turso.db` with Turso enabled)
178
258
 
179
259
  ## License
180
260
 
@@ -0,0 +1,13 @@
1
+ export interface ChangelogEntry {
2
+ version: string;
3
+ date: string;
4
+ sections: {
5
+ type: 'Added' | 'Changed' | 'Deprecated' | 'Removed' | 'Fixed' | 'Security';
6
+ items: string[];
7
+ }[];
8
+ }
9
+ export interface Changelog {
10
+ entries: ChangelogEntry[];
11
+ }
12
+ export declare function parseChangelog(): Changelog;
13
+ export declare function getLatestVersion(): string;
@@ -0,0 +1,95 @@
1
+ import { readFileSync } from 'fs';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ function findChangelogPath() {
5
+ // Get the directory of the current module
6
+ const currentFile = fileURLToPath(import.meta.url);
7
+ const currentDir = dirname(currentFile);
8
+ // Try to find CHANGELOG.md relative to the package root
9
+ // From dist/ or src/, go up one level
10
+ const possiblePaths = [
11
+ join(currentDir, '..', 'CHANGELOG.md'),
12
+ join(currentDir, '..', '..', 'CHANGELOG.md'),
13
+ join(process.cwd(), 'CHANGELOG.md'),
14
+ ];
15
+ for (const path of possiblePaths) {
16
+ try {
17
+ readFileSync(path, 'utf-8');
18
+ return path;
19
+ }
20
+ catch {
21
+ // continue to next path
22
+ }
23
+ }
24
+ return possiblePaths[0]; // Return first path as fallback
25
+ }
26
+ export function parseChangelog() {
27
+ const changelogPath = findChangelogPath();
28
+ let content;
29
+ try {
30
+ content = readFileSync(changelogPath, 'utf-8');
31
+ }
32
+ catch {
33
+ return { entries: [] };
34
+ }
35
+ const entries = [];
36
+ const lines = content.split('\n');
37
+ let currentEntry = null;
38
+ let currentSection = null;
39
+ for (const line of lines) {
40
+ // Match version header: ## [0.1.0] - 2025-01-29 or ## [Unreleased]
41
+ const versionMatch = line.match(/^## \[([^\]]+)\](?:\s*-\s*(.+))?$/);
42
+ if (versionMatch) {
43
+ if (currentEntry) {
44
+ if (currentSection && currentSection.items.length > 0) {
45
+ currentEntry.sections.push(currentSection);
46
+ }
47
+ if (currentEntry.sections.length > 0 || currentEntry.version !== 'Unreleased') {
48
+ entries.push(currentEntry);
49
+ }
50
+ }
51
+ currentEntry = {
52
+ version: versionMatch[1],
53
+ date: versionMatch[2]?.trim() || '',
54
+ sections: [],
55
+ };
56
+ currentSection = null;
57
+ continue;
58
+ }
59
+ // Match section header: ### Added, ### Changed, etc.
60
+ const sectionMatch = line.match(/^### (Added|Changed|Deprecated|Removed|Fixed|Security)$/);
61
+ if (sectionMatch && currentEntry) {
62
+ if (currentSection && currentSection.items.length > 0) {
63
+ currentEntry.sections.push(currentSection);
64
+ }
65
+ currentSection = {
66
+ type: sectionMatch[1],
67
+ items: [],
68
+ };
69
+ continue;
70
+ }
71
+ // Match list item: - Item description
72
+ const itemMatch = line.match(/^- (.+)$/);
73
+ if (itemMatch && currentSection) {
74
+ currentSection.items.push(itemMatch[1]);
75
+ }
76
+ }
77
+ // Add last entry
78
+ if (currentEntry) {
79
+ if (currentSection && currentSection.items.length > 0) {
80
+ currentEntry.sections.push(currentSection);
81
+ }
82
+ if (currentEntry.sections.length > 0) {
83
+ entries.push(currentEntry);
84
+ }
85
+ }
86
+ // Filter out Unreleased if it has no content
87
+ return {
88
+ entries: entries.filter(e => e.version !== 'Unreleased' || e.sections.length > 0),
89
+ };
90
+ }
91
+ export function getLatestVersion() {
92
+ const changelog = parseChangelog();
93
+ const released = changelog.entries.find(e => e.version !== 'Unreleased');
94
+ return released?.version || '0.0.0';
95
+ }
package/dist/cli.js CHANGED
@@ -7,7 +7,9 @@ import { listTasks, listProjects } from './commands/list.js';
7
7
  import { moveTask } from './commands/move.js';
8
8
  import { markDone } from './commands/done.js';
9
9
  import { addProject, listProjectsCommand, showProject, completeProject, } from './commands/project.js';
10
- import { showConfig, setLanguage, setDbPath, resetDbPath, setTheme, selectTheme, setTurso, disableTurso, syncCommand } from './commands/config.js';
10
+ import { showConfig, setLanguage, setDbPath, resetDbPath, setTheme, selectTheme, setViewModeCommand, selectMode, setTurso, disableTurso, syncCommand, resetDatabase } from './commands/config.js';
11
+ import { addComment, listComments } from './commands/comment.js';
12
+ import { runSetupWizard } from './commands/setup.js';
11
13
  import { VERSION } from './version.js';
12
14
  const program = new Command();
13
15
  program
@@ -121,6 +123,17 @@ configCmd
121
123
  await selectTheme();
122
124
  }
123
125
  });
126
+ configCmd
127
+ .command('mode [mode]')
128
+ .description('Set view mode (gtd, kanban) or select interactively')
129
+ .action(async (mode) => {
130
+ if (mode) {
131
+ await setViewModeCommand(mode);
132
+ }
133
+ else {
134
+ await selectMode();
135
+ }
136
+ });
124
137
  configCmd
125
138
  .command('turso')
126
139
  .description('Configure Turso cloud sync')
@@ -147,4 +160,34 @@ program
147
160
  .action(async () => {
148
161
  await syncCommand();
149
162
  });
163
+ // Database commands
164
+ const dbCmd = program
165
+ .command('db')
166
+ .description('Database management commands');
167
+ dbCmd
168
+ .command('reset')
169
+ .description('Reset the database (delete all data)')
170
+ .option('-f, --force', 'Skip confirmation')
171
+ .action(async (options) => {
172
+ await resetDatabase(options.force ?? false);
173
+ });
174
+ // Comment command
175
+ program
176
+ .command('comment <taskId> [content]')
177
+ .description('Add or list comments for a task')
178
+ .action(async (taskId, content) => {
179
+ if (content) {
180
+ await addComment(taskId, content);
181
+ }
182
+ else {
183
+ await listComments(taskId);
184
+ }
185
+ });
186
+ // Setup wizard command
187
+ program
188
+ .command('setup')
189
+ .description('Run the setup wizard')
190
+ .action(async () => {
191
+ await runSetupWizard();
192
+ });
150
193
  export { program };
@@ -0,0 +1,2 @@
1
+ export declare function addComment(taskId: string, content: string): Promise<void>;
2
+ export declare function listComments(taskId: string): Promise<void>;
@@ -0,0 +1,67 @@
1
+ import { eq, like } from 'drizzle-orm';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import { getDb, schema } from '../db/index.js';
4
+ import { t, fmt } from '../i18n/index.js';
5
+ export async function addComment(taskId, content) {
6
+ const db = getDb();
7
+ const i18n = t();
8
+ // Find task by ID prefix
9
+ const tasks = await db
10
+ .select()
11
+ .from(schema.tasks)
12
+ .where(like(schema.tasks.id, `${taskId}%`));
13
+ if (tasks.length === 0) {
14
+ console.error(fmt(i18n.commands.comment.notFound, { id: taskId }));
15
+ process.exit(1);
16
+ }
17
+ if (tasks.length > 1) {
18
+ console.error(fmt(i18n.commands.comment.multipleMatch, { id: taskId }));
19
+ for (const task of tasks) {
20
+ console.error(` [${task.id.slice(0, 8)}] ${task.title}`);
21
+ }
22
+ process.exit(1);
23
+ }
24
+ const task = tasks[0];
25
+ await db.insert(schema.comments).values({
26
+ id: uuidv4(),
27
+ taskId: task.id,
28
+ content: content.trim(),
29
+ createdAt: new Date(),
30
+ });
31
+ console.log(fmt(i18n.commands.comment.added, { title: task.title }));
32
+ }
33
+ export async function listComments(taskId) {
34
+ const db = getDb();
35
+ const i18n = t();
36
+ // Find task by ID prefix
37
+ const tasks = await db
38
+ .select()
39
+ .from(schema.tasks)
40
+ .where(like(schema.tasks.id, `${taskId}%`));
41
+ if (tasks.length === 0) {
42
+ console.error(fmt(i18n.commands.comment.notFound, { id: taskId }));
43
+ process.exit(1);
44
+ }
45
+ if (tasks.length > 1) {
46
+ console.error(fmt(i18n.commands.comment.multipleMatch, { id: taskId }));
47
+ for (const task of tasks) {
48
+ console.error(` [${task.id.slice(0, 8)}] ${task.title}`);
49
+ }
50
+ process.exit(1);
51
+ }
52
+ const task = tasks[0];
53
+ const comments = await db
54
+ .select()
55
+ .from(schema.comments)
56
+ .where(eq(schema.comments.taskId, task.id));
57
+ if (comments.length === 0) {
58
+ console.log(fmt(i18n.commands.comment.listHeader, { title: task.title }));
59
+ console.log(` ${i18n.commands.comment.noComments}`);
60
+ return;
61
+ }
62
+ console.log(fmt(i18n.commands.comment.listHeader, { title: task.title }));
63
+ for (const comment of comments) {
64
+ const date = comment.createdAt.toLocaleString();
65
+ console.log(` [${date}] ${comment.content}`);
66
+ }
67
+ }
@@ -4,6 +4,10 @@ export declare function setDbPath(dbPath: string): Promise<void>;
4
4
  export declare function resetDbPath(): Promise<void>;
5
5
  export declare function setTheme(theme: string): Promise<void>;
6
6
  export declare function selectTheme(): Promise<void>;
7
+ export declare function showViewMode(): Promise<void>;
8
+ export declare function setViewModeCommand(mode: string): Promise<void>;
9
+ export declare function selectMode(): Promise<void>;
7
10
  export declare function setTurso(url: string, token: string): Promise<void>;
8
11
  export declare function disableTurso(): Promise<void>;
9
12
  export declare function syncCommand(): Promise<void>;
13
+ export declare function resetDatabase(force: boolean): Promise<void>;