jiradc-cli 1.0.24 → 1.0.25-gc990f41.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/dist/index.js +158 -82
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -47,26 +47,72 @@ function positiveInt(raw) {
|
|
|
47
47
|
}
|
|
48
48
|
return n;
|
|
49
49
|
}
|
|
50
|
+
function text(raw) {
|
|
51
|
+
return raw;
|
|
52
|
+
}
|
|
53
|
+
function date(raw) {
|
|
54
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw);
|
|
55
|
+
if (!m) {
|
|
56
|
+
throw new InvalidArgumentError(`Must be a date in YYYY-MM-DD format (got "${raw}")`);
|
|
57
|
+
}
|
|
58
|
+
const [, y, mo, d] = m;
|
|
59
|
+
const year = Number(y);
|
|
60
|
+
const month = Number(mo);
|
|
61
|
+
const day = Number(d);
|
|
62
|
+
const dt = new Date(Date.UTC(year, month - 1, day));
|
|
63
|
+
if (dt.getUTCFullYear() !== year || dt.getUTCMonth() !== month - 1 || dt.getUTCDate() !== day) {
|
|
64
|
+
throw new InvalidArgumentError(`Not a real calendar date: "${raw}".`);
|
|
65
|
+
}
|
|
66
|
+
return raw;
|
|
67
|
+
}
|
|
68
|
+
function dateTime(raw) {
|
|
69
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(raw) || Number.isNaN(Date.parse(raw))) {
|
|
70
|
+
throw new InvalidArgumentError(`Must be an ISO 8601 date-time, e.g. 2026-06-08T14:30:00Z (got "${raw}")`);
|
|
71
|
+
}
|
|
72
|
+
return raw;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ../../cli-utils/dist/json.js
|
|
76
|
+
import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
77
|
+
function truncate(s, max = 80) {
|
|
78
|
+
return s.length > max ? `${s.slice(0, max)}\u2026` : s;
|
|
79
|
+
}
|
|
80
|
+
function jsonShape(schema) {
|
|
81
|
+
return (raw) => {
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = JSON.parse(raw);
|
|
85
|
+
} catch {
|
|
86
|
+
throw new InvalidArgumentError2(`Must be valid JSON (could not parse "${truncate(raw)}").`);
|
|
87
|
+
}
|
|
88
|
+
const result = schema.safeParse(parsed);
|
|
89
|
+
if (!result.success) {
|
|
90
|
+
const issues3 = result.error.issues.map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ");
|
|
91
|
+
throw new InvalidArgumentError2(`Invalid JSON shape \u2014 ${issues3}`);
|
|
92
|
+
}
|
|
93
|
+
return result.data;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
50
96
|
|
|
51
97
|
// ../../cli-utils/dist/text-or-file.js
|
|
52
98
|
import { readFileSync as readFileSync3 } from "fs";
|
|
53
|
-
import { InvalidArgumentError as
|
|
99
|
+
import { InvalidArgumentError as InvalidArgumentError3, Option } from "commander";
|
|
54
100
|
var STDIN_REF = "-";
|
|
55
101
|
function rejectStdinSentinel(value) {
|
|
56
102
|
if (value === "@-" || value === STDIN_REF) {
|
|
57
|
-
throw new
|
|
103
|
+
throw new InvalidArgumentError3(`"${value}" looks like a stdin redirect, which is not supported here. Pass the text directly, or read it from a file/stdin with the matching --\u2026-file <path|-> option.`);
|
|
58
104
|
}
|
|
59
105
|
return value;
|
|
60
106
|
}
|
|
61
107
|
function readFileOrStdin(ref) {
|
|
62
108
|
if (ref === STDIN_REF) {
|
|
63
109
|
if (process.stdin.isTTY) {
|
|
64
|
-
throw new
|
|
110
|
+
throw new InvalidArgumentError3('"--\u2026-file -" reads stdin, but stdin is a terminal (nothing piped).');
|
|
65
111
|
}
|
|
66
112
|
try {
|
|
67
113
|
return readFileSync3(0, "utf8");
|
|
68
114
|
} catch (err) {
|
|
69
|
-
throw new
|
|
115
|
+
throw new InvalidArgumentError3(`failed to read stdin for "--\u2026-file -": ${err.message}`);
|
|
70
116
|
}
|
|
71
117
|
}
|
|
72
118
|
try {
|
|
@@ -74,28 +120,28 @@ function readFileOrStdin(ref) {
|
|
|
74
120
|
} catch (err) {
|
|
75
121
|
const e = err;
|
|
76
122
|
if (e.code === "ENOENT") {
|
|
77
|
-
throw new
|
|
123
|
+
throw new InvalidArgumentError3(`file not found: "${ref}".`);
|
|
78
124
|
}
|
|
79
|
-
throw new
|
|
125
|
+
throw new InvalidArgumentError3(`failed to read file "${ref}": ${e.message}`);
|
|
80
126
|
}
|
|
81
127
|
}
|
|
82
128
|
function textOrFileOption(cmd, name, opts = {}) {
|
|
83
129
|
const label = `${name.charAt(0).toUpperCase()}${name.slice(1)} content`;
|
|
84
130
|
cmd.option(`--${name} <text>`, opts.description ?? label, rejectStdinSentinel);
|
|
85
|
-
cmd.addOption(new Option(`--${name}-file <path>`, `Read --${name} from a file, or "-" for stdin (mutually exclusive with --${name})`).conflicts(name));
|
|
131
|
+
cmd.addOption(new Option(`--${name}-file <path>`, `Read --${name} from a file, or "-" for stdin (mutually exclusive with --${name})`).conflicts(name).argParser(text));
|
|
86
132
|
return cmd;
|
|
87
133
|
}
|
|
88
134
|
function resolveTextOrFile(opts, name, { required = true } = {}) {
|
|
89
135
|
const literal = opts[name];
|
|
90
136
|
const ref = opts[`${name}File`];
|
|
91
137
|
if (literal !== void 0 && ref !== void 0) {
|
|
92
|
-
throw new
|
|
138
|
+
throw new InvalidArgumentError3(`--${name} and --${name}-file are mutually exclusive; provide only one.`);
|
|
93
139
|
}
|
|
94
140
|
if (ref !== void 0) {
|
|
95
141
|
return readFileOrStdin(ref);
|
|
96
142
|
}
|
|
97
143
|
if (literal === void 0 && required) {
|
|
98
|
-
throw new
|
|
144
|
+
throw new InvalidArgumentError3(`a ${name} is required: provide --${name} <text> or --${name}-file <path>.`);
|
|
99
145
|
}
|
|
100
146
|
return literal;
|
|
101
147
|
}
|
|
@@ -127,7 +173,7 @@ function subjectArg(cmd, name, opts = {}) {
|
|
|
127
173
|
function subEntityOption(cmd, entity, opts = {}) {
|
|
128
174
|
const numeric = opts.numeric ?? SUB_ENTITY_ID_NUMERIC[entity] ?? true;
|
|
129
175
|
const description = `${entity.charAt(0).toUpperCase()}${entity.slice(1)} id`;
|
|
130
|
-
return defineOption(cmd, `--${entity}-id <id>`, description, numeric ? positiveInt :
|
|
176
|
+
return defineOption(cmd, `--${entity}-id <id>`, description, numeric ? positiveInt : text, opts.mandatory);
|
|
131
177
|
}
|
|
132
178
|
function bodyOption(cmd, opts = {}) {
|
|
133
179
|
return textOrFileOption(cmd, "body", { description: "Prose body content", ...opts });
|
|
@@ -717,7 +763,7 @@ function transformTransitions(response) {
|
|
|
717
763
|
|
|
718
764
|
// src/commands/board/issues.ts
|
|
719
765
|
function issues(parent) {
|
|
720
|
-
const cmd = parent.command("issues").description("Get issues for a board").addArgument(new Argument("<id>", "Board ID").argParser(positiveInt)).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated field names to return").option("--jql <jql>", "Additional JQL filter within the board");
|
|
766
|
+
const cmd = parent.command("issues").description("Get issues for a board").addArgument(new Argument("<id>", "Board ID").argParser(positiveInt)).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated field names to return", text).option("--jql <jql>", "Additional JQL filter within the board", text);
|
|
721
767
|
examples(cmd, [
|
|
722
768
|
"42",
|
|
723
769
|
"42 --limit 10",
|
|
@@ -741,7 +787,7 @@ function issues(parent) {
|
|
|
741
787
|
import { Option as Option2 } from "commander";
|
|
742
788
|
var BOARD_TYPES = ["scrum", "kanban", "simple"];
|
|
743
789
|
function list(parent) {
|
|
744
|
-
const cmd = parent.command("list").description("List agile boards").option("--limit <number>", "Max results (1-1000)", intInRange(1, 1e3), 25).option("--project <key>", "Filter boards by project key or ID").addOption(new Option2("--type <type>", "Board type filter").choices(BOARD_TYPES)).option("--name <name>", "Filter boards by name");
|
|
790
|
+
const cmd = parent.command("list").description("List agile boards").option("--limit <number>", "Max results (1-1000)", intInRange(1, 1e3), 25).option("--project <key>", "Filter boards by project key or ID", text).addOption(new Option2("--type <type>", "Board type filter").choices(BOARD_TYPES)).option("--name <name>", "Filter boards by name", text);
|
|
745
791
|
examples(cmd, ["", "--limit 10", "--project PROJ", '--type scrum --name "Team Board"']);
|
|
746
792
|
cmd.action(async (opts) => {
|
|
747
793
|
const client = getClient();
|
|
@@ -772,7 +818,7 @@ var ASSIGNEE_TYPES = [
|
|
|
772
818
|
"UNASSIGNED"
|
|
773
819
|
];
|
|
774
820
|
function create(parent) {
|
|
775
|
-
const cmd = parent.command("create").description("Create a new component in a project").requiredOption("--project <key>", "Project key (e.g., AI)").requiredOption("--name <name>", "Component name").option("--lead <username>", "Username of the component lead").addOption(new Option3("--assignee-type <type>", "Assignee strategy").choices(ASSIGNEE_TYPES));
|
|
821
|
+
const cmd = parent.command("create").description("Create a new component in a project").requiredOption("--project <key>", "Project key (e.g., AI)", text).requiredOption("--name <name>", "Component name", text).option("--lead <username>", "Username of the component lead", text).addOption(new Option3("--assignee-type <type>", "Assignee strategy").choices(ASSIGNEE_TYPES));
|
|
776
822
|
textOrFileOption(cmd, "description", { description: "Component description" });
|
|
777
823
|
examples(cmd, [
|
|
778
824
|
"--project AI --name Backend",
|
|
@@ -797,40 +843,40 @@ function create(parent) {
|
|
|
797
843
|
|
|
798
844
|
// src/commands/component/delete.ts
|
|
799
845
|
function deleteComponent(parent) {
|
|
800
|
-
const cmd = parent.command("delete
|
|
846
|
+
const cmd = parent.command("delete").description("Delete a component, optionally reassigning its issues to another component").argument("<id>", "Component ID", positiveInt).option("--move-issues-to <id>", "Reassign existing issues to this component ID before deletion", text);
|
|
801
847
|
examples(cmd, ["11289", "11289 --move-issues-to 11290"]);
|
|
802
848
|
cmd.action(async (id, opts) => {
|
|
803
849
|
const client = getClient();
|
|
804
|
-
await client.components.delete({ id, moveIssuesTo: opts.moveIssuesTo });
|
|
850
|
+
await client.components.delete({ id: String(id), moveIssuesTo: opts.moveIssuesTo });
|
|
805
851
|
output({ deleted: true, componentId: id, ...opts.moveIssuesTo && { movedIssuesTo: opts.moveIssuesTo } });
|
|
806
852
|
});
|
|
807
853
|
}
|
|
808
854
|
|
|
809
855
|
// src/commands/component/get.ts
|
|
810
856
|
function get(parent) {
|
|
811
|
-
const cmd = parent.command("get
|
|
857
|
+
const cmd = parent.command("get").description("Get a component by ID").argument("<id>", "Component ID", positiveInt);
|
|
812
858
|
examples(cmd, ["11289"]);
|
|
813
859
|
cmd.action(async (id) => {
|
|
814
860
|
const client = getClient();
|
|
815
|
-
const result = await client.components.get({ id });
|
|
861
|
+
const result = await client.components.get({ id: String(id) });
|
|
816
862
|
output(transformComponent(result));
|
|
817
863
|
});
|
|
818
864
|
}
|
|
819
865
|
|
|
820
866
|
// src/commands/component/issue-count.ts
|
|
821
867
|
function issueCount(parent) {
|
|
822
|
-
const cmd = parent.command("issue-count
|
|
868
|
+
const cmd = parent.command("issue-count").description("Get the number of issues currently using this component").argument("<id>", "Component ID", positiveInt);
|
|
823
869
|
examples(cmd, ["11289"]);
|
|
824
870
|
cmd.action(async (id) => {
|
|
825
871
|
const client = getClient();
|
|
826
|
-
const result = await client.components.getRelatedIssueCounts({ id });
|
|
872
|
+
const result = await client.components.getRelatedIssueCounts({ id: String(id) });
|
|
827
873
|
output(transformComponentIssueCounts(result));
|
|
828
874
|
});
|
|
829
875
|
}
|
|
830
876
|
|
|
831
877
|
// src/commands/component/list.ts
|
|
832
878
|
function list2(parent) {
|
|
833
|
-
const cmd = parent.command("list").description("List all components for a project").requiredOption("--project <key>", "Project key (e.g., AI)");
|
|
879
|
+
const cmd = parent.command("list").description("List all components for a project").requiredOption("--project <key>", "Project key (e.g., AI)", text);
|
|
834
880
|
examples(cmd, ["--project AI"]);
|
|
835
881
|
cmd.action(async (opts) => {
|
|
836
882
|
const client = getClient();
|
|
@@ -848,7 +894,7 @@ var ASSIGNEE_TYPES2 = [
|
|
|
848
894
|
"UNASSIGNED"
|
|
849
895
|
];
|
|
850
896
|
function update(parent) {
|
|
851
|
-
const cmd = parent.command("update
|
|
897
|
+
const cmd = parent.command("update").description("Update an existing component (only provided fields are changed)").argument("<id>", "Component ID", positiveInt).option("--name <name>", "New component name", text).option("--lead <username>", "Username of the component lead (empty string clears it)", text).addOption(new Option4("--assignee-type <type>", "New assignee strategy").choices(ASSIGNEE_TYPES2));
|
|
852
898
|
textOrFileOption(cmd, "description", { description: "New component description" });
|
|
853
899
|
examples(cmd, [
|
|
854
900
|
"11289 --name Backend",
|
|
@@ -863,7 +909,7 @@ function update(parent) {
|
|
|
863
909
|
}
|
|
864
910
|
const client = getClient();
|
|
865
911
|
const result = await client.components.update({
|
|
866
|
-
id,
|
|
912
|
+
id: String(id),
|
|
867
913
|
name: opts.name,
|
|
868
914
|
description,
|
|
869
915
|
leadUserName: opts.lead,
|
|
@@ -895,7 +941,7 @@ function registerComponentCommands(program) {
|
|
|
895
941
|
|
|
896
942
|
// src/commands/field/options.ts
|
|
897
943
|
function options(parent) {
|
|
898
|
-
const cmd = parent.command("options
|
|
944
|
+
const cmd = parent.command("options").description("Get available options for a custom field").argument("<id>", "Field ID", text).option("--query <text>", "Filter options by text", text).option("--limit <number>", "Max results to return (1-1000)", intInRange(1, 1e3), 25).option("--start <number>", "Page number (1-indexed)", positiveInt);
|
|
899
945
|
examples(cmd, ["10001", '10001 --query "High"', "10001 --limit 20 --start 2"]);
|
|
900
946
|
cmd.action(async (id, opts) => {
|
|
901
947
|
const client = getClient();
|
|
@@ -911,7 +957,7 @@ function options(parent) {
|
|
|
911
957
|
|
|
912
958
|
// src/commands/field/search.ts
|
|
913
959
|
function search(parent) {
|
|
914
|
-
const cmd = parent.command("search
|
|
960
|
+
const cmd = parent.command("search").description("Search for fields by name or ID").argument("<keyword>", "Search keyword", text).option("--limit <number>", "Maximum number of results (1-1000)", intInRange(1, 1e3), 25);
|
|
915
961
|
examples(cmd, ["epic", "customfield_10100", "priority --limit 5"]);
|
|
916
962
|
cmd.action(async (keyword, opts) => {
|
|
917
963
|
const client = getClient();
|
|
@@ -944,9 +990,18 @@ async function resolveUserToken(token) {
|
|
|
944
990
|
return token;
|
|
945
991
|
}
|
|
946
992
|
|
|
993
|
+
// src/utils/validators.ts
|
|
994
|
+
import { InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
995
|
+
function issueKey(raw) {
|
|
996
|
+
if (!/^[A-Z][A-Z0-9]+-\d+$/.test(raw)) {
|
|
997
|
+
throw new InvalidArgumentError4(`Must be a Jira issue key like PROJ-123 (got "${raw}")`);
|
|
998
|
+
}
|
|
999
|
+
return raw;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
947
1002
|
// src/commands/issue/assign.ts
|
|
948
1003
|
function assign(parent) {
|
|
949
|
-
const cmd = parent.command("assign
|
|
1004
|
+
const cmd = parent.command("assign").description('Assign an issue. --assignee is a username, "me", or "none" to unassign.').argument("<key>", "Issue key", issueKey).requiredOption("--assignee <user>", 'Username to assign, "me" for the current user, or "none" to unassign', text);
|
|
950
1005
|
examples(cmd, ["PROJ-123 --assignee jsmith", "PROJ-123 --assignee me", "PROJ-123 --assignee none"]);
|
|
951
1006
|
cmd.action(async (key, opts) => {
|
|
952
1007
|
const resolved = await resolveUserToken(opts.assignee);
|
|
@@ -961,7 +1016,7 @@ function assign(parent) {
|
|
|
961
1016
|
|
|
962
1017
|
// src/commands/issue/attachment/delete.ts
|
|
963
1018
|
function deleteAttachment(parent) {
|
|
964
|
-
const cmd = parent.command("delete
|
|
1019
|
+
const cmd = parent.command("delete").description("Delete an attachment by ID").argument("<key>", "Issue key", issueKey);
|
|
965
1020
|
subEntityOption(cmd, "attachment", { mandatory: true });
|
|
966
1021
|
examples(cmd, ["PROJ-123 --attachment-id 12345"]);
|
|
967
1022
|
cmd.action(async (key, opts) => {
|
|
@@ -975,7 +1030,7 @@ function deleteAttachment(parent) {
|
|
|
975
1030
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
976
1031
|
import { join as join3 } from "path";
|
|
977
1032
|
function downloadAll(parent) {
|
|
978
|
-
const cmd = parent.command("download-all
|
|
1033
|
+
const cmd = parent.command("download-all").description("Download all attachments from an issue").argument("<key>", "Issue key", issueKey).requiredOption("--output <dir>", "Local directory to save attachments into", text);
|
|
979
1034
|
examples(cmd, ["PROJ-123 --output ./downloads"]);
|
|
980
1035
|
cmd.action(async (key, opts) => {
|
|
981
1036
|
const client = getClient();
|
|
@@ -1016,9 +1071,9 @@ function downloadAll(parent) {
|
|
|
1016
1071
|
|
|
1017
1072
|
// src/commands/issue/attachment/download.ts
|
|
1018
1073
|
function download(parent) {
|
|
1019
|
-
const cmd = parent.command("download
|
|
1074
|
+
const cmd = parent.command("download").description("Download a single attachment by ID").argument("<key>", "Issue key", issueKey);
|
|
1020
1075
|
subEntityOption(cmd, "attachment", { mandatory: true });
|
|
1021
|
-
cmd.requiredOption("--output <path>", "Local file path to save the attachment");
|
|
1076
|
+
cmd.requiredOption("--output <path>", "Local file path to save the attachment", text);
|
|
1022
1077
|
examples(cmd, ["PROJ-123 --attachment-id 12345 --output ./report.pdf"]);
|
|
1023
1078
|
cmd.action(async (key, opts) => {
|
|
1024
1079
|
const client = getClient();
|
|
@@ -1043,7 +1098,7 @@ function download(parent) {
|
|
|
1043
1098
|
|
|
1044
1099
|
// src/commands/issue/attachment/list.ts
|
|
1045
1100
|
function list3(parent) {
|
|
1046
|
-
const cmd = parent.command("list
|
|
1101
|
+
const cmd = parent.command("list").description("List attachments on an issue").argument("<key>", "Issue key", issueKey);
|
|
1047
1102
|
examples(cmd, ["PROJ-123"]);
|
|
1048
1103
|
cmd.action(async (key) => {
|
|
1049
1104
|
const client = getClient();
|
|
@@ -1068,7 +1123,7 @@ function list3(parent) {
|
|
|
1068
1123
|
|
|
1069
1124
|
// src/commands/issue/attachment/upload.ts
|
|
1070
1125
|
function upload(parent) {
|
|
1071
|
-
const cmd = parent.command("upload
|
|
1126
|
+
const cmd = parent.command("upload").description("Upload attachments to an issue").argument("<key>", "Issue key", issueKey).requiredOption("--files <paths>", "Comma-separated file paths to upload", text);
|
|
1072
1127
|
examples(cmd, ["PROJ-123 --files ./report.pdf", "PROJ-123 --files ./a.txt,./b.png"]);
|
|
1073
1128
|
cmd.action(async (key, opts) => {
|
|
1074
1129
|
const client = getClient();
|
|
@@ -1111,7 +1166,7 @@ function registerAttachmentCommands(parent) {
|
|
|
1111
1166
|
|
|
1112
1167
|
// src/commands/issue/batch-changelog.ts
|
|
1113
1168
|
function batchChangelog(parent) {
|
|
1114
|
-
const cmd = parent.command("batch-changelog
|
|
1169
|
+
const cmd = parent.command("batch-changelog").description("Get changelogs for multiple issues at once").argument("<keys>", "Comma-separated issue keys", text).option("--limit <number>", "Max changelog entries per issue (1-50, Jira DC caps at 50)", intInRange(1, 50), 25);
|
|
1115
1170
|
examples(cmd, ["PROJ-1,PROJ-2,PROJ-3", "PROJ-123,PROJ-124 --limit 10"]);
|
|
1116
1171
|
cmd.action(async (keys, opts) => {
|
|
1117
1172
|
const client = getClient();
|
|
@@ -1131,14 +1186,16 @@ function batchChangelog(parent) {
|
|
|
1131
1186
|
}
|
|
1132
1187
|
|
|
1133
1188
|
// src/commands/issue/batch-create.ts
|
|
1189
|
+
import { z } from "zod";
|
|
1190
|
+
var issuesSchema = z.array(z.record(z.unknown())).min(1, "must be a non-empty array");
|
|
1134
1191
|
function batchCreate(parent) {
|
|
1135
|
-
const cmd = parent.command("batch-create").description("Create multiple issues from a JSON array").requiredOption("--issues <json>", "JSON array of issue objects");
|
|
1192
|
+
const cmd = parent.command("batch-create").description("Create multiple issues from a JSON array").requiredOption("--issues <json>", "JSON array of issue objects", jsonShape(issuesSchema));
|
|
1136
1193
|
examples(cmd, [
|
|
1137
1194
|
`--issues '[{"projectKeyOrId":"PROJ","issueTypeName":"Task","summary":"Task 1"},{"projectKeyOrId":"PROJ","issueTypeName":"Task","summary":"Task 2"}]'`
|
|
1138
1195
|
]);
|
|
1139
1196
|
cmd.action(async (opts) => {
|
|
1140
1197
|
const client = getClient();
|
|
1141
|
-
const parsed =
|
|
1198
|
+
const parsed = opts.issues;
|
|
1142
1199
|
const results = [];
|
|
1143
1200
|
for (const issue of parsed) {
|
|
1144
1201
|
try {
|
|
@@ -1154,7 +1211,7 @@ function batchCreate(parent) {
|
|
|
1154
1211
|
|
|
1155
1212
|
// src/commands/issue/changelog.ts
|
|
1156
1213
|
function changelog(parent) {
|
|
1157
|
-
const cmd = parent.command("changelog
|
|
1214
|
+
const cmd = parent.command("changelog").description("Get changelog for an issue").argument("<key>", "Issue key", issueKey).option("--limit <number>", "Max changelog entries (1-50, Jira DC caps at 50)", intInRange(1, 50), 25);
|
|
1158
1215
|
examples(cmd, ["PROJ-123", "PROJ-123 --limit 10"]);
|
|
1159
1216
|
cmd.action(async (key, opts) => {
|
|
1160
1217
|
const client = getClient();
|
|
@@ -1182,7 +1239,7 @@ var CLONE_FIELDS = [
|
|
|
1182
1239
|
"issuelinks"
|
|
1183
1240
|
];
|
|
1184
1241
|
function clone(parent) {
|
|
1185
|
-
const cmd = parent.command("clone
|
|
1242
|
+
const cmd = parent.command("clone").description("Clone an issue (create a duplicate with the same fields)").argument("<key>", "Issue key", issueKey).option("--summary <text>", 'Override the summary (default: "CLONE - <original>")', text).option("--project <key>", "Create in a different project", text).option("--assignee <username>", "Override assignee", text).option("--include-attachments", "Copy attachments to the cloned issue").option("--include-links", "Copy issue links to the cloned issue");
|
|
1186
1243
|
examples(cmd, [
|
|
1187
1244
|
"PROJ-123",
|
|
1188
1245
|
'PROJ-123 --summary "Cloned: new title"',
|
|
@@ -1259,7 +1316,7 @@ function clone(parent) {
|
|
|
1259
1316
|
|
|
1260
1317
|
// src/commands/issue/comment/create.ts
|
|
1261
1318
|
function create2(parent) {
|
|
1262
|
-
const cmd = parent.command("create
|
|
1319
|
+
const cmd = parent.command("create").description("Add a comment to an issue").argument("<key>", "Issue key", issueKey);
|
|
1263
1320
|
bodyOption(cmd);
|
|
1264
1321
|
examples(cmd, ['PROJ-123 --body "Fixed in latest build"']);
|
|
1265
1322
|
cmd.action(async (key, opts) => {
|
|
@@ -1272,7 +1329,7 @@ function create2(parent) {
|
|
|
1272
1329
|
|
|
1273
1330
|
// src/commands/issue/comment/delete.ts
|
|
1274
1331
|
function deleteComment(parent) {
|
|
1275
|
-
const cmd = parent.command("delete
|
|
1332
|
+
const cmd = parent.command("delete").description("Delete a comment from an issue").argument("<key>", "Issue key", issueKey);
|
|
1276
1333
|
subEntityOption(cmd, "comment", { mandatory: true });
|
|
1277
1334
|
examples(cmd, ["PROJ-123 --comment-id 12345"]);
|
|
1278
1335
|
cmd.action(async (key, opts) => {
|
|
@@ -1284,7 +1341,7 @@ function deleteComment(parent) {
|
|
|
1284
1341
|
|
|
1285
1342
|
// src/commands/issue/comment/update.ts
|
|
1286
1343
|
function update2(parent) {
|
|
1287
|
-
const cmd = parent.command("update
|
|
1344
|
+
const cmd = parent.command("update").description("Update an existing comment").argument("<key>", "Issue key", issueKey);
|
|
1288
1345
|
subEntityOption(cmd, "comment", { mandatory: true });
|
|
1289
1346
|
bodyOption(cmd);
|
|
1290
1347
|
examples(cmd, ['PROJ-123 --comment-id 12345 --body "Updated comment text"']);
|
|
@@ -1314,32 +1371,40 @@ function registerCommentCommands(parent) {
|
|
|
1314
1371
|
}
|
|
1315
1372
|
|
|
1316
1373
|
// src/commands/issue/create.ts
|
|
1374
|
+
import { z as z2 } from "zod";
|
|
1375
|
+
var customFieldsSchema = z2.record(z2.unknown());
|
|
1317
1376
|
function create3(parent) {
|
|
1318
|
-
const cmd = parent.command("create").description("Create a new issue").requiredOption("--project <key>", "Project key or ID").requiredOption("--type <name>", "Issue type name (e.g., Task, Bug, Story)").requiredOption("--summary <text>", "Issue summary/title").option("--assignee <
|
|
1377
|
+
const cmd = parent.command("create").description("Create a new issue").requiredOption("--project <key>", "Project key or ID", text).requiredOption("--type <name>", "Issue type name (e.g., Task, Bug, Story)", text).requiredOption("--summary <text>", "Issue summary/title", text).option("--assignee <user>", 'Assignee. Username, "me", or "none" to leave unassigned.', text).option("--reporter <user>", 'Reporter. Username or "me".', text).option("--priority <name>", "Priority name (e.g., High, Medium, Low)", text).option("--labels <labels>", "Comma-separated labels", text).option("--components <names>", "Comma-separated component names", text).option("--fix-versions <versions>", "Comma-separated fix version names", text).option("--due-date <date>", "Due date in YYYY-MM-DD format", date).option("--parent <key>", "Parent issue key (for subtasks)", issueKey).option(
|
|
1378
|
+
"--custom-fields <json>",
|
|
1379
|
+
`Additional custom fields as JSON (e.g., '{"customfield_10100": "EPIC-1"}')`,
|
|
1380
|
+
jsonShape(customFieldsSchema)
|
|
1381
|
+
);
|
|
1319
1382
|
textOrFileOption(cmd, "description", { description: "Issue description in wiki markup" });
|
|
1320
1383
|
examples(cmd, [
|
|
1321
1384
|
'--project PROJ --type Task --summary "Fix login bug"',
|
|
1322
|
-
'--project PROJ --type Story --summary "New feature" --assignee
|
|
1385
|
+
'--project PROJ --type Story --summary "New feature" --assignee me --priority High',
|
|
1323
1386
|
'--project PROJ --type Bug --summary "Urgent" --labels urgent,production --components Backend'
|
|
1324
1387
|
]);
|
|
1325
1388
|
cmd.action(
|
|
1326
1389
|
async (opts) => {
|
|
1327
1390
|
const description = resolveTextOrFile(opts, "description", { required: false });
|
|
1391
|
+
const assignee = opts.assignee !== void 0 ? await resolveUserToken(opts.assignee) : void 0;
|
|
1392
|
+
const reporter = opts.reporter !== void 0 ? await resolveUserToken(opts.reporter) : void 0;
|
|
1328
1393
|
const client = getClient();
|
|
1329
1394
|
const result = await client.issues.create({
|
|
1330
1395
|
projectKeyOrId: opts.project,
|
|
1331
1396
|
issueTypeName: opts.type,
|
|
1332
1397
|
summary: opts.summary,
|
|
1333
1398
|
description,
|
|
1334
|
-
assignee:
|
|
1335
|
-
reporter:
|
|
1399
|
+
assignee: assignee ?? void 0,
|
|
1400
|
+
reporter: reporter ?? void 0,
|
|
1336
1401
|
priority: opts.priority,
|
|
1337
1402
|
labels: opts.labels?.split(",").map((l) => l.trim()),
|
|
1338
1403
|
components: opts.components?.split(",").map((c) => c.trim()),
|
|
1339
1404
|
fixVersions: opts.fixVersions?.split(",").map((v) => v.trim()),
|
|
1340
1405
|
dueDate: opts.dueDate,
|
|
1341
1406
|
parent: opts.parent,
|
|
1342
|
-
customFields: opts.customFields
|
|
1407
|
+
customFields: opts.customFields
|
|
1343
1408
|
});
|
|
1344
1409
|
output(transformCreatedIssue(result));
|
|
1345
1410
|
}
|
|
@@ -1348,7 +1413,7 @@ function create3(parent) {
|
|
|
1348
1413
|
|
|
1349
1414
|
// src/commands/issue/delete.ts
|
|
1350
1415
|
function deleteIssue(parent) {
|
|
1351
|
-
const cmd = parent.command("delete
|
|
1416
|
+
const cmd = parent.command("delete").description("Delete an issue").argument("<key>", "Issue key", issueKey).option("--delete-subtasks", "Also delete subtasks (default: false)");
|
|
1352
1417
|
examples(cmd, ["PROJ-123", "PROJ-123 --delete-subtasks"]);
|
|
1353
1418
|
cmd.action(async (key, opts) => {
|
|
1354
1419
|
const client = getClient();
|
|
@@ -1359,7 +1424,7 @@ function deleteIssue(parent) {
|
|
|
1359
1424
|
|
|
1360
1425
|
// src/commands/issue/dev-status.ts
|
|
1361
1426
|
function devStatus(parent) {
|
|
1362
|
-
const cmd = parent.command("dev-status
|
|
1427
|
+
const cmd = parent.command("dev-status").description("Get development status (PRs, commits, branches, builds) for an issue").argument("<key>", "Issue key", issueKey).option("--detail", "Include PR URLs, commit IDs, and other details");
|
|
1363
1428
|
examples(cmd, ["PROJ-123", "PROJ-123 --detail"]);
|
|
1364
1429
|
cmd.action(async (key, opts) => {
|
|
1365
1430
|
const client = getClient();
|
|
@@ -1453,7 +1518,7 @@ var DEFAULT_FIELDS = [
|
|
|
1453
1518
|
|
|
1454
1519
|
// src/commands/issue/get.ts
|
|
1455
1520
|
function get2(parent) {
|
|
1456
|
-
const cmd = parent.command("get
|
|
1521
|
+
const cmd = parent.command("get").description("Get issue details").argument("<key>", "Issue key", issueKey).option("--fields <fields>", "Comma-separated fields to return (defaults to essential fields)", text).option("--all-fields", "Return all fields instead of defaults").option("--expand <expand>", 'Expand options (e.g., "transitions", "changelog")', text);
|
|
1457
1522
|
examples(cmd, [
|
|
1458
1523
|
"PROJ-123",
|
|
1459
1524
|
"PROJ-123 --fields summary,status,assignee",
|
|
@@ -1474,7 +1539,7 @@ function get2(parent) {
|
|
|
1474
1539
|
|
|
1475
1540
|
// src/commands/issue/link-epic.ts
|
|
1476
1541
|
function linkEpic(parent) {
|
|
1477
|
-
const cmd = parent.command("link-epic
|
|
1542
|
+
const cmd = parent.command("link-epic").description("Link one or more issues to an epic").argument("<keys...>", "Issue keys to link", issueKey).requiredOption("--epic <epicKey>", "Epic issue key", issueKey);
|
|
1478
1543
|
examples(cmd, ["PROJ-456 --epic PROJ-123", "PROJ-456 PROJ-457 PROJ-458 --epic PROJ-123"]);
|
|
1479
1544
|
cmd.action(async (keys, opts) => {
|
|
1480
1545
|
const client = getClient();
|
|
@@ -1517,7 +1582,7 @@ function linkTypes(parent) {
|
|
|
1517
1582
|
|
|
1518
1583
|
// src/commands/issue/link.ts
|
|
1519
1584
|
function link(parent) {
|
|
1520
|
-
const cmd = parent.command("link").description("Link two issues together").requiredOption("--type <name>", "Link type name (e.g., 'Blocks', 'Duplicate', 'Relates')").requiredOption("--from <key>", 'Source issue key (e.g., the issue that "blocks")').requiredOption("--to <key>", 'Target issue key (e.g., the issue that "is blocked by")');
|
|
1585
|
+
const cmd = parent.command("link").description("Link two issues together").requiredOption("--type <name>", "Link type name (e.g., 'Blocks', 'Duplicate', 'Relates')", text).requiredOption("--from <key>", 'Source issue key (e.g., the issue that "blocks")', issueKey).requiredOption("--to <key>", 'Target issue key (e.g., the issue that "is blocked by")', issueKey);
|
|
1521
1586
|
commentOption(cmd, { description: "Optional comment" });
|
|
1522
1587
|
examples(cmd, [
|
|
1523
1588
|
"--type Relates --from AI-154 --to AI-149",
|
|
@@ -1543,7 +1608,7 @@ function link(parent) {
|
|
|
1543
1608
|
|
|
1544
1609
|
// src/commands/issue/search.ts
|
|
1545
1610
|
function search2(parent) {
|
|
1546
|
-
const cmd = parent.command("search
|
|
1611
|
+
const cmd = parent.command("search").description("Search issues using JQL").argument("<jql>", "JQL query string", text).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated fields to return (defaults to essential fields)", text).option("--all-fields", "Return all fields instead of defaults");
|
|
1547
1612
|
examples(cmd, [
|
|
1548
1613
|
'"project = PROJ AND status = Open"',
|
|
1549
1614
|
'"assignee = currentUser()" --limit 10 --fields summary,status',
|
|
@@ -1564,7 +1629,7 @@ function search2(parent) {
|
|
|
1564
1629
|
|
|
1565
1630
|
// src/commands/issue/transition.ts
|
|
1566
1631
|
function transition(parent) {
|
|
1567
|
-
const cmd = parent.command("transition
|
|
1632
|
+
const cmd = parent.command("transition").description("Transition issue to a new status").argument("<key>", "Issue key", issueKey).requiredOption("--to <idOrName>", "Transition ID, or status name (case-insensitive)", text);
|
|
1568
1633
|
commentOption(cmd, { description: "Comment to add during transition" });
|
|
1569
1634
|
examples(cmd, [
|
|
1570
1635
|
"PROJ-123 --to 31",
|
|
@@ -1602,7 +1667,7 @@ function transition(parent) {
|
|
|
1602
1667
|
|
|
1603
1668
|
// src/commands/issue/transitions.ts
|
|
1604
1669
|
function transitions(parent) {
|
|
1605
|
-
const cmd = parent.command("transitions
|
|
1670
|
+
const cmd = parent.command("transitions").description("Get available transitions for an issue").argument("<key>", "Issue key", issueKey);
|
|
1606
1671
|
examples(cmd, ["PROJ-123"]);
|
|
1607
1672
|
cmd.action(async (key) => {
|
|
1608
1673
|
const client = getClient();
|
|
@@ -1616,30 +1681,33 @@ function transitions(parent) {
|
|
|
1616
1681
|
|
|
1617
1682
|
// src/commands/issue/unlink.ts
|
|
1618
1683
|
function unlink2(parent) {
|
|
1619
|
-
const cmd = parent.command("unlink
|
|
1684
|
+
const cmd = parent.command("unlink").description("Remove a link between two issues").argument("<id>", "Link ID", positiveInt);
|
|
1620
1685
|
examples(cmd, ["12345"]);
|
|
1621
1686
|
cmd.action(async (id) => {
|
|
1622
1687
|
const client = getClient();
|
|
1623
|
-
await client.links.remove({ linkId: id });
|
|
1688
|
+
await client.links.remove({ linkId: String(id) });
|
|
1624
1689
|
output({ removed: true, linkId: id });
|
|
1625
1690
|
});
|
|
1626
1691
|
}
|
|
1627
1692
|
|
|
1693
|
+
// src/commands/issue/update.ts
|
|
1694
|
+
import { z as z3 } from "zod";
|
|
1695
|
+
|
|
1628
1696
|
// src/utils/multi-value.ts
|
|
1629
|
-
import { InvalidArgumentError as
|
|
1697
|
+
import { InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
1630
1698
|
function parseMultiValue(flagName, raw) {
|
|
1631
1699
|
const items = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
1632
1700
|
if (items.length === 0) {
|
|
1633
|
-
throw new
|
|
1701
|
+
throw new InvalidArgumentError5(`${flagName} cannot be empty`);
|
|
1634
1702
|
}
|
|
1635
1703
|
const lonePrefix = items.find((s) => s === "+" || s === "-");
|
|
1636
1704
|
if (lonePrefix !== void 0) {
|
|
1637
|
-
throw new
|
|
1705
|
+
throw new InvalidArgumentError5(`${flagName} has an empty value after '${lonePrefix}' prefix`);
|
|
1638
1706
|
}
|
|
1639
1707
|
const prefixed = items.filter((s) => s.startsWith("+") || s.startsWith("-"));
|
|
1640
1708
|
const bare = items.filter((s) => !s.startsWith("+") && !s.startsWith("-"));
|
|
1641
1709
|
if (prefixed.length > 0 && bare.length > 0) {
|
|
1642
|
-
throw new
|
|
1710
|
+
throw new InvalidArgumentError5(
|
|
1643
1711
|
`${flagName} mixes set and mutate syntax. Either all values have +/- prefix, or none do.`
|
|
1644
1712
|
);
|
|
1645
1713
|
}
|
|
@@ -1652,6 +1720,7 @@ function parseMultiValue(flagName, raw) {
|
|
|
1652
1720
|
}
|
|
1653
1721
|
|
|
1654
1722
|
// src/commands/issue/update.ts
|
|
1723
|
+
var fieldsSchema = z3.record(z3.unknown());
|
|
1655
1724
|
function buildUpdateOps(parsed, wrap) {
|
|
1656
1725
|
if (parsed.mode !== "mutate") return void 0;
|
|
1657
1726
|
return [...parsed.adds.map((v) => ({ add: wrap(v) })), ...parsed.removes.map((v) => ({ remove: wrap(v) }))];
|
|
@@ -1661,7 +1730,11 @@ function buildSetValue(parsed, wrap) {
|
|
|
1661
1730
|
return parsed.values.map(wrap);
|
|
1662
1731
|
}
|
|
1663
1732
|
function update3(parent) {
|
|
1664
|
-
const cmd = parent.command("update
|
|
1733
|
+
const cmd = parent.command("update").description("Update issue fields").argument("<key>", "Issue key", issueKey).option(
|
|
1734
|
+
"--fields <json>",
|
|
1735
|
+
"JSON string of fields to update (advanced; merges with shortcuts, wins on conflict)",
|
|
1736
|
+
jsonShape(fieldsSchema)
|
|
1737
|
+
).option("--no-notify-users", "Suppress notification emails (default: notify)").option("--attachments <paths>", "Comma-separated local file paths to attach", text).option("--summary <text>", "Set the issue summary", text).option("--priority <name>", "Set the priority by name (e.g. High)", text).option("--assignee <user>", 'Set the assignee. Username, "me", or "none" to unassign.', text).option("--labels <list>", 'Set labels ("a,b,c") or mutate ("+add,-remove")', text).option("--components <list>", 'Set components ("a,b") or mutate ("+add,-remove")', text).option("--fix-versions <list>", 'Set fix versions ("1.0,2.0") or mutate ("+1.0,-0.9")', text);
|
|
1665
1738
|
textOrFileOption(cmd, "description", { description: "Set the issue description (wiki markup)" });
|
|
1666
1739
|
examples(cmd, [
|
|
1667
1740
|
'PROJ-123 --summary "New title"',
|
|
@@ -1710,8 +1783,7 @@ function update3(parent) {
|
|
|
1710
1783
|
if (ops) updateOps.fixVersions = ops;
|
|
1711
1784
|
}
|
|
1712
1785
|
if (opts.fields) {
|
|
1713
|
-
|
|
1714
|
-
Object.assign(fields, parsedFields);
|
|
1786
|
+
Object.assign(fields, opts.fields);
|
|
1715
1787
|
}
|
|
1716
1788
|
const client = getClient();
|
|
1717
1789
|
const didFieldUpdate = Object.keys(fields).length > 0 || Object.keys(updateOps).length > 0;
|
|
@@ -1743,7 +1815,7 @@ function update3(parent) {
|
|
|
1743
1815
|
|
|
1744
1816
|
// src/commands/issue/worklog/create.ts
|
|
1745
1817
|
function create4(parent) {
|
|
1746
|
-
const cmd = parent.command("create
|
|
1818
|
+
const cmd = parent.command("create").description("Log time spent on an issue").argument("<key>", "Issue key", issueKey).requiredOption("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')", text).option("--started <datetime>", "Start time in ISO 8601 format", dateTime);
|
|
1747
1819
|
commentOption(cmd, { description: "Worklog comment" });
|
|
1748
1820
|
examples(cmd, [
|
|
1749
1821
|
"PROJ-123 --time 2h",
|
|
@@ -1767,11 +1839,12 @@ function create4(parent) {
|
|
|
1767
1839
|
import { Option as Option5 } from "commander";
|
|
1768
1840
|
var ADJUST_ESTIMATE = ["new", "leave", "manual", "auto"];
|
|
1769
1841
|
function deleteWorklog(parent) {
|
|
1770
|
-
const cmd = parent.command("delete
|
|
1842
|
+
const cmd = parent.command("delete").description("Delete a worklog entry").argument("<key>", "Issue key", issueKey);
|
|
1771
1843
|
subEntityOption(cmd, "worklog", { mandatory: true });
|
|
1772
|
-
cmd.addOption(new Option5("--adjust-estimate <mode>", "How to adjust the remaining estimate").choices(ADJUST_ESTIMATE)).option("--new-estimate <estimate>", 'New remaining estimate; required when --adjust-estimate is "new"').option(
|
|
1844
|
+
cmd.addOption(new Option5("--adjust-estimate <mode>", "How to adjust the remaining estimate").choices(ADJUST_ESTIMATE)).option("--new-estimate <estimate>", 'New remaining estimate; required when --adjust-estimate is "new"', text).option(
|
|
1773
1845
|
"--increase-by <amount>",
|
|
1774
|
-
'Amount to increase the estimate by; required when --adjust-estimate is "manual"'
|
|
1846
|
+
'Amount to increase the estimate by; required when --adjust-estimate is "manual"',
|
|
1847
|
+
text
|
|
1775
1848
|
);
|
|
1776
1849
|
examples(cmd, [
|
|
1777
1850
|
"PROJ-123 --worklog-id 12345",
|
|
@@ -1795,7 +1868,7 @@ function deleteWorklog(parent) {
|
|
|
1795
1868
|
|
|
1796
1869
|
// src/commands/issue/worklog/list.ts
|
|
1797
1870
|
function list4(parent) {
|
|
1798
|
-
const cmd = parent.command("list
|
|
1871
|
+
const cmd = parent.command("list").description("Get worklogs for an issue").argument("<key>", "Issue key", issueKey).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--limit <number>", "Max results per page (1-1000)", intInRange(1, 1e3), 25);
|
|
1799
1872
|
examples(cmd, ["PROJ-123", "PROJ-123 --limit 10", "PROJ-123 --start 10 --limit 5"]);
|
|
1800
1873
|
cmd.action(async (key, opts) => {
|
|
1801
1874
|
const client = getClient();
|
|
@@ -1812,9 +1885,9 @@ function list4(parent) {
|
|
|
1812
1885
|
import { Option as Option6 } from "commander";
|
|
1813
1886
|
var ADJUST_ESTIMATE2 = ["new", "leave", "auto"];
|
|
1814
1887
|
function update4(parent) {
|
|
1815
|
-
const cmd = parent.command("update
|
|
1888
|
+
const cmd = parent.command("update").description("Update an existing worklog entry").argument("<key>", "Issue key", issueKey);
|
|
1816
1889
|
subEntityOption(cmd, "worklog", { mandatory: true });
|
|
1817
|
-
cmd.option("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')").option("--started <datetime>", "Start time in ISO 8601 format").addOption(new Option6("--adjust-estimate <mode>", "How to adjust the remaining estimate").choices(ADJUST_ESTIMATE2)).option("--new-estimate <estimate>", 'New remaining estimate; required when --adjust-estimate is "new"');
|
|
1890
|
+
cmd.option("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')", text).option("--started <datetime>", "Start time in ISO 8601 format", dateTime).addOption(new Option6("--adjust-estimate <mode>", "How to adjust the remaining estimate").choices(ADJUST_ESTIMATE2)).option("--new-estimate <estimate>", 'New remaining estimate; required when --adjust-estimate is "new"', text);
|
|
1818
1891
|
commentOption(cmd, { description: "Worklog comment" });
|
|
1819
1892
|
examples(cmd, [
|
|
1820
1893
|
'PROJ-123 --worklog-id 12345 --time "1h 30m"',
|
|
@@ -1889,7 +1962,7 @@ function registerIssueCommands(program) {
|
|
|
1889
1962
|
|
|
1890
1963
|
// src/commands/project/list.ts
|
|
1891
1964
|
function list5(parent) {
|
|
1892
|
-
const cmd = parent.command("list").description("List all projects").option("--expand <expand>", 'Expand options (e.g., "description,lead")').option("--include-archived", "Include archived projects (default: false)");
|
|
1965
|
+
const cmd = parent.command("list").description("List all projects").option("--expand <expand>", 'Expand options (e.g., "description,lead")', text).option("--include-archived", "Include archived projects (default: false)");
|
|
1893
1966
|
examples(cmd, ["", "--expand description,lead", "--include-archived"]);
|
|
1894
1967
|
cmd.action(async (opts) => {
|
|
1895
1968
|
const client = getClient();
|
|
@@ -1900,7 +1973,7 @@ function list5(parent) {
|
|
|
1900
1973
|
|
|
1901
1974
|
// src/commands/project/versions.ts
|
|
1902
1975
|
function versions(parent) {
|
|
1903
|
-
const cmd = parent.command("versions
|
|
1976
|
+
const cmd = parent.command("versions").description("Get all versions for a project").argument("<key>", "Project key", text).option("--expand <expand>", "Expand options", text);
|
|
1904
1977
|
examples(cmd, ["PROJ", "PROJ --expand operations"]);
|
|
1905
1978
|
cmd.action(async (key, opts) => {
|
|
1906
1979
|
const client = getClient();
|
|
@@ -1919,7 +1992,7 @@ function registerProjectCommands(program) {
|
|
|
1919
1992
|
|
|
1920
1993
|
// src/commands/sprint/create.ts
|
|
1921
1994
|
function create5(parent) {
|
|
1922
|
-
const cmd = parent.command("create").description("Create a new sprint").requiredOption("--board <id>", "Board ID to create sprint in", positiveInt).requiredOption("--name <name>", "Sprint name").option("--start-date <date>", "Start date in ISO 8601 format").option("--end-date <date>", "End date in ISO 8601 format").option("--goal <goal>", "Sprint goal");
|
|
1995
|
+
const cmd = parent.command("create").description("Create a new sprint").requiredOption("--board <id>", "Board ID to create sprint in", positiveInt).requiredOption("--name <name>", "Sprint name", text).option("--start-date <date>", "Start date in ISO 8601 format", text).option("--end-date <date>", "End date in ISO 8601 format", text).option("--goal <goal>", "Sprint goal", text);
|
|
1923
1996
|
examples(cmd, [
|
|
1924
1997
|
'--board 42 --name "Sprint 10"',
|
|
1925
1998
|
'--board 42 --name "Sprint 10" --start-date 2026-03-20 --end-date 2026-04-03 --goal "Complete auth module"'
|
|
@@ -1952,7 +2025,7 @@ function deleteSprint(parent) {
|
|
|
1952
2025
|
// src/commands/sprint/issues.ts
|
|
1953
2026
|
import { Argument as Argument3 } from "commander";
|
|
1954
2027
|
function issues2(parent) {
|
|
1955
|
-
const cmd = parent.command("issues").description("Get issues in a sprint").addArgument(new Argument3("<id>", "Sprint ID").argParser(positiveInt)).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated field names to return").option("--jql <jql>", "Additional JQL filter within the sprint");
|
|
2028
|
+
const cmd = parent.command("issues").description("Get issues in a sprint").addArgument(new Argument3("<id>", "Sprint ID").argParser(positiveInt)).option("--limit <number>", "Max results (1-50, Jira DC caps at 50)", intInRange(1, 50), 25).option("--start <number>", "Starting index for pagination", nonNegativeInt).option("--fields <fields>", "Comma-separated field names to return", text).option("--jql <jql>", "Additional JQL filter within the sprint", text);
|
|
1956
2029
|
examples(cmd, [
|
|
1957
2030
|
"100",
|
|
1958
2031
|
"100 --limit 20",
|
|
@@ -1992,7 +2065,7 @@ function list6(parent) {
|
|
|
1992
2065
|
import { Argument as Argument4, Option as Option8 } from "commander";
|
|
1993
2066
|
var SPRINT_STATES2 = ["future", "active", "closed"];
|
|
1994
2067
|
function update5(parent) {
|
|
1995
|
-
const cmd = parent.command("update").description("Update an existing sprint").addArgument(new Argument4("<id>", "Sprint ID").argParser(positiveInt)).option("--name <name>", "New sprint name").addOption(new Option8("--state <state>", "New sprint state").choices(SPRINT_STATES2)).option("--start-date <date>", "New start date in ISO 8601 format").option("--end-date <date>", "New end date in ISO 8601 format").option("--goal <goal>", "New sprint goal");
|
|
2068
|
+
const cmd = parent.command("update").description("Update an existing sprint").addArgument(new Argument4("<id>", "Sprint ID").argParser(positiveInt)).option("--name <name>", "New sprint name", text).addOption(new Option8("--state <state>", "New sprint state").choices(SPRINT_STATES2)).option("--start-date <date>", "New start date in ISO 8601 format", text).option("--end-date <date>", "New end date in ISO 8601 format", text).option("--goal <goal>", "New sprint goal", text);
|
|
1996
2069
|
examples(cmd, [
|
|
1997
2070
|
'100 --name "Sprint 10 - Extended"',
|
|
1998
2071
|
"100 --state active",
|
|
@@ -2050,13 +2123,14 @@ function getTokenClient(options2 = {}) {
|
|
|
2050
2123
|
|
|
2051
2124
|
// src/commands/token/create.ts
|
|
2052
2125
|
function create6(parent) {
|
|
2053
|
-
const cmd = parent.command("create").description("Create a Personal Access Token. The secret is returned exactly once.").requiredOption("--name <name>", "Token name").option(
|
|
2126
|
+
const cmd = parent.command("create").description("Create a Personal Access Token. The secret is returned exactly once.").requiredOption("--name <name>", "Token name", text).option(
|
|
2054
2127
|
"--expiration-duration <days>",
|
|
2055
2128
|
"Token lifetime in days. Omit for a non-expiring token (admin policy permitting).",
|
|
2056
2129
|
positiveInt
|
|
2057
|
-
).option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME").option(
|
|
2130
|
+
).option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME", text).option(
|
|
2058
2131
|
"--basic-password <p>",
|
|
2059
|
-
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)"
|
|
2132
|
+
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)",
|
|
2133
|
+
text
|
|
2060
2134
|
);
|
|
2061
2135
|
examples(cmd, [["--name my-pat", "non-expiring"], "--name svc-token --expiration-duration 365"]);
|
|
2062
2136
|
cmd.action(async (opts) => {
|
|
@@ -2076,9 +2150,10 @@ function create6(parent) {
|
|
|
2076
2150
|
|
|
2077
2151
|
// src/commands/token/list.ts
|
|
2078
2152
|
function list7(parent) {
|
|
2079
|
-
const cmd = parent.command("list").description("List Personal Access Tokens owned by the authenticated user (secrets not included)").option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME").option(
|
|
2153
|
+
const cmd = parent.command("list").description("List Personal Access Tokens owned by the authenticated user (secrets not included)").option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME", text).option(
|
|
2080
2154
|
"--basic-password <p>",
|
|
2081
|
-
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)"
|
|
2155
|
+
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)",
|
|
2156
|
+
text
|
|
2082
2157
|
);
|
|
2083
2158
|
examples(cmd, [""]);
|
|
2084
2159
|
cmd.action(async (opts) => {
|
|
@@ -2092,9 +2167,10 @@ function list7(parent) {
|
|
|
2092
2167
|
|
|
2093
2168
|
// src/commands/token/revoke.ts
|
|
2094
2169
|
function revoke(parent) {
|
|
2095
|
-
const cmd = parent.command("revoke").description("Revoke a Personal Access Token by id").option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME").option(
|
|
2170
|
+
const cmd = parent.command("revoke").description("Revoke a Personal Access Token by id").option("--basic-username <u>", "Override $JIRA_BASIC_USERNAME", text).option(
|
|
2096
2171
|
"--basic-password <p>",
|
|
2097
|
-
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)"
|
|
2172
|
+
"Override $JIRA_BASIC_PASSWORD (caution: visible in process table; prefer the env var)",
|
|
2173
|
+
text
|
|
2098
2174
|
);
|
|
2099
2175
|
subjectArg(cmd, "tokenId", { parser: positiveInt, description: "Token id to revoke" });
|
|
2100
2176
|
examples(cmd, ["173"]);
|
|
@@ -2123,7 +2199,7 @@ function registerTokenCommands(program) {
|
|
|
2123
2199
|
|
|
2124
2200
|
// src/commands/user/get.ts
|
|
2125
2201
|
function get3(parent) {
|
|
2126
|
-
const cmd = parent.command("get
|
|
2202
|
+
const cmd = parent.command("get").description("Get a user profile by exact username or key").argument("<username>", "Username or user key", text).option("--by-key", "Treat the positional argument as a user key instead of a username");
|
|
2127
2203
|
examples(cmd, ["jsmith", "JIRAUSER10100 --by-key"]);
|
|
2128
2204
|
cmd.action(async (identifier, opts) => {
|
|
2129
2205
|
const client = getClient();
|
|
@@ -2145,7 +2221,7 @@ function me(parent) {
|
|
|
2145
2221
|
|
|
2146
2222
|
// src/commands/user/search.ts
|
|
2147
2223
|
function search3(parent) {
|
|
2148
|
-
const cmd = parent.command("search
|
|
2224
|
+
const cmd = parent.command("search").description("Search users by partial username, display name or email").argument("<query>", "Search query", text).option("--limit <n>", "Maximum results (1-50)", intInRange(1, 50), 25).option("--start <n>", "Starting index (pagination offset)", nonNegativeInt, 0).option("--include-inactive", "Include inactive users in results", false);
|
|
2149
2225
|
examples(cmd, ["Smith", '"John Smith"', "jsmith@example.com --limit 5"]);
|
|
2150
2226
|
cmd.action(async (query, opts) => {
|
|
2151
2227
|
const client = getClient();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jiradc-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25-gc990f41.1",
|
|
4
4
|
"publish": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
],
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"commander": "^13.1.0",
|
|
15
|
-
"
|
|
15
|
+
"zod": "^3.25.67",
|
|
16
|
+
"jira-data-center-client": "1.0.39-gc990f41.1"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"@types/node": "24.10.4",
|