@zinn-dev/cli 0.10.0 → 0.12.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.md +13 -1
- package/package.json +2 -2
- package/src/constant.ts +1 -0
- package/src/routes/task-router.ts +56 -8
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ Use `task relation create --help` to discover types.
|
|
|
124
124
|
|
|
125
125
|
## Edit tasks
|
|
126
126
|
|
|
127
|
-
Edit a task's title, description, or labels:
|
|
127
|
+
Edit a task's title, description, priority, or labels:
|
|
128
128
|
|
|
129
129
|
```sh
|
|
130
130
|
zinn task edit MDR-1 --title "Meet the quarterly refinement quota"
|
|
@@ -196,3 +196,15 @@ zinn task move --help
|
|
|
196
196
|
The short `-h` form works in the same positions.
|
|
197
197
|
|
|
198
198
|
Running `zinn` without a command shows help
|
|
199
|
+
|
|
200
|
+
## Task priority
|
|
201
|
+
|
|
202
|
+
Priority is optional: `low`, `medium`, `high`, or `urgent`. New tasks have no assigned priority by default.
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
zinn task create MDR --title "Review the numbers" --priority high
|
|
206
|
+
zinn task edit MDR-1 --priority urgent
|
|
207
|
+
zinn task edit MDR-1 --priority none
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Use `none` to clear priority. Omitting `--priority` on edits preserves it. Assigned priorities appear in task list and view output; board ordering remains unchanged.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zinn-dev/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "A kanban workflow in the terminal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": {
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@zinn-dev/core": "0.
|
|
45
|
+
"@zinn-dev/core": "0.11.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/src/constant.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TASK_DESCRIPTION_PREVIEW_LENGTH = 80;
|
|
@@ -5,7 +5,24 @@ import { task, project, column } from "@zinn-dev/core";
|
|
|
5
5
|
|
|
6
6
|
import { quit, validatePositionalCount, validateUniqueOptions } from "../lib";
|
|
7
7
|
import { formatRelations, relationRouter } from "./relation-router";
|
|
8
|
+
import { TASK_DESCRIPTION_PREVIEW_LENGTH } from "../constant";
|
|
8
9
|
|
|
10
|
+
function formatTaskDescriptionPreview(description: string | null) {
|
|
11
|
+
if (description == null) {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const normalizedDescription = description.replace(/\s+/g, " ").trim();
|
|
16
|
+
|
|
17
|
+
if (normalizedDescription.length <= TASK_DESCRIPTION_PREVIEW_LENGTH) {
|
|
18
|
+
return normalizedDescription;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return `${normalizedDescription.slice(0, TASK_DESCRIPTION_PREVIEW_LENGTH - 1).trimEnd()}…`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO: a CLI row formatter that accepts text columns and joins them with " | " would be useful
|
|
25
|
+
// Reuse it across task list/view and other command output in a separate change.
|
|
9
26
|
function formatTask(
|
|
10
27
|
taskMatch: ReturnType<typeof task.getByKey>,
|
|
11
28
|
options: { showsStatus?: boolean } = {},
|
|
@@ -17,11 +34,12 @@ function formatTask(
|
|
|
17
34
|
: "";
|
|
18
35
|
const description = taskMatch.description == null ? "" : ` | ${taskMatch.description}`;
|
|
19
36
|
|
|
37
|
+
const priority = taskMatch.priority == null ? "" : ` | Priority: ${taskMatch.priority}`;
|
|
20
38
|
const labels = task.label.getAll(taskKey);
|
|
21
39
|
const labelText =
|
|
22
40
|
labels.length === 0 ? "" : ` | Labels: ${labels.map((label) => label.name).join(", ")}`;
|
|
23
41
|
|
|
24
|
-
return `${taskKey}${status} | ${taskColumn.name} | ${taskMatch.title}${description}${labelText}`;
|
|
42
|
+
return `${taskKey}${status} | ${taskColumn.name} | ${taskMatch.title}${description}${priority}${labelText}`;
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
export const taskRouter = {
|
|
@@ -32,6 +50,7 @@ export const taskRouter = {
|
|
|
32
50
|
options: {
|
|
33
51
|
title: { type: "string" },
|
|
34
52
|
description: { type: "string" },
|
|
53
|
+
priority: { type: "string" },
|
|
35
54
|
"add-label": { type: "string", multiple: true },
|
|
36
55
|
"remove-label": { type: "string", multiple: true },
|
|
37
56
|
},
|
|
@@ -53,12 +72,13 @@ export const taskRouter = {
|
|
|
53
72
|
const hasEditFlags =
|
|
54
73
|
values.title !== undefined ||
|
|
55
74
|
values.description !== undefined ||
|
|
75
|
+
values.priority !== undefined ||
|
|
56
76
|
values["add-label"] !== undefined ||
|
|
57
77
|
values["remove-label"] !== undefined;
|
|
58
78
|
|
|
59
79
|
if (!hasEditFlags) {
|
|
60
80
|
quit(
|
|
61
|
-
"Provide at least one edit flag: --title, --description, --add-label, or --remove-label",
|
|
81
|
+
"Provide at least one edit flag: --title, --description, --priority, --add-label, or --remove-label",
|
|
62
82
|
);
|
|
63
83
|
}
|
|
64
84
|
|
|
@@ -66,15 +86,17 @@ export const taskRouter = {
|
|
|
66
86
|
taskKey,
|
|
67
87
|
title: values.title,
|
|
68
88
|
description: values.description,
|
|
89
|
+
priority: parsePriority(values.priority),
|
|
69
90
|
addLabelNames: values["add-label"],
|
|
70
91
|
removeLabelNames: values["remove-label"],
|
|
71
92
|
});
|
|
72
93
|
|
|
73
94
|
console.info(formatTask(editedTask));
|
|
74
95
|
},
|
|
75
|
-
help: `Usage: zinn task edit <task-key> [--title <text>] [--description <text>] [--add-label <name>] [--remove-label <name>]
|
|
96
|
+
help: `Usage: zinn task edit <task-key> [--title <text>] [--description <text>] [--priority <low|medium|high|urgent|none>] [--add-label <name>] [--remove-label <name>]
|
|
76
97
|
|
|
77
98
|
Change the supplied fields and preserve everything else.
|
|
99
|
+
Use --priority none to clear priority.
|
|
78
100
|
Provide at least one edit flag. Use --description "" for an empty description.
|
|
79
101
|
|
|
80
102
|
Repeat --add-label or --remove-label for multiple existing labels.
|
|
@@ -95,6 +117,7 @@ Example: zinn task edit MDR-1 --title "Meet the quarterly refinement quota"`,
|
|
|
95
117
|
options: {
|
|
96
118
|
title: { type: "string" },
|
|
97
119
|
description: { type: "string" },
|
|
120
|
+
priority: { type: "string" },
|
|
98
121
|
label: { type: "string", multiple: true },
|
|
99
122
|
},
|
|
100
123
|
allowPositionals: true,
|
|
@@ -105,7 +128,11 @@ Example: zinn task edit MDR-1 --title "Meet the quarterly refinement quota"`,
|
|
|
105
128
|
if (projectKey == null) {
|
|
106
129
|
quit("A task needs to belong to a project");
|
|
107
130
|
}
|
|
108
|
-
validatePositionalCount(
|
|
131
|
+
validatePositionalCount(
|
|
132
|
+
positionals,
|
|
133
|
+
1,
|
|
134
|
+
"Only one project key can be specified; use --title and --description",
|
|
135
|
+
);
|
|
109
136
|
if (values.title === undefined) {
|
|
110
137
|
quit("A task needs at least a title: use --title");
|
|
111
138
|
}
|
|
@@ -118,13 +145,15 @@ Example: zinn task edit MDR-1 --title "Meet the quarterly refinement quota"`,
|
|
|
118
145
|
project_id: projectMatch.id,
|
|
119
146
|
title: values.title,
|
|
120
147
|
description: values.description ?? null,
|
|
148
|
+
priority: parsePriority(values.priority),
|
|
121
149
|
labelNames: values.label,
|
|
122
150
|
});
|
|
123
151
|
console.info(formatTask(createdTask));
|
|
124
152
|
},
|
|
125
|
-
help: `Usage: zinn task create <project-key> --title <text> [--description <text>] [--label <name>]
|
|
153
|
+
help: `Usage: zinn task create <project-key> --title <text> [--description <text>] [--priority <low|medium|high|urgent|none>] [--label <name>]
|
|
126
154
|
|
|
127
155
|
Create a task in the project's first column.
|
|
156
|
+
Priority defaults to none (unassigned).
|
|
128
157
|
Repeat --label to attach multiple existing labels. Unknown labels are errors.
|
|
129
158
|
Titles cannot be blank. Use --title="--example" for text beginning with a dash.
|
|
130
159
|
|
|
@@ -163,6 +192,7 @@ Example: zinn task create MDR --title "Refine the numbers" --description "Meet t
|
|
|
163
192
|
status: t.archived_at == null ? "Active" : "Archived",
|
|
164
193
|
title: t.title,
|
|
165
194
|
description: t.description,
|
|
195
|
+
priority: t.priority,
|
|
166
196
|
column: taskColumn.name,
|
|
167
197
|
};
|
|
168
198
|
});
|
|
@@ -181,8 +211,10 @@ Example: zinn task create MDR --title "Refine the numbers" --description "Meet t
|
|
|
181
211
|
.map((t) => {
|
|
182
212
|
// TODO: console output formatting for standardizied output
|
|
183
213
|
const status = showsAll ? ` | ${t.status.padEnd(longestStatusLength)}` : "";
|
|
184
|
-
const
|
|
185
|
-
|
|
214
|
+
const descriptionPreview = formatTaskDescriptionPreview(t.description);
|
|
215
|
+
const description = t.description == null ? "" : ` | ${descriptionPreview}`;
|
|
216
|
+
const priority = t.priority == null ? "" : ` | Priority: ${t.priority}`;
|
|
217
|
+
return `${t.id.padEnd(longestIdLength)}${status} | ${t.column} | ${t.title}${description}${priority}`;
|
|
186
218
|
})
|
|
187
219
|
.join("\n"),
|
|
188
220
|
);
|
|
@@ -212,7 +244,7 @@ Example: zinn task list MDR --all`,
|
|
|
212
244
|
},
|
|
213
245
|
help: `Usage: zinn task view <task-key>
|
|
214
246
|
|
|
215
|
-
Show a task with its current column, description, labels, and relations.
|
|
247
|
+
Show a task with its current column, description, priority, labels, and relations.
|
|
216
248
|
|
|
217
249
|
Example: zinn task view MDR-1`,
|
|
218
250
|
},
|
|
@@ -388,3 +420,19 @@ function parseTaskLabelArgs(args: string[]) {
|
|
|
388
420
|
}
|
|
389
421
|
return { taskKey: positionals[0]!, labelNames: positionals.slice(1) };
|
|
390
422
|
}
|
|
423
|
+
|
|
424
|
+
function parsePriority(value: string | undefined) {
|
|
425
|
+
switch (value) {
|
|
426
|
+
case undefined:
|
|
427
|
+
return undefined;
|
|
428
|
+
case "none":
|
|
429
|
+
return null;
|
|
430
|
+
case "low":
|
|
431
|
+
case "medium":
|
|
432
|
+
case "high":
|
|
433
|
+
case "urgent":
|
|
434
|
+
return value;
|
|
435
|
+
default:
|
|
436
|
+
quit("Priority must be low, medium, high, urgent, or none");
|
|
437
|
+
}
|
|
438
|
+
}
|