@zinn-dev/cli 0.8.0 → 0.9.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 CHANGED
@@ -84,6 +84,9 @@ Tasks from separate projects can be related to each other. Tasks can also be rel
84
84
 
85
85
  `task view` a task's existing relations.
86
86
 
87
+ Remove a relation with `zinn task relation delete MDR-1 MDR-2 --type dependency`, using its original direction for `dependency` and `duplicate`. For `related`, order does not matter.
88
+ Note that a deletion happens _without_ confirmation.
89
+
87
90
  Use `task relation create --help` to discover types.
88
91
 
89
92
  ## Edit tasks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zinn-dev/cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.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.8.0"
45
+ "@zinn-dev/core": "0.9.0"
46
46
  }
47
47
  }
@@ -38,33 +38,68 @@ export function formatRelations(taskKey: string) {
38
38
  .join("\n");
39
39
  }
40
40
 
41
+ function parseRelationArgs(args: string[]) {
42
+ const { values, positionals, tokens } = parseArgs({
43
+ args,
44
+ options: { type: { type: "string" } },
45
+ allowPositionals: true,
46
+ strict: true,
47
+ tokens: true,
48
+ });
49
+
50
+ if (positionals.length !== 2) {
51
+ quit("Exactly two task keys are required: source, target");
52
+ }
53
+
54
+ const optionCount = tokens.filter((token) => token.kind === "option").length;
55
+
56
+ if (optionCount > 1) {
57
+ // TODO: maybe a reusable option validator can be given expected option keys, and it can spit out unsupported options as well as help for what options are supported
58
+ quit('Option "--type" can only be specified once');
59
+ }
60
+
61
+ const typeResult = relationCreateSchema.shape.relation_type.safeParse(values.type);
62
+
63
+ if (!typeResult.success) {
64
+ quit("--type must be one of these: related, dependency, duplicate");
65
+ }
66
+ const sourceTaskKey = positionals[0]!;
67
+ const targetTaskKey = positionals[1]!;
68
+
69
+ return { sourceTaskKey, targetTaskKey, relation_type: typeResult.data };
70
+ }
71
+
41
72
  export const relationRouter = {
42
- create: {
73
+ delete: {
43
74
  run: (args) => {
44
- const { values, positionals, tokens } = parseArgs({
45
- args,
46
- options: { type: { type: "string" } },
47
- allowPositionals: true,
48
- strict: true,
49
- tokens: true,
50
- });
51
-
52
- if (positionals.length !== 2) {
53
- quit("Provide exactly two task keys: source and target");
54
- }
75
+ const props = parseRelationArgs(args);
76
+ relation.delete(props);
55
77
 
56
- if (tokens.filter((token) => token.kind === "option").length > 1) {
57
- quit('Option "--type" can only be specified once');
58
- }
78
+ const source = task.getByKey(props.sourceTaskKey);
79
+ const target = task.getByKey(props.targetTaskKey);
80
+ console.info(`Deleted ${props.relation_type} relation from ${source.key} to ${target.key}`);
81
+ },
82
+ help: `Usage: zinn task relation delete <source-task-key> <target-task-key> --type <type>
59
83
 
60
- const typeResult = relationCreateSchema.shape.relation_type.safeParse(values.type);
61
- if (!typeResult.success) {
62
- quit("Provide --type with one of: related, dependency, duplicate");
63
- }
64
- const sourceTaskKey = positionals[0]!;
65
- const targetTaskKey = positionals[1]!;
84
+ Remove only the specified relation. No confirmation is required.
85
+
86
+ Types: related, dependency, duplicate.
87
+
88
+ For related, either task order works.
89
+ For dependency and duplicate, use the creation direction:
90
+ source depends on target, or source is a duplicate of target.
91
+
92
+ Archived and cross-project tasks are supported.
93
+ A missing relation is an error.
94
+
95
+ Example: zinn task relation delete APP-1 APP-2 --type dependency`,
96
+ },
97
+ create: {
98
+ run: (args) => {
99
+ const props = parseRelationArgs(args);
100
+ const { sourceTaskKey, targetTaskKey } = props;
66
101
 
67
- relation.create({ sourceTaskKey, targetTaskKey, relation_type: typeResult.data });
102
+ relation.create(props);
68
103
 
69
104
  const source = task.getByKey(sourceTaskKey);
70
105
  const target = task.getByKey(targetTaskKey);
@@ -73,7 +108,7 @@ export const relationRouter = {
73
108
  related: "related to",
74
109
  dependency: "depends on",
75
110
  duplicate: "is a duplicate of",
76
- }[typeResult.data];
111
+ }[props.relation_type];
77
112
 
78
113
  console.info(`${source.key} ${label} ${target.key}`);
79
114
  },