@task-mcp/cli 1.0.21 → 1.0.22
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/dist/index.js +818 -0
- package/package.json +7 -5
- package/src/__tests__/ansi.test.ts +0 -221
- package/src/__tests__/dashboard.test.ts +0 -226
- package/src/__tests__/inbox.test.ts +0 -307
- package/src/__tests__/index.test.ts +0 -140
- package/src/__tests__/list.test.ts +0 -347
- package/src/__tests__/storage.test.ts +0 -271
- package/src/ansi.ts +0 -50
- package/src/commands/dashboard.ts +0 -92
- package/src/commands/inbox.ts +0 -229
- package/src/commands/list.ts +0 -106
- package/src/constants.ts +0 -59
- package/src/index.ts +0 -277
- package/src/interactive.ts +0 -254
- package/src/storage.ts +0 -221
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard command - displays workspace overview with unified widgets
|
|
3
|
-
* Uses shared dashboard renderer from @task-mcp/shared
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { VERSION } from "../index.js";
|
|
7
|
-
import { c } from "../ansi.js";
|
|
8
|
-
import {
|
|
9
|
-
renderGlobalDashboard,
|
|
10
|
-
renderWorkspaceDashboard,
|
|
11
|
-
type Task as SharedTask,
|
|
12
|
-
type WorkspaceInfo,
|
|
13
|
-
} from "@task-mcp/shared";
|
|
14
|
-
import {
|
|
15
|
-
listWorkspaces,
|
|
16
|
-
listTasks,
|
|
17
|
-
listAllTasks,
|
|
18
|
-
listInboxItems,
|
|
19
|
-
getActiveTag,
|
|
20
|
-
getCurrentWorkspace,
|
|
21
|
-
type Task,
|
|
22
|
-
} from "../storage.js";
|
|
23
|
-
|
|
24
|
-
// =============================================================================
|
|
25
|
-
// Main Dashboard
|
|
26
|
-
// =============================================================================
|
|
27
|
-
|
|
28
|
-
export async function dashboard(workspaceName?: string): Promise<void> {
|
|
29
|
-
// Get workspaces, tasks, and active tag
|
|
30
|
-
const workspaces = await listWorkspaces();
|
|
31
|
-
const activeTag = await getActiveTag();
|
|
32
|
-
const currentWorkspace = getCurrentWorkspace();
|
|
33
|
-
|
|
34
|
-
if (workspaces.length === 0) {
|
|
35
|
-
console.log(c.yellow("No tasks found. Create a task first using the MCP server."));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// If workspace specified, show single workspace. Otherwise show all.
|
|
40
|
-
let selectedWorkspace: WorkspaceInfo | undefined;
|
|
41
|
-
let tasks: Task[];
|
|
42
|
-
|
|
43
|
-
if (workspaceName) {
|
|
44
|
-
selectedWorkspace = workspaces.find(w => w.name === workspaceName || w.name.startsWith(workspaceName));
|
|
45
|
-
if (!selectedWorkspace) {
|
|
46
|
-
console.log(c.error(`Workspace not found: ${workspaceName}`));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
tasks = await listAllTasks();
|
|
50
|
-
tasks = tasks.filter(t => t.workspace === selectedWorkspace!.name);
|
|
51
|
-
} else if (workspaces.length === 1) {
|
|
52
|
-
selectedWorkspace = workspaces[0];
|
|
53
|
-
tasks = await listTasks();
|
|
54
|
-
} else {
|
|
55
|
-
// Show all tasks across all workspaces
|
|
56
|
-
tasks = await listAllTasks();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Get inbox items
|
|
60
|
-
const inboxItems = await listInboxItems("pending");
|
|
61
|
-
|
|
62
|
-
// Create task lookup for workspaces table (batch query to avoid N+1)
|
|
63
|
-
const allTasksForLookup = await listAllTasks();
|
|
64
|
-
const tasksByWorkspace = new Map<string, Task[]>();
|
|
65
|
-
for (const task of allTasksForLookup) {
|
|
66
|
-
const workspaceTasks = tasksByWorkspace.get(task.workspace) ?? [];
|
|
67
|
-
workspaceTasks.push(task);
|
|
68
|
-
tasksByWorkspace.set(task.workspace, workspaceTasks);
|
|
69
|
-
}
|
|
70
|
-
const getWorkspaceTasks = (ws: string) => (tasksByWorkspace.get(ws) ?? []) as SharedTask[];
|
|
71
|
-
|
|
72
|
-
// Render dashboard using shared renderer
|
|
73
|
-
// Cast types - CLI types are compatible subset of shared types
|
|
74
|
-
let output: string;
|
|
75
|
-
if (selectedWorkspace) {
|
|
76
|
-
output = renderWorkspaceDashboard(
|
|
77
|
-
selectedWorkspace.name,
|
|
78
|
-
tasks as SharedTask[],
|
|
79
|
-
{ version: VERSION, activeTag }
|
|
80
|
-
);
|
|
81
|
-
} else {
|
|
82
|
-
output = renderGlobalDashboard(
|
|
83
|
-
workspaces,
|
|
84
|
-
tasks as SharedTask[],
|
|
85
|
-
inboxItems,
|
|
86
|
-
getWorkspaceTasks,
|
|
87
|
-
{ version: VERSION, activeTag }
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
console.log(output);
|
|
92
|
-
}
|
package/src/commands/inbox.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI Inbox Commands
|
|
3
|
-
* Quick capture and management of ideas
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { c, formatStatus, formatPriority } from "../ansi.js";
|
|
7
|
-
import { InboxStore, TaskStore } from "@task-mcp/mcp-server/storage";
|
|
8
|
-
import { parseInboxInput } from "@task-mcp/shared";
|
|
9
|
-
import {
|
|
10
|
-
LIST_SEPARATOR_WIDTH,
|
|
11
|
-
MENU_SEPARATOR_WIDTH,
|
|
12
|
-
INBOX_PROMOTE_TITLE_MAX_LENGTH,
|
|
13
|
-
INBOX_DISCARD_PREVIEW_LENGTH,
|
|
14
|
-
} from "../constants.js";
|
|
15
|
-
|
|
16
|
-
const inboxStore = new InboxStore();
|
|
17
|
-
const taskStore = new TaskStore();
|
|
18
|
-
|
|
19
|
-
export interface InboxAddOptions {
|
|
20
|
-
content: string;
|
|
21
|
-
source?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface InboxListOptions {
|
|
25
|
-
all?: boolean;
|
|
26
|
-
status?: "pending" | "promoted" | "discarded";
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface InboxPromoteOptions {
|
|
30
|
-
itemId: string;
|
|
31
|
-
title?: string;
|
|
32
|
-
priority?: "critical" | "high" | "medium" | "low";
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Add item to inbox with natural language parsing
|
|
37
|
-
*/
|
|
38
|
-
export async function inboxAddCmd(options: InboxAddOptions): Promise<void> {
|
|
39
|
-
const parsed = parseInboxInput(options.content);
|
|
40
|
-
|
|
41
|
-
const item = await inboxStore.add({
|
|
42
|
-
content: parsed.content,
|
|
43
|
-
source: options.source ?? "cli",
|
|
44
|
-
tags: parsed.tags,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
console.log();
|
|
48
|
-
console.log(c.green("✓") + " Captured to inbox");
|
|
49
|
-
console.log();
|
|
50
|
-
console.log(" " + c.dim("ID:") + " " + c.cyan(item.id));
|
|
51
|
-
console.log(" " + c.dim("Content:") + " " + item.content);
|
|
52
|
-
if (parsed.tags?.length) {
|
|
53
|
-
console.log(" " + c.dim("Tags:") + " " + parsed.tags.map((t) => c.yellow("#" + t)).join(" "));
|
|
54
|
-
}
|
|
55
|
-
console.log();
|
|
56
|
-
console.log(c.dim("Use 'task inbox promote " + item.id + "' to convert to task"));
|
|
57
|
-
console.log();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* List inbox items
|
|
62
|
-
*/
|
|
63
|
-
export async function inboxListCmd(options: InboxListOptions): Promise<void> {
|
|
64
|
-
const status = options.all ? undefined : (options.status ?? "pending");
|
|
65
|
-
const items = await inboxStore.list({ status });
|
|
66
|
-
|
|
67
|
-
console.log();
|
|
68
|
-
|
|
69
|
-
if (items.length === 0) {
|
|
70
|
-
console.log(c.dim(status ? `No ${status} items in inbox.` : "Inbox is empty."));
|
|
71
|
-
console.log();
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Header
|
|
76
|
-
const title = status ? `Inbox (${status})` : "Inbox (all)";
|
|
77
|
-
console.log(c.bold(c.cyan(title)) + c.dim(` - ${items.length} items`));
|
|
78
|
-
console.log(c.dim("─".repeat(LIST_SEPARATOR_WIDTH)));
|
|
79
|
-
console.log();
|
|
80
|
-
|
|
81
|
-
for (const item of items) {
|
|
82
|
-
const statusIcon =
|
|
83
|
-
item.status === "pending" ? c.yellow("○") :
|
|
84
|
-
item.status === "promoted" ? c.green("✓") :
|
|
85
|
-
c.dim("×");
|
|
86
|
-
|
|
87
|
-
const date = new Date(item.capturedAt).toLocaleDateString();
|
|
88
|
-
const tags = item.tags?.length
|
|
89
|
-
? " " + item.tags.map((t: string) => c.dim("#" + t)).join(" ")
|
|
90
|
-
: "";
|
|
91
|
-
|
|
92
|
-
console.log(`${statusIcon} ${c.cyan(item.id)} ${c.dim("(" + date + ")")}`);
|
|
93
|
-
console.log(` ${item.content}${tags}`);
|
|
94
|
-
|
|
95
|
-
if (item.promotedToTaskId) {
|
|
96
|
-
console.log(` ${c.dim("→ Task:")} ${c.green(item.promotedToTaskId)}`);
|
|
97
|
-
}
|
|
98
|
-
console.log();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Show inbox item details
|
|
104
|
-
*/
|
|
105
|
-
export async function inboxGetCmd(itemId: string): Promise<void> {
|
|
106
|
-
const item = await inboxStore.get(itemId);
|
|
107
|
-
|
|
108
|
-
if (!item) {
|
|
109
|
-
console.log();
|
|
110
|
-
console.log(c.error(`Inbox item not found: ${itemId}`));
|
|
111
|
-
console.log();
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log();
|
|
116
|
-
console.log(c.bold(c.cyan("Inbox Item")));
|
|
117
|
-
console.log(c.dim("─".repeat(MENU_SEPARATOR_WIDTH)));
|
|
118
|
-
console.log();
|
|
119
|
-
console.log(" " + c.dim("ID:") + " " + item.id);
|
|
120
|
-
console.log(" " + c.dim("Status:") + " " + formatStatus(item.status));
|
|
121
|
-
console.log(" " + c.dim("Captured:") + " " + new Date(item.capturedAt).toLocaleString());
|
|
122
|
-
if (item.source) {
|
|
123
|
-
console.log(" " + c.dim("Source:") + " " + item.source);
|
|
124
|
-
}
|
|
125
|
-
if (item.tags?.length) {
|
|
126
|
-
console.log(" " + c.dim("Tags:") + " " + item.tags.map((t: string) => c.yellow("#" + t)).join(" "));
|
|
127
|
-
}
|
|
128
|
-
console.log();
|
|
129
|
-
console.log(c.bold("Content:"));
|
|
130
|
-
console.log(" " + item.content);
|
|
131
|
-
|
|
132
|
-
if (item.promotedToTaskId) {
|
|
133
|
-
console.log();
|
|
134
|
-
console.log(c.green("→ Promoted to: " + item.promotedToTaskId));
|
|
135
|
-
}
|
|
136
|
-
console.log();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Promote inbox item to task in current workspace
|
|
141
|
-
*/
|
|
142
|
-
export async function inboxPromoteCmd(options: InboxPromoteOptions): Promise<void> {
|
|
143
|
-
const item = await inboxStore.get(options.itemId);
|
|
144
|
-
|
|
145
|
-
if (!item) {
|
|
146
|
-
console.log();
|
|
147
|
-
console.log(c.error(`Inbox item not found: ${options.itemId}`));
|
|
148
|
-
console.log();
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (item.status === "promoted") {
|
|
153
|
-
console.log();
|
|
154
|
-
console.log(c.warning(`Item already promoted to: ${item.promotedToTaskId}`));
|
|
155
|
-
console.log();
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Create task in current workspace (auto-detected)
|
|
160
|
-
const task = await taskStore.create({
|
|
161
|
-
title: options.title ?? item.content.slice(0, INBOX_PROMOTE_TITLE_MAX_LENGTH),
|
|
162
|
-
description: item.content,
|
|
163
|
-
priority: options.priority ?? "medium",
|
|
164
|
-
tags: item.tags,
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// Mark as promoted
|
|
168
|
-
await inboxStore.promote(options.itemId, task.id);
|
|
169
|
-
|
|
170
|
-
console.log();
|
|
171
|
-
console.log(c.green("✓") + " Promoted to task");
|
|
172
|
-
console.log();
|
|
173
|
-
console.log(" " + c.dim("Task ID:") + " " + c.cyan(task.id));
|
|
174
|
-
console.log(" " + c.dim("Title:") + " " + task.title);
|
|
175
|
-
console.log(" " + c.dim("Workspace:") + " " + task.workspace);
|
|
176
|
-
console.log(" " + c.dim("Priority:") + " " + formatPriority(task.priority));
|
|
177
|
-
console.log();
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Discard inbox item
|
|
182
|
-
*/
|
|
183
|
-
export async function inboxDiscardCmd(itemId: string): Promise<void> {
|
|
184
|
-
const item = await inboxStore.discard(itemId);
|
|
185
|
-
|
|
186
|
-
if (!item) {
|
|
187
|
-
console.log();
|
|
188
|
-
console.log(c.error(`Inbox item not found: ${itemId}`));
|
|
189
|
-
console.log();
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
console.log();
|
|
194
|
-
console.log(c.dim("×") + " Discarded: " + item.content.slice(0, INBOX_DISCARD_PREVIEW_LENGTH) + "...");
|
|
195
|
-
console.log();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Delete inbox item permanently
|
|
200
|
-
*/
|
|
201
|
-
export async function inboxDeleteCmd(itemId: string): Promise<void> {
|
|
202
|
-
const deleted = await inboxStore.delete(itemId);
|
|
203
|
-
|
|
204
|
-
if (!deleted) {
|
|
205
|
-
console.log();
|
|
206
|
-
console.log(c.error(`Inbox item not found: ${itemId}`));
|
|
207
|
-
console.log();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
console.log();
|
|
212
|
-
console.log(c.green("✓") + " Deleted: " + itemId);
|
|
213
|
-
console.log();
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Show inbox count
|
|
218
|
-
*/
|
|
219
|
-
export async function inboxCountCmd(): Promise<void> {
|
|
220
|
-
const count = await inboxStore.getPendingCount();
|
|
221
|
-
|
|
222
|
-
console.log();
|
|
223
|
-
if (count > 0) {
|
|
224
|
-
console.log(c.yellow("📥") + ` ${count} pending item${count === 1 ? "" : "s"} in inbox`);
|
|
225
|
-
} else {
|
|
226
|
-
console.log(c.dim("Inbox is empty"));
|
|
227
|
-
}
|
|
228
|
-
console.log();
|
|
229
|
-
}
|
package/src/commands/list.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* List commands - list tasks and workspaces
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { c, table, formatStatus, formatPriority, type TableColumn } from "../ansi.js";
|
|
6
|
-
import {
|
|
7
|
-
listWorkspaces,
|
|
8
|
-
listTasks,
|
|
9
|
-
listAllTasks,
|
|
10
|
-
getCurrentWorkspace,
|
|
11
|
-
type Task,
|
|
12
|
-
type WorkspaceInfo,
|
|
13
|
-
} from "../storage.js";
|
|
14
|
-
import {
|
|
15
|
-
COLUMN_WIDTH_ID,
|
|
16
|
-
COLUMN_WIDTH_TITLE,
|
|
17
|
-
COLUMN_WIDTH_PROJECT_NAME,
|
|
18
|
-
COLUMN_WIDTH_STATUS,
|
|
19
|
-
COLUMN_WIDTH_PRIORITY,
|
|
20
|
-
COLUMN_WIDTH_DATE,
|
|
21
|
-
ID_DISPLAY_LENGTH,
|
|
22
|
-
} from "../constants.js";
|
|
23
|
-
|
|
24
|
-
function formatDate(dateStr?: string): string {
|
|
25
|
-
if (!dateStr) return c.gray("-");
|
|
26
|
-
const date = new Date(dateStr);
|
|
27
|
-
return date.toLocaleDateString();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function listTasksCmd(options: {
|
|
31
|
-
workspace?: string;
|
|
32
|
-
status?: string;
|
|
33
|
-
priority?: string;
|
|
34
|
-
all?: boolean;
|
|
35
|
-
}): Promise<void> {
|
|
36
|
-
let tasks: Task[];
|
|
37
|
-
|
|
38
|
-
if (options.workspace) {
|
|
39
|
-
// Filter by specific workspace
|
|
40
|
-
const allTasks = await listAllTasks();
|
|
41
|
-
tasks = allTasks.filter(t => t.workspace === options.workspace || t.workspace.startsWith(options.workspace!));
|
|
42
|
-
} else {
|
|
43
|
-
// Current workspace
|
|
44
|
-
tasks = await listTasks();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Apply filters
|
|
48
|
-
if (options.status) {
|
|
49
|
-
const statuses = options.status.split(",");
|
|
50
|
-
tasks = tasks.filter(t => statuses.includes(t.status));
|
|
51
|
-
} else if (!options.all) {
|
|
52
|
-
// By default, hide completed/cancelled
|
|
53
|
-
tasks = tasks.filter(t => t.status !== "completed" && t.status !== "cancelled");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (options.priority) {
|
|
57
|
-
const priorities = options.priority.split(",");
|
|
58
|
-
tasks = tasks.filter(t => priorities.includes(t.priority));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (tasks.length === 0) {
|
|
62
|
-
console.log(c.gray("No tasks found."));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const currentWorkspace = getCurrentWorkspace();
|
|
67
|
-
console.log(c.bold(`\nTasks (${tasks.length}) - ${c.cyan(currentWorkspace)}\n`));
|
|
68
|
-
|
|
69
|
-
const columns: TableColumn[] = [
|
|
70
|
-
{ header: "ID", key: "id", width: COLUMN_WIDTH_ID, format: (v) => c.cyan(String(v).slice(0, ID_DISPLAY_LENGTH)) },
|
|
71
|
-
{ header: "Title", key: "title", width: COLUMN_WIDTH_TITLE },
|
|
72
|
-
{ header: "Status", key: "status", width: COLUMN_WIDTH_STATUS, format: (v) => formatStatus(v as Task["status"]) },
|
|
73
|
-
{ header: "Priority", key: "priority", width: COLUMN_WIDTH_PRIORITY, format: (v) => formatPriority(v as Task["priority"]) },
|
|
74
|
-
{ header: "Due", key: "dueDate", width: COLUMN_WIDTH_DATE, format: (v) => formatDate(v as string) },
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
console.log(table(tasks as unknown as Record<string, unknown>[], columns));
|
|
78
|
-
console.log();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function listWorkspacesCmd(): Promise<void> {
|
|
82
|
-
const workspaces = await listWorkspaces();
|
|
83
|
-
const currentWorkspace = getCurrentWorkspace();
|
|
84
|
-
|
|
85
|
-
if (workspaces.length === 0) {
|
|
86
|
-
console.log(c.gray("No workspaces found."));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
console.log(c.bold(`\nWorkspaces (${workspaces.length})\n`));
|
|
91
|
-
|
|
92
|
-
const workspacesWithCurrent = workspaces.map(ws => ({
|
|
93
|
-
...ws,
|
|
94
|
-
current: ws.name === currentWorkspace ? c.green("●") : "",
|
|
95
|
-
progress: `${ws.completedCount}/${ws.taskCount}`,
|
|
96
|
-
}));
|
|
97
|
-
|
|
98
|
-
const columns: TableColumn[] = [
|
|
99
|
-
{ header: "", key: "current", width: 2 },
|
|
100
|
-
{ header: "Name", key: "name", width: COLUMN_WIDTH_PROJECT_NAME, format: (v) => c.cyan(String(v)) },
|
|
101
|
-
{ header: "Tasks", key: "progress", width: COLUMN_WIDTH_PRIORITY },
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
console.log(table(workspacesWithCurrent, columns));
|
|
105
|
-
console.log();
|
|
106
|
-
}
|
package/src/constants.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI Constants
|
|
3
|
-
* Centralized magic numbers for column widths, limits, and UI settings
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// =============================================================================
|
|
7
|
-
// UI Layout
|
|
8
|
-
// =============================================================================
|
|
9
|
-
|
|
10
|
-
/** Width for horizontal separators in menus */
|
|
11
|
-
export const MENU_SEPARATOR_WIDTH = 40;
|
|
12
|
-
|
|
13
|
-
/** Width for horizontal separators in lists */
|
|
14
|
-
export const LIST_SEPARATOR_WIDTH = 50;
|
|
15
|
-
|
|
16
|
-
// =============================================================================
|
|
17
|
-
// Timing
|
|
18
|
-
// =============================================================================
|
|
19
|
-
|
|
20
|
-
/** Delay in ms after showing error message */
|
|
21
|
-
export const ERROR_MESSAGE_DELAY_MS = 1000;
|
|
22
|
-
|
|
23
|
-
/** Delay in ms for welcome screen display */
|
|
24
|
-
export const WELCOME_SCREEN_DELAY_MS = 1000;
|
|
25
|
-
|
|
26
|
-
// =============================================================================
|
|
27
|
-
// Table Column Widths
|
|
28
|
-
// =============================================================================
|
|
29
|
-
|
|
30
|
-
/** ID column width (shows truncated ID) */
|
|
31
|
-
export const COLUMN_WIDTH_ID = 6;
|
|
32
|
-
|
|
33
|
-
/** Task title column width */
|
|
34
|
-
export const COLUMN_WIDTH_TITLE = 45;
|
|
35
|
-
|
|
36
|
-
/** Project name column width */
|
|
37
|
-
export const COLUMN_WIDTH_PROJECT_NAME = 30;
|
|
38
|
-
|
|
39
|
-
/** Status column width */
|
|
40
|
-
export const COLUMN_WIDTH_STATUS = 14;
|
|
41
|
-
|
|
42
|
-
/** Priority column width */
|
|
43
|
-
export const COLUMN_WIDTH_PRIORITY = 10;
|
|
44
|
-
|
|
45
|
-
/** Date column width */
|
|
46
|
-
export const COLUMN_WIDTH_DATE = 12;
|
|
47
|
-
|
|
48
|
-
// =============================================================================
|
|
49
|
-
// Text Limits
|
|
50
|
-
// =============================================================================
|
|
51
|
-
|
|
52
|
-
/** Maximum length for task title when promoting from inbox */
|
|
53
|
-
export const INBOX_PROMOTE_TITLE_MAX_LENGTH = 100;
|
|
54
|
-
|
|
55
|
-
/** Maximum length for content preview when discarding inbox item */
|
|
56
|
-
export const INBOX_DISCARD_PREVIEW_LENGTH = 50;
|
|
57
|
-
|
|
58
|
-
/** Number of characters to show for truncated task/project IDs */
|
|
59
|
-
export const ID_DISPLAY_LENGTH = 4;
|