floq 0.3.1 → 0.5.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.
- package/README.ja.md +12 -1
- package/README.md +12 -1
- package/dist/cli.js +24 -0
- package/dist/commands/add.d.ts +1 -0
- package/dist/commands/add.js +2 -0
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.js +36 -0
- package/dist/commands/list.js +17 -5
- package/dist/config.d.ts +4 -0
- package/dist/config.js +25 -0
- package/dist/db/index.js +16 -0
- package/dist/db/schema.d.ts +19 -0
- package/dist/db/schema.js +1 -0
- package/dist/i18n/en.d.ts +44 -0
- package/dist/i18n/en.js +26 -0
- package/dist/i18n/ja.js +26 -0
- package/dist/ui/App.js +187 -13
- package/dist/ui/components/KanbanBoard.js +173 -16
- package/dist/ui/components/SearchResults.d.ts +2 -1
- package/dist/ui/components/SearchResults.js +22 -2
- package/dist/ui/components/TaskItem.js +1 -1
- package/dist/ui/history/commands/SetContextCommand.d.ts +20 -0
- package/dist/ui/history/commands/SetContextCommand.js +37 -0
- package/dist/ui/history/commands/index.d.ts +1 -0
- package/dist/ui/history/commands/index.js +1 -0
- package/dist/ui/history/index.d.ts +1 -1
- package/dist/ui/history/index.js +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -7,9 +7,10 @@ MS-DOSスタイルのテーマを備えたターミナルベースのGTD(Getti
|
|
|
7
7
|
## 特徴
|
|
8
8
|
|
|
9
9
|
- **TUIインターフェース**: Ink(CLI用React)で構築されたインタラクティブなターミナルUI
|
|
10
|
-
- **GTDワークフロー**: Inbox、Next Actions、Waiting For、Someday/Maybe、Done
|
|
10
|
+
- **GTDワークフロー**: Inbox、Next Actions、Waiting For、Someday/Maybe、Done(過去7日間表示)
|
|
11
11
|
- **カンバンモード**: 3カラムのカンバンボード表示(TODO、Doing、Done)
|
|
12
12
|
- **プロジェクト**: タスクをプロジェクトに整理(進捗バー表示付き)
|
|
13
|
+
- **コンテキスト**: タスクにコンテキスト(@work、@homeなど)を設定してフィルタリング。タスク追加時は現在のフィルターを自動継承
|
|
13
14
|
- **タスク検索**: `/` キーで全タスクを素早く検索
|
|
14
15
|
- **コメント**: タスクにメモやコメントを追加
|
|
15
16
|
- **クラウド同期**: [Turso](https://turso.tech/)のembedded replicasによるオプションの同期機能
|
|
@@ -57,6 +58,8 @@ floq
|
|
|
57
58
|
| `w` | Waiting Forに移動(担当者入力) |
|
|
58
59
|
| `p` | プロジェクトに変換 |
|
|
59
60
|
| `P` | プロジェクトに紐付け |
|
|
61
|
+
| `c` | コンテキスト設定 |
|
|
62
|
+
| `@` | コンテキストでフィルター |
|
|
60
63
|
| `Enter` | タスク詳細を開く / プロジェクトを開く |
|
|
61
64
|
| `Esc/b` | 戻る |
|
|
62
65
|
| `/` | タスク検索 |
|
|
@@ -106,6 +109,8 @@ floq
|
|
|
106
109
|
| `d` | 完了にする |
|
|
107
110
|
| `m` | タスクを右に移動(→) |
|
|
108
111
|
| `Backspace` | タスクを左に移動(←) |
|
|
112
|
+
| `c` | コンテキスト設定 |
|
|
113
|
+
| `@` | コンテキストでフィルター |
|
|
109
114
|
| `Enter` | タスク詳細を開く |
|
|
110
115
|
| `/` | タスク検索 |
|
|
111
116
|
| `r` | 更新 |
|
|
@@ -142,6 +147,7 @@ floq setup
|
|
|
142
147
|
# タスク追加
|
|
143
148
|
floq add "タスクのタイトル"
|
|
144
149
|
floq add "タスクのタイトル" -p "プロジェクト名"
|
|
150
|
+
floq add "タスクのタイトル" -c work # コンテキスト付き
|
|
145
151
|
|
|
146
152
|
# タスク一覧
|
|
147
153
|
floq list # 未完了タスク全て
|
|
@@ -168,6 +174,11 @@ floq project complete <id>
|
|
|
168
174
|
# コメント
|
|
169
175
|
floq comment <id> "コメント内容" # コメント追加
|
|
170
176
|
floq comment <id> # コメント一覧
|
|
177
|
+
|
|
178
|
+
# コンテキスト
|
|
179
|
+
floq context list # コンテキスト一覧
|
|
180
|
+
floq context add <name> # コンテキスト追加
|
|
181
|
+
floq context remove <name> # コンテキスト削除
|
|
171
182
|
```
|
|
172
183
|
|
|
173
184
|
## 設定
|
package/README.md
CHANGED
|
@@ -7,9 +7,10 @@ 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, Done
|
|
10
|
+
- **GTD Workflow**: Inbox, Next Actions, Waiting For, Someday/Maybe, Done (shows last 7 days)
|
|
11
11
|
- **Kanban Mode**: 3-column kanban board view (TODO, Doing, Done)
|
|
12
12
|
- **Projects**: Organize tasks into projects with progress tracking
|
|
13
|
+
- **Contexts**: Tag tasks with contexts (@work, @home, etc.) and filter by context. New tasks inherit the active context filter
|
|
13
14
|
- **Task Search**: Quick search across all tasks with `/`
|
|
14
15
|
- **Comments**: Add notes and comments to tasks
|
|
15
16
|
- **Cloud Sync**: Optional sync with [Turso](https://turso.tech/) using embedded replicas
|
|
@@ -57,6 +58,8 @@ floq
|
|
|
57
58
|
| `w` | Move to Waiting For (prompts for person) |
|
|
58
59
|
| `p` | Convert to project |
|
|
59
60
|
| `P` | Link to project |
|
|
61
|
+
| `c` | Set context |
|
|
62
|
+
| `@` | Filter by context |
|
|
60
63
|
| `Enter` | Open task detail / Open project |
|
|
61
64
|
| `Esc/b` | Back |
|
|
62
65
|
| `/` | Search tasks |
|
|
@@ -106,6 +109,8 @@ floq
|
|
|
106
109
|
| `d` | Mark as done |
|
|
107
110
|
| `m` | Move task right (→) |
|
|
108
111
|
| `Backspace` | Move task left (←) |
|
|
112
|
+
| `c` | Set context |
|
|
113
|
+
| `@` | Filter by context |
|
|
109
114
|
| `Enter` | Open task detail |
|
|
110
115
|
| `/` | Search tasks |
|
|
111
116
|
| `r` | Refresh |
|
|
@@ -142,6 +147,7 @@ floq setup
|
|
|
142
147
|
# Add task
|
|
143
148
|
floq add "Task title"
|
|
144
149
|
floq add "Task title" -p "Project name"
|
|
150
|
+
floq add "Task title" -c work # With context
|
|
145
151
|
|
|
146
152
|
# List tasks
|
|
147
153
|
floq list # All non-done tasks
|
|
@@ -168,6 +174,11 @@ floq project complete <id>
|
|
|
168
174
|
# Comments
|
|
169
175
|
floq comment <id> "Comment text" # Add comment
|
|
170
176
|
floq comment <id> # List comments
|
|
177
|
+
|
|
178
|
+
# Contexts
|
|
179
|
+
floq context list # List available contexts
|
|
180
|
+
floq context add <name> # Add new context
|
|
181
|
+
floq context remove <name> # Remove context
|
|
171
182
|
```
|
|
172
183
|
|
|
173
184
|
## Configuration
|
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,7 @@ import { markDone } from './commands/done.js';
|
|
|
9
9
|
import { addProject, listProjectsCommand, showProject, completeProject, } from './commands/project.js';
|
|
10
10
|
import { showConfig, setLanguage, setDbPath, resetDbPath, setTheme, selectTheme, setViewModeCommand, selectMode, setTurso, disableTurso, syncCommand, resetDatabase } from './commands/config.js';
|
|
11
11
|
import { addComment, listComments } from './commands/comment.js';
|
|
12
|
+
import { listContexts, addContextCommand, removeContextCommand } from './commands/context.js';
|
|
12
13
|
import { runSetupWizard } from './commands/setup.js';
|
|
13
14
|
import { VERSION } from './version.js';
|
|
14
15
|
const program = new Command();
|
|
@@ -27,6 +28,7 @@ program
|
|
|
27
28
|
.description('Add a new task to Inbox')
|
|
28
29
|
.option('-p, --project <name>', 'Add to a specific project')
|
|
29
30
|
.option('-d, --description <text>', 'Add a description')
|
|
31
|
+
.option('-c, --context <context>', 'Set context (e.g., work, home)')
|
|
30
32
|
.action(async (title, options) => {
|
|
31
33
|
await addTask(title, options);
|
|
32
34
|
});
|
|
@@ -183,6 +185,28 @@ program
|
|
|
183
185
|
await listComments(taskId);
|
|
184
186
|
}
|
|
185
187
|
});
|
|
188
|
+
// Context commands
|
|
189
|
+
const contextCmd = program
|
|
190
|
+
.command('context')
|
|
191
|
+
.description('Context management commands');
|
|
192
|
+
contextCmd
|
|
193
|
+
.command('list')
|
|
194
|
+
.description('List available contexts')
|
|
195
|
+
.action(async () => {
|
|
196
|
+
await listContexts();
|
|
197
|
+
});
|
|
198
|
+
contextCmd
|
|
199
|
+
.command('add <name>')
|
|
200
|
+
.description('Add a new context')
|
|
201
|
+
.action(async (name) => {
|
|
202
|
+
await addContextCommand(name);
|
|
203
|
+
});
|
|
204
|
+
contextCmd
|
|
205
|
+
.command('remove <name>')
|
|
206
|
+
.description('Remove a context')
|
|
207
|
+
.action(async (name) => {
|
|
208
|
+
await removeContextCommand(name);
|
|
209
|
+
});
|
|
186
210
|
// Setup wizard command
|
|
187
211
|
program
|
|
188
212
|
.command('setup')
|
package/dist/commands/add.d.ts
CHANGED
package/dist/commands/add.js
CHANGED
|
@@ -18,12 +18,14 @@ export async function addTask(title, options) {
|
|
|
18
18
|
}
|
|
19
19
|
parentId = projects[0].id;
|
|
20
20
|
}
|
|
21
|
+
const context = options.context?.toLowerCase().replace(/^@/, '');
|
|
21
22
|
const task = {
|
|
22
23
|
id: uuidv4(),
|
|
23
24
|
title,
|
|
24
25
|
description: options.description,
|
|
25
26
|
status: 'inbox',
|
|
26
27
|
parentId,
|
|
28
|
+
context: context || null,
|
|
27
29
|
createdAt: now,
|
|
28
30
|
updatedAt: now,
|
|
29
31
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getContexts, addContext, removeContext } from '../config.js';
|
|
2
|
+
import { t, fmt } from '../i18n/index.js';
|
|
3
|
+
export async function listContexts() {
|
|
4
|
+
const i18n = t();
|
|
5
|
+
const contexts = getContexts();
|
|
6
|
+
if (contexts.length === 0) {
|
|
7
|
+
console.log(i18n.commands.context.noContexts);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
console.log(i18n.commands.context.list);
|
|
11
|
+
for (const context of contexts) {
|
|
12
|
+
console.log(` @${context}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function addContextCommand(name) {
|
|
16
|
+
const i18n = t();
|
|
17
|
+
const normalized = name.toLowerCase().replace(/^@/, '');
|
|
18
|
+
if (addContext(normalized)) {
|
|
19
|
+
console.log(fmt(i18n.commands.context.added, { context: normalized }));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.error(fmt(i18n.commands.context.alreadyExists, { context: normalized }));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function removeContextCommand(name) {
|
|
27
|
+
const i18n = t();
|
|
28
|
+
const normalized = name.toLowerCase().replace(/^@/, '');
|
|
29
|
+
if (removeContext(normalized)) {
|
|
30
|
+
console.log(fmt(i18n.commands.context.removed, { context: normalized }));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.error(fmt(i18n.commands.context.notFound, { context: normalized }));
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq } from 'drizzle-orm';
|
|
1
|
+
import { eq, and, gte } from 'drizzle-orm';
|
|
2
2
|
import { getDb, schema } from '../db/index.js';
|
|
3
3
|
import { t, fmt } from '../i18n/index.js';
|
|
4
4
|
export async function listTasks(status) {
|
|
@@ -11,10 +11,22 @@ export async function listTasks(status) {
|
|
|
11
11
|
console.error(fmt(i18n.commands.list.validStatuses, { statuses: validStatuses.join(', ') }));
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
// For done status, only show tasks from the last week by default
|
|
15
|
+
let tasks;
|
|
16
|
+
if (status === 'done') {
|
|
17
|
+
const oneWeekAgo = new Date();
|
|
18
|
+
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
|
|
19
|
+
tasks = await db
|
|
20
|
+
.select()
|
|
21
|
+
.from(schema.tasks)
|
|
22
|
+
.where(and(eq(schema.tasks.status, 'done'), gte(schema.tasks.updatedAt, oneWeekAgo)));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
tasks = await db
|
|
26
|
+
.select()
|
|
27
|
+
.from(schema.tasks)
|
|
28
|
+
.where(eq(schema.tasks.status, status));
|
|
29
|
+
}
|
|
18
30
|
console.log(`\n${i18n.status[status]} (${tasks.length})`);
|
|
19
31
|
console.log('─'.repeat(40));
|
|
20
32
|
if (tasks.length === 0) {
|
package/dist/config.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface Config {
|
|
|
12
12
|
theme: ThemeName;
|
|
13
13
|
viewMode: ViewMode;
|
|
14
14
|
turso?: TursoConfig;
|
|
15
|
+
contexts?: string[];
|
|
15
16
|
}
|
|
16
17
|
export declare function loadConfig(): Config;
|
|
17
18
|
export declare function saveConfig(updates: Partial<Config>): void;
|
|
@@ -26,3 +27,6 @@ export declare function setThemeName(theme: ThemeName): void;
|
|
|
26
27
|
export declare function getViewMode(): ViewMode;
|
|
27
28
|
export declare function setViewMode(viewMode: ViewMode): void;
|
|
28
29
|
export declare function isFirstRun(): boolean;
|
|
30
|
+
export declare function getContexts(): string[];
|
|
31
|
+
export declare function addContext(context: string): boolean;
|
|
32
|
+
export declare function removeContext(context: string): boolean;
|
package/dist/config.js
CHANGED
|
@@ -28,10 +28,12 @@ function migrateDbFiles() {
|
|
|
28
28
|
}
|
|
29
29
|
// Run DB file migration on module load
|
|
30
30
|
migrateDbFiles();
|
|
31
|
+
const DEFAULT_CONTEXTS = ['work', 'home'];
|
|
31
32
|
const DEFAULT_CONFIG = {
|
|
32
33
|
locale: 'en',
|
|
33
34
|
theme: 'modern',
|
|
34
35
|
viewMode: 'gtd',
|
|
36
|
+
contexts: DEFAULT_CONTEXTS,
|
|
35
37
|
};
|
|
36
38
|
let configCache = null;
|
|
37
39
|
export function loadConfig() {
|
|
@@ -113,3 +115,26 @@ export function setViewMode(viewMode) {
|
|
|
113
115
|
export function isFirstRun() {
|
|
114
116
|
return !existsSync(CONFIG_FILE);
|
|
115
117
|
}
|
|
118
|
+
export function getContexts() {
|
|
119
|
+
return loadConfig().contexts || DEFAULT_CONTEXTS;
|
|
120
|
+
}
|
|
121
|
+
export function addContext(context) {
|
|
122
|
+
const contexts = getContexts();
|
|
123
|
+
const normalized = context.toLowerCase().replace(/^@/, '');
|
|
124
|
+
if (contexts.includes(normalized)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
saveConfig({ contexts: [...contexts, normalized] });
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
export function removeContext(context) {
|
|
131
|
+
const contexts = getContexts();
|
|
132
|
+
const normalized = context.toLowerCase().replace(/^@/, '');
|
|
133
|
+
const index = contexts.indexOf(normalized);
|
|
134
|
+
if (index === -1) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const newContexts = contexts.filter(c => c !== normalized);
|
|
138
|
+
saveConfig({ contexts: newContexts });
|
|
139
|
+
return true;
|
|
140
|
+
}
|
package/dist/db/index.js
CHANGED
|
@@ -23,6 +23,7 @@ async function initializeRemoteSchema(tursoUrl, authToken) {
|
|
|
23
23
|
const tableInfoResult = await remoteClient.execute("PRAGMA table_info(tasks)");
|
|
24
24
|
const tableInfo = tableInfoResult.rows;
|
|
25
25
|
const tableExists = tableInfo.length > 0;
|
|
26
|
+
const hasContext = tableInfo.some(col => col.name === 'context');
|
|
26
27
|
if (!tableExists) {
|
|
27
28
|
// Fresh install: create new schema on remote
|
|
28
29
|
await remoteClient.execute(`
|
|
@@ -34,6 +35,7 @@ async function initializeRemoteSchema(tursoUrl, authToken) {
|
|
|
34
35
|
is_project INTEGER NOT NULL DEFAULT 0,
|
|
35
36
|
parent_id TEXT,
|
|
36
37
|
waiting_for TEXT,
|
|
38
|
+
context TEXT,
|
|
37
39
|
due_date INTEGER,
|
|
38
40
|
created_at INTEGER NOT NULL,
|
|
39
41
|
updated_at INTEGER NOT NULL
|
|
@@ -42,6 +44,12 @@ async function initializeRemoteSchema(tursoUrl, authToken) {
|
|
|
42
44
|
await remoteClient.execute("CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)");
|
|
43
45
|
await remoteClient.execute("CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)");
|
|
44
46
|
await remoteClient.execute("CREATE INDEX IF NOT EXISTS idx_tasks_is_project ON tasks(is_project)");
|
|
47
|
+
await remoteClient.execute("CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)");
|
|
48
|
+
}
|
|
49
|
+
else if (!hasContext) {
|
|
50
|
+
// Migration: add context column
|
|
51
|
+
await remoteClient.execute("ALTER TABLE tasks ADD COLUMN context TEXT");
|
|
52
|
+
await remoteClient.execute("CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)");
|
|
45
53
|
}
|
|
46
54
|
// Create comments table
|
|
47
55
|
await remoteClient.execute(`
|
|
@@ -66,6 +74,7 @@ async function initializeLocalSchema() {
|
|
|
66
74
|
const tableInfo = tableInfoResult.rows;
|
|
67
75
|
const hasProjectId = tableInfo.some(col => col.name === 'project_id');
|
|
68
76
|
const hasIsProject = tableInfo.some(col => col.name === 'is_project');
|
|
77
|
+
const hasContext = tableInfo.some(col => col.name === 'context');
|
|
69
78
|
const tableExists = tableInfo.length > 0;
|
|
70
79
|
if (tableExists && hasProjectId && !hasIsProject) {
|
|
71
80
|
// Migration: old schema -> new schema
|
|
@@ -96,6 +105,7 @@ async function initializeLocalSchema() {
|
|
|
96
105
|
is_project INTEGER NOT NULL DEFAULT 0,
|
|
97
106
|
parent_id TEXT,
|
|
98
107
|
waiting_for TEXT,
|
|
108
|
+
context TEXT,
|
|
99
109
|
due_date INTEGER,
|
|
100
110
|
created_at INTEGER NOT NULL,
|
|
101
111
|
updated_at INTEGER NOT NULL
|
|
@@ -104,6 +114,12 @@ async function initializeLocalSchema() {
|
|
|
104
114
|
await client.execute("CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)");
|
|
105
115
|
await client.execute("CREATE INDEX IF NOT EXISTS idx_tasks_parent_id ON tasks(parent_id)");
|
|
106
116
|
await client.execute("CREATE INDEX IF NOT EXISTS idx_tasks_is_project ON tasks(is_project)");
|
|
117
|
+
await client.execute("CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)");
|
|
118
|
+
}
|
|
119
|
+
// Migration: add context column if missing
|
|
120
|
+
if (tableExists && !hasContext) {
|
|
121
|
+
await client.execute("ALTER TABLE tasks ADD COLUMN context TEXT");
|
|
122
|
+
await client.execute("CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)");
|
|
107
123
|
}
|
|
108
124
|
// Create comments table
|
|
109
125
|
await client.execute(`
|
package/dist/db/schema.d.ts
CHANGED
|
@@ -133,6 +133,25 @@ export declare const tasks: import("drizzle-orm/sqlite-core").SQLiteTableWithCol
|
|
|
133
133
|
}, {}, {
|
|
134
134
|
length: number | undefined;
|
|
135
135
|
}>;
|
|
136
|
+
context: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
137
|
+
name: "context";
|
|
138
|
+
tableName: "tasks";
|
|
139
|
+
dataType: "string";
|
|
140
|
+
columnType: "SQLiteText";
|
|
141
|
+
data: string;
|
|
142
|
+
driverParam: string;
|
|
143
|
+
notNull: false;
|
|
144
|
+
hasDefault: false;
|
|
145
|
+
isPrimaryKey: false;
|
|
146
|
+
isAutoincrement: false;
|
|
147
|
+
hasRuntimeDefault: false;
|
|
148
|
+
enumValues: [string, ...string[]];
|
|
149
|
+
baseColumn: never;
|
|
150
|
+
identity: undefined;
|
|
151
|
+
generated: undefined;
|
|
152
|
+
}, {}, {
|
|
153
|
+
length: number | undefined;
|
|
154
|
+
}>;
|
|
136
155
|
dueDate: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
137
156
|
name: "due_date";
|
|
138
157
|
tableName: "tasks";
|
package/dist/db/schema.js
CHANGED
|
@@ -7,6 +7,7 @@ export const tasks = sqliteTable('tasks', {
|
|
|
7
7
|
isProject: integer('is_project', { mode: 'boolean' }).notNull().default(false),
|
|
8
8
|
parentId: text('parent_id'),
|
|
9
9
|
waitingFor: text('waiting_for'),
|
|
10
|
+
context: text('context'),
|
|
10
11
|
dueDate: integer('due_date', { mode: 'timestamp' }),
|
|
11
12
|
createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
|
|
12
13
|
updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
|
package/dist/i18n/en.d.ts
CHANGED
|
@@ -63,6 +63,14 @@ export declare const en: {
|
|
|
63
63
|
noComments: string;
|
|
64
64
|
listHeader: string;
|
|
65
65
|
};
|
|
66
|
+
context: {
|
|
67
|
+
list: string;
|
|
68
|
+
added: string;
|
|
69
|
+
removed: string;
|
|
70
|
+
alreadyExists: string;
|
|
71
|
+
notFound: string;
|
|
72
|
+
noContexts: string;
|
|
73
|
+
};
|
|
66
74
|
};
|
|
67
75
|
tui: {
|
|
68
76
|
title: string;
|
|
@@ -129,6 +137,8 @@ export declare const en: {
|
|
|
129
137
|
taskDetail: string;
|
|
130
138
|
addComment: string;
|
|
131
139
|
searchTasks: string;
|
|
140
|
+
filterByContext: string;
|
|
141
|
+
setContext: string;
|
|
132
142
|
settings: string;
|
|
133
143
|
changeTheme: string;
|
|
134
144
|
changeViewMode: string;
|
|
@@ -199,6 +209,21 @@ export declare const en: {
|
|
|
199
209
|
resultsTitle: string;
|
|
200
210
|
searchTasks: string;
|
|
201
211
|
};
|
|
212
|
+
context: {
|
|
213
|
+
label: string;
|
|
214
|
+
filter: string;
|
|
215
|
+
filterHelp: string;
|
|
216
|
+
all: string;
|
|
217
|
+
none: string;
|
|
218
|
+
setContext: string;
|
|
219
|
+
setContextHelp: string;
|
|
220
|
+
contextSet: string;
|
|
221
|
+
contextCleared: string;
|
|
222
|
+
filterActive: string;
|
|
223
|
+
addNew: string;
|
|
224
|
+
newContext: string;
|
|
225
|
+
newContextPlaceholder: string;
|
|
226
|
+
};
|
|
202
227
|
info: {
|
|
203
228
|
settings: string;
|
|
204
229
|
database: string;
|
|
@@ -290,6 +315,8 @@ export type HelpTranslations = {
|
|
|
290
315
|
taskDetail: string;
|
|
291
316
|
addComment: string;
|
|
292
317
|
searchTasks: string;
|
|
318
|
+
filterByContext: string;
|
|
319
|
+
setContext: string;
|
|
293
320
|
settings: string;
|
|
294
321
|
changeTheme: string;
|
|
295
322
|
changeViewMode: string;
|
|
@@ -359,6 +386,21 @@ export type SearchTranslations = {
|
|
|
359
386
|
resultsTitle: string;
|
|
360
387
|
searchTasks: string;
|
|
361
388
|
};
|
|
389
|
+
export type ContextTranslations = {
|
|
390
|
+
label: string;
|
|
391
|
+
filter: string;
|
|
392
|
+
filterHelp: string;
|
|
393
|
+
all: string;
|
|
394
|
+
none: string;
|
|
395
|
+
setContext: string;
|
|
396
|
+
setContextHelp: string;
|
|
397
|
+
contextSet: string;
|
|
398
|
+
contextCleared: string;
|
|
399
|
+
filterActive: string;
|
|
400
|
+
addNew: string;
|
|
401
|
+
newContext: string;
|
|
402
|
+
newContextPlaceholder: string;
|
|
403
|
+
};
|
|
362
404
|
export type InfoTranslations = {
|
|
363
405
|
settings: string;
|
|
364
406
|
database: string;
|
|
@@ -404,6 +446,7 @@ export type TuiTranslations = {
|
|
|
404
446
|
whatsNew: WhatsNewTranslations;
|
|
405
447
|
kanbanHelp: KanbanHelpTranslations;
|
|
406
448
|
search: SearchTranslations;
|
|
449
|
+
context: ContextTranslations;
|
|
407
450
|
info: InfoTranslations;
|
|
408
451
|
addComment: string;
|
|
409
452
|
noComments: string;
|
|
@@ -485,6 +528,7 @@ export type Translations = {
|
|
|
485
528
|
done: Record<string, string>;
|
|
486
529
|
project: Record<string, string>;
|
|
487
530
|
comment: Record<string, string>;
|
|
531
|
+
context: Record<string, string>;
|
|
488
532
|
};
|
|
489
533
|
tui: TuiTranslations;
|
|
490
534
|
setup: SetupTranslations;
|
package/dist/i18n/en.js
CHANGED
|
@@ -67,6 +67,14 @@ export const en = {
|
|
|
67
67
|
noComments: 'No comments',
|
|
68
68
|
listHeader: 'Comments for "{title}":',
|
|
69
69
|
},
|
|
70
|
+
context: {
|
|
71
|
+
list: 'Available contexts:',
|
|
72
|
+
added: 'Added context: @{context}',
|
|
73
|
+
removed: 'Removed context: @{context}',
|
|
74
|
+
alreadyExists: 'Context @{context} already exists.',
|
|
75
|
+
notFound: 'Context @{context} not found.',
|
|
76
|
+
noContexts: 'No contexts configured.',
|
|
77
|
+
},
|
|
70
78
|
},
|
|
71
79
|
// TUI
|
|
72
80
|
tui: {
|
|
@@ -138,6 +146,8 @@ export const en = {
|
|
|
138
146
|
taskDetail: 'View task details',
|
|
139
147
|
addComment: 'Add comment',
|
|
140
148
|
searchTasks: 'Search tasks',
|
|
149
|
+
filterByContext: 'Filter by context',
|
|
150
|
+
setContext: 'Set context',
|
|
141
151
|
settings: 'Settings',
|
|
142
152
|
changeTheme: 'Change theme',
|
|
143
153
|
changeViewMode: 'Change view mode',
|
|
@@ -212,6 +222,22 @@ export const en = {
|
|
|
212
222
|
resultsTitle: 'Search Results',
|
|
213
223
|
searchTasks: 'Search tasks',
|
|
214
224
|
},
|
|
225
|
+
// Context
|
|
226
|
+
context: {
|
|
227
|
+
label: 'Context',
|
|
228
|
+
filter: 'Filter by context',
|
|
229
|
+
filterHelp: 'j/k: select, Enter: confirm, Esc: cancel',
|
|
230
|
+
all: 'All',
|
|
231
|
+
none: 'No context',
|
|
232
|
+
setContext: 'Set context',
|
|
233
|
+
setContextHelp: 'j/k: select, Enter: confirm, Esc: cancel',
|
|
234
|
+
contextSet: 'Set context @{context} for "{title}"',
|
|
235
|
+
contextCleared: 'Cleared context for "{title}"',
|
|
236
|
+
filterActive: '@{context}',
|
|
237
|
+
addNew: '+ New context',
|
|
238
|
+
newContext: 'New context: ',
|
|
239
|
+
newContextPlaceholder: 'Enter context name...',
|
|
240
|
+
},
|
|
215
241
|
// Info tab
|
|
216
242
|
info: {
|
|
217
243
|
settings: 'Settings',
|
package/dist/i18n/ja.js
CHANGED
|
@@ -67,6 +67,14 @@ export const ja = {
|
|
|
67
67
|
noComments: 'コメントはありません',
|
|
68
68
|
listHeader: '「{title}」のコメント:',
|
|
69
69
|
},
|
|
70
|
+
context: {
|
|
71
|
+
list: '利用可能なコンテキスト:',
|
|
72
|
+
added: 'コンテキストを追加しました: @{context}',
|
|
73
|
+
removed: 'コンテキストを削除しました: @{context}',
|
|
74
|
+
alreadyExists: 'コンテキスト @{context} は既に存在します。',
|
|
75
|
+
notFound: 'コンテキスト @{context} が見つかりません。',
|
|
76
|
+
noContexts: 'コンテキストが設定されていません。',
|
|
77
|
+
},
|
|
70
78
|
},
|
|
71
79
|
// TUI
|
|
72
80
|
tui: {
|
|
@@ -138,6 +146,8 @@ export const ja = {
|
|
|
138
146
|
taskDetail: 'タスク詳細を表示',
|
|
139
147
|
addComment: 'コメント追加',
|
|
140
148
|
searchTasks: 'タスク検索',
|
|
149
|
+
filterByContext: 'コンテキストフィルター',
|
|
150
|
+
setContext: 'コンテキスト設定',
|
|
141
151
|
settings: '設定',
|
|
142
152
|
changeTheme: 'テーマ変更',
|
|
143
153
|
changeViewMode: '表示モード変更',
|
|
@@ -212,6 +222,22 @@ export const ja = {
|
|
|
212
222
|
resultsTitle: '検索結果',
|
|
213
223
|
searchTasks: 'タスク検索',
|
|
214
224
|
},
|
|
225
|
+
// Context
|
|
226
|
+
context: {
|
|
227
|
+
label: 'コンテキスト',
|
|
228
|
+
filter: 'コンテキストでフィルター',
|
|
229
|
+
filterHelp: 'j/k: 選択, Enter: 確定, Esc: キャンセル',
|
|
230
|
+
all: 'すべて',
|
|
231
|
+
none: 'コンテキストなし',
|
|
232
|
+
setContext: 'コンテキスト設定',
|
|
233
|
+
setContextHelp: 'j/k: 選択, Enter: 確定, Esc: キャンセル',
|
|
234
|
+
contextSet: '「{title}」にコンテキスト @{context} を設定しました',
|
|
235
|
+
contextCleared: '「{title}」のコンテキストをクリアしました',
|
|
236
|
+
filterActive: '@{context}',
|
|
237
|
+
addNew: '+ 新規コンテキスト',
|
|
238
|
+
newContext: '新規コンテキスト: ',
|
|
239
|
+
newContextPlaceholder: 'コンテキスト名を入力...',
|
|
240
|
+
},
|
|
215
241
|
// Info tab
|
|
216
242
|
info: {
|
|
217
243
|
settings: '設定',
|