@leeguoo/zentao-mcp 0.5.0 → 0.5.1
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 +24 -0
- package/package.json +1 -1
- package/skills/zentao-cli.md +24 -0
- package/src/cli/help.js +4 -4
- package/src/commands/bug.js +45 -3
- package/src/commands/bugs.js +75 -5
- package/src/commands/products.js +34 -3
package/README.md
CHANGED
|
@@ -46,24 +46,48 @@ List products:
|
|
|
46
46
|
zentao products list
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
Full JSON output:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
zentao products list --json
|
|
53
|
+
```
|
|
54
|
+
|
|
49
55
|
List bugs for a product:
|
|
50
56
|
|
|
51
57
|
```bash
|
|
52
58
|
zentao bugs list --product 1
|
|
53
59
|
```
|
|
54
60
|
|
|
61
|
+
Full JSON output:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
zentao bugs list --product 1 --json
|
|
65
|
+
```
|
|
66
|
+
|
|
55
67
|
Get bug details:
|
|
56
68
|
|
|
57
69
|
```bash
|
|
58
70
|
zentao bug get --id 123
|
|
59
71
|
```
|
|
60
72
|
|
|
73
|
+
Full JSON output:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
zentao bug get --id 123 --json
|
|
77
|
+
```
|
|
78
|
+
|
|
61
79
|
List my bugs:
|
|
62
80
|
|
|
63
81
|
```bash
|
|
64
82
|
zentao bugs mine --scope assigned --status active
|
|
65
83
|
```
|
|
66
84
|
|
|
85
|
+
Full JSON output:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
zentao bugs mine --scope assigned --status active --json
|
|
89
|
+
```
|
|
90
|
+
|
|
67
91
|
Self test:
|
|
68
92
|
|
|
69
93
|
```bash
|
package/package.json
CHANGED
package/skills/zentao-cli.md
CHANGED
|
@@ -42,24 +42,48 @@ Or via CLI flags:
|
|
|
42
42
|
zentao products list
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
Full JSON output:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
zentao products list --json
|
|
49
|
+
```
|
|
50
|
+
|
|
45
51
|
### List bugs for a product
|
|
46
52
|
|
|
47
53
|
```bash
|
|
48
54
|
zentao bugs list --product 1
|
|
49
55
|
```
|
|
50
56
|
|
|
57
|
+
Full JSON output:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
zentao bugs list --product 1 --json
|
|
61
|
+
```
|
|
62
|
+
|
|
51
63
|
### Get bug details
|
|
52
64
|
|
|
53
65
|
```bash
|
|
54
66
|
zentao bug get --id 123
|
|
55
67
|
```
|
|
56
68
|
|
|
69
|
+
Full JSON output:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
zentao bug get --id 123 --json
|
|
73
|
+
```
|
|
74
|
+
|
|
57
75
|
### List my bugs
|
|
58
76
|
|
|
59
77
|
```bash
|
|
60
78
|
zentao bugs mine --scope assigned --status active
|
|
61
79
|
```
|
|
62
80
|
|
|
81
|
+
Full JSON output:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
zentao bugs mine --scope assigned --status active --json
|
|
85
|
+
```
|
|
86
|
+
|
|
63
87
|
Common options:
|
|
64
88
|
|
|
65
89
|
- `--scope`: `assigned|opened|resolved|all`
|
package/src/cli/help.js
CHANGED
|
@@ -4,10 +4,10 @@ export function printRootHelp() {
|
|
|
4
4
|
process.stdout.write(`Usage:\n`);
|
|
5
5
|
process.stdout.write(` zentao login [--zentao-url ... --zentao-account ... --zentao-password ...] [--yes]\n`);
|
|
6
6
|
process.stdout.write(` zentao whoami\n`);
|
|
7
|
-
process.stdout.write(` zentao products list [--page N] [--limit N]\n`);
|
|
8
|
-
process.stdout.write(` zentao bugs list --product <id> [--page N] [--limit N]\n`);
|
|
9
|
-
process.stdout.write(` zentao bug get --id <bugId
|
|
10
|
-
process.stdout.write(` zentao bugs mine [--scope ...] [--status ...] [--include-details]\n`);
|
|
7
|
+
process.stdout.write(` zentao products list [--page N] [--limit N] [--json]\n`);
|
|
8
|
+
process.stdout.write(` zentao bugs list --product <id> [--page N] [--limit N] [--json]\n`);
|
|
9
|
+
process.stdout.write(` zentao bug get --id <bugId> [--json]\n`);
|
|
10
|
+
process.stdout.write(` zentao bugs mine [--scope ...] [--status ...] [--include-details] [--json]\n`);
|
|
11
11
|
process.stdout.write(` zentao self-test [--expected N]\n`);
|
|
12
12
|
process.stdout.write(` zentao release [patch|minor|major] [--dry-run] [--yes]\n\n`);
|
|
13
13
|
process.stdout.write(`Auth options:\n`);
|
package/src/commands/bug.js
CHANGED
|
@@ -3,9 +3,40 @@ import { extractCommand, hasHelpFlag, parseCliArgs } from "../cli/args.js";
|
|
|
3
3
|
import { createClientFromCli } from "../zentao/client.js";
|
|
4
4
|
|
|
5
5
|
function printHelp() {
|
|
6
|
-
process.stdout.write(`zentao
|
|
6
|
+
process.stdout.write(`zentao bug get\n\n`);
|
|
7
7
|
process.stdout.write(`Usage:\n`);
|
|
8
|
-
process.stdout.write(` zentao
|
|
8
|
+
process.stdout.write(` zentao bug get --id <bugId> [--json]\n`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function formatAccount(value) {
|
|
12
|
+
if (!value) return "";
|
|
13
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
14
|
+
if (typeof value === "object") return String(value.account || value.name || value.realname || "");
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function formatBugSimple(bug) {
|
|
19
|
+
const header = [
|
|
20
|
+
"id",
|
|
21
|
+
"title",
|
|
22
|
+
"status",
|
|
23
|
+
"pri",
|
|
24
|
+
"severity",
|
|
25
|
+
"assignedTo",
|
|
26
|
+
"openedBy",
|
|
27
|
+
"resolvedBy",
|
|
28
|
+
].join("\t");
|
|
29
|
+
const row = [
|
|
30
|
+
String(bug?.id ?? ""),
|
|
31
|
+
String(bug?.title ?? ""),
|
|
32
|
+
String(bug?.status ?? ""),
|
|
33
|
+
String(bug?.pri ?? ""),
|
|
34
|
+
String(bug?.severity ?? ""),
|
|
35
|
+
formatAccount(bug?.assignedTo),
|
|
36
|
+
formatAccount(bug?.openedBy),
|
|
37
|
+
formatAccount(bug?.resolvedBy),
|
|
38
|
+
].join("\t");
|
|
39
|
+
return `${header}\n${row}\n`;
|
|
9
40
|
}
|
|
10
41
|
|
|
11
42
|
export async function runBug({ argv = [], env = process.env } = {}) {
|
|
@@ -23,5 +54,16 @@ export async function runBug({ argv = [], env = process.env } = {}) {
|
|
|
23
54
|
|
|
24
55
|
const api = createClientFromCli({ argv: argvWithoutSub, env });
|
|
25
56
|
const result = await api.getBug({ id });
|
|
26
|
-
|
|
57
|
+
if (cliArgs.json) {
|
|
58
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const bug = result?.result?.bug;
|
|
63
|
+
if (!bug || typeof bug !== "object") {
|
|
64
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
process.stdout.write(formatBugSimple(bug));
|
|
27
69
|
}
|
package/src/commands/bugs.js
CHANGED
|
@@ -18,10 +18,62 @@ function parseCsvIntegers(value) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function printHelp() {
|
|
21
|
-
process.stdout.write(`zentao
|
|
21
|
+
process.stdout.write(`zentao bugs <subcommand>\n\n`);
|
|
22
22
|
process.stdout.write(`Usage:\n`);
|
|
23
|
-
process.stdout.write(` zentao
|
|
24
|
-
process.stdout.write(` zentao
|
|
23
|
+
process.stdout.write(` zentao bugs list --product <id> [--page N] [--limit N] [--json]\n`);
|
|
24
|
+
process.stdout.write(` zentao bugs mine [--scope assigned|opened|resolved|all] [--status active|resolved|closed|all] [--include-details] [--json]\n`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function formatAccount(value) {
|
|
28
|
+
if (!value) return "";
|
|
29
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
30
|
+
if (typeof value === "object") return String(value.account || value.name || value.realname || "");
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function formatBugsSimple(bugs) {
|
|
35
|
+
const rows = [];
|
|
36
|
+
rows.push(["id", "title", "status", "pri", "severity", "assignedTo"].join("\t"));
|
|
37
|
+
for (const bug of bugs) {
|
|
38
|
+
rows.push(
|
|
39
|
+
[
|
|
40
|
+
String(bug?.id ?? ""),
|
|
41
|
+
String(bug?.title ?? ""),
|
|
42
|
+
String(bug?.status ?? ""),
|
|
43
|
+
String(bug?.pri ?? ""),
|
|
44
|
+
String(bug?.severity ?? ""),
|
|
45
|
+
formatAccount(bug?.assignedTo),
|
|
46
|
+
].join("\t")
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return `${rows.join("\n")}\n`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function formatBugsMineSimple(result) {
|
|
53
|
+
const total = result?.total ?? 0;
|
|
54
|
+
const products = Array.isArray(result?.products) ? result.products : [];
|
|
55
|
+
const rows = [];
|
|
56
|
+
rows.push(`total\t${total}`);
|
|
57
|
+
rows.push(["id", "name", "myBugs", "totalBugs"].join("\t"));
|
|
58
|
+
for (const product of products) {
|
|
59
|
+
rows.push(
|
|
60
|
+
[
|
|
61
|
+
String(product?.id ?? ""),
|
|
62
|
+
String(product?.name ?? ""),
|
|
63
|
+
String(product?.myBugs ?? ""),
|
|
64
|
+
String(product?.totalBugs ?? ""),
|
|
65
|
+
].join("\t")
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const bugs = Array.isArray(result?.bugs) ? result.bugs : [];
|
|
70
|
+
if (bugs.length) {
|
|
71
|
+
rows.push("");
|
|
72
|
+
rows.push("bugs");
|
|
73
|
+
rows.push(formatBugsSimple(bugs).trimEnd());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return `${rows.join("\n")}\n`;
|
|
25
77
|
}
|
|
26
78
|
|
|
27
79
|
export async function runBugs({ argv = [], env = process.env } = {}) {
|
|
@@ -42,7 +94,19 @@ export async function runBugs({ argv = [], env = process.env } = {}) {
|
|
|
42
94
|
page: cliArgs.page,
|
|
43
95
|
limit: cliArgs.limit,
|
|
44
96
|
});
|
|
45
|
-
|
|
97
|
+
|
|
98
|
+
if (cliArgs.json) {
|
|
99
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const bugs = result?.result?.bugs;
|
|
104
|
+
if (!Array.isArray(bugs)) {
|
|
105
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
process.stdout.write(formatBugsSimple(bugs));
|
|
46
110
|
return;
|
|
47
111
|
}
|
|
48
112
|
|
|
@@ -60,7 +124,13 @@ export async function runBugs({ argv = [], env = process.env } = {}) {
|
|
|
60
124
|
maxItems: cliArgs["max-items"],
|
|
61
125
|
includeDetails,
|
|
62
126
|
});
|
|
63
|
-
|
|
127
|
+
|
|
128
|
+
if (cliArgs.json) {
|
|
129
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
process.stdout.write(formatBugsMineSimple(result?.result));
|
|
64
134
|
return;
|
|
65
135
|
}
|
|
66
136
|
|
package/src/commands/products.js
CHANGED
|
@@ -3,9 +3,28 @@ import { extractCommand, hasHelpFlag, parseCliArgs } from "../cli/args.js";
|
|
|
3
3
|
import { createClientFromCli } from "../zentao/client.js";
|
|
4
4
|
|
|
5
5
|
function printHelp() {
|
|
6
|
-
process.stdout.write(`zentao
|
|
6
|
+
process.stdout.write(`zentao products list\n\n`);
|
|
7
7
|
process.stdout.write(`Usage:\n`);
|
|
8
|
-
process.stdout.write(` zentao
|
|
8
|
+
process.stdout.write(` zentao products list [--page N] [--limit N] [--json]\n`);
|
|
9
|
+
process.stdout.write(`\n`);
|
|
10
|
+
process.stdout.write(`Options:\n`);
|
|
11
|
+
process.stdout.write(` --json print full JSON payload\n`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function formatProductsSimple(products) {
|
|
15
|
+
const rows = [];
|
|
16
|
+
rows.push(["id", "name", "totalBugs", "status"].join("\t"));
|
|
17
|
+
for (const product of products) {
|
|
18
|
+
rows.push(
|
|
19
|
+
[
|
|
20
|
+
String(product.id ?? ""),
|
|
21
|
+
String(product.name ?? ""),
|
|
22
|
+
String(product.totalBugs ?? product.totalBugsCount ?? ""),
|
|
23
|
+
String(product.status ?? product.productStatus ?? ""),
|
|
24
|
+
].join("\t")
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return `${rows.join("\n")}\n`;
|
|
9
28
|
}
|
|
10
29
|
|
|
11
30
|
export async function runProducts({ argv = [], env = process.env } = {}) {
|
|
@@ -23,5 +42,17 @@ export async function runProducts({ argv = [], env = process.env } = {}) {
|
|
|
23
42
|
page: cliArgs.page,
|
|
24
43
|
limit: cliArgs.limit,
|
|
25
44
|
});
|
|
26
|
-
|
|
45
|
+
|
|
46
|
+
if (cliArgs.json) {
|
|
47
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const products = result?.result?.products;
|
|
52
|
+
if (!Array.isArray(products)) {
|
|
53
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
process.stdout.write(formatProductsSimple(products));
|
|
27
58
|
}
|