jiradc-cli 1.0.23 → 1.0.24

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.
Files changed (2) hide show
  1. package/dist/index.js +111 -38
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -48,6 +48,58 @@ function positiveInt(raw) {
48
48
  return n;
49
49
  }
50
50
 
51
+ // ../../cli-utils/dist/text-or-file.js
52
+ import { readFileSync as readFileSync3 } from "fs";
53
+ import { InvalidArgumentError as InvalidArgumentError2, Option } from "commander";
54
+ var STDIN_REF = "-";
55
+ function rejectStdinSentinel(value) {
56
+ if (value === "@-" || value === STDIN_REF) {
57
+ throw new InvalidArgumentError2(`"${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
+ }
59
+ return value;
60
+ }
61
+ function readFileOrStdin(ref) {
62
+ if (ref === STDIN_REF) {
63
+ if (process.stdin.isTTY) {
64
+ throw new InvalidArgumentError2('"--\u2026-file -" reads stdin, but stdin is a terminal (nothing piped).');
65
+ }
66
+ try {
67
+ return readFileSync3(0, "utf8");
68
+ } catch (err) {
69
+ throw new InvalidArgumentError2(`failed to read stdin for "--\u2026-file -": ${err.message}`);
70
+ }
71
+ }
72
+ try {
73
+ return readFileSync3(ref, "utf8");
74
+ } catch (err) {
75
+ const e = err;
76
+ if (e.code === "ENOENT") {
77
+ throw new InvalidArgumentError2(`file not found: "${ref}".`);
78
+ }
79
+ throw new InvalidArgumentError2(`failed to read file "${ref}": ${e.message}`);
80
+ }
81
+ }
82
+ function textOrFileOption(cmd, name, opts = {}) {
83
+ const label = `${name.charAt(0).toUpperCase()}${name.slice(1)} content`;
84
+ 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));
86
+ return cmd;
87
+ }
88
+ function resolveTextOrFile(opts, name, { required = true } = {}) {
89
+ const literal = opts[name];
90
+ const ref = opts[`${name}File`];
91
+ if (literal !== void 0 && ref !== void 0) {
92
+ throw new InvalidArgumentError2(`--${name} and --${name}-file are mutually exclusive; provide only one.`);
93
+ }
94
+ if (ref !== void 0) {
95
+ return readFileOrStdin(ref);
96
+ }
97
+ if (literal === void 0 && required) {
98
+ throw new InvalidArgumentError2(`a ${name} is required: provide --${name} <text> or --${name}-file <path>.`);
99
+ }
100
+ return literal;
101
+ }
102
+
51
103
  // ../../cli-utils/dist/registry.js
52
104
  var SUB_ENTITY_ID_NUMERIC = {
53
105
  comment: true,
@@ -78,7 +130,10 @@ function subEntityOption(cmd, entity, opts = {}) {
78
130
  return defineOption(cmd, `--${entity}-id <id>`, description, numeric ? positiveInt : void 0, opts.mandatory);
79
131
  }
80
132
  function bodyOption(cmd, opts = {}) {
81
- return defineOption(cmd, "--body <text>", "Prose body content", void 0, opts.mandatory);
133
+ return textOrFileOption(cmd, "body", { description: "Prose body content", ...opts });
134
+ }
135
+ function commentOption(cmd, opts = {}) {
136
+ return textOrFileOption(cmd, "comment", { description: "Optional note attached to the action", ...opts });
82
137
  }
83
138
  var EXAMPLES = /* @__PURE__ */ new WeakSet();
84
139
  function commandPath(cmd) {
@@ -683,10 +738,10 @@ function issues(parent) {
683
738
  }
684
739
 
685
740
  // src/commands/board/list.ts
686
- import { Option } from "commander";
741
+ import { Option as Option2 } from "commander";
687
742
  var BOARD_TYPES = ["scrum", "kanban", "simple"];
688
743
  function list(parent) {
689
- 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 Option("--type <type>", "Board type filter").choices(BOARD_TYPES)).option("--name <name>", "Filter boards by name");
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");
690
745
  examples(cmd, ["", "--limit 10", "--project PROJ", '--type scrum --name "Team Board"']);
691
746
  cmd.action(async (opts) => {
692
747
  const client = getClient();
@@ -709,7 +764,7 @@ function registerBoardCommands(program) {
709
764
  }
710
765
 
711
766
  // src/commands/component/create.ts
712
- import { Option as Option2 } from "commander";
767
+ import { Option as Option3 } from "commander";
713
768
  var ASSIGNEE_TYPES = [
714
769
  "PROJECT_DEFAULT",
715
770
  "COMPONENT_LEAD",
@@ -717,7 +772,8 @@ var ASSIGNEE_TYPES = [
717
772
  "UNASSIGNED"
718
773
  ];
719
774
  function create(parent) {
720
- 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("--description <text>", "Component description").option("--lead <username>", "Username of the component lead").addOption(new Option2("--assignee-type <type>", "Assignee strategy").choices(ASSIGNEE_TYPES));
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));
776
+ textOrFileOption(cmd, "description", { description: "Component description" });
721
777
  examples(cmd, [
722
778
  "--project AI --name Backend",
723
779
  '--project AI --name Frontend --description "UI work" --lead jsmith',
@@ -725,11 +781,12 @@ function create(parent) {
725
781
  ]);
726
782
  cmd.action(
727
783
  async (opts) => {
784
+ const description = resolveTextOrFile(opts, "description", { required: false });
728
785
  const client = getClient();
729
786
  const result = await client.components.create({
730
787
  project: opts.project,
731
788
  name: opts.name,
732
- description: opts.description,
789
+ description,
733
790
  leadUserName: opts.lead,
734
791
  assigneeType: opts.assigneeType
735
792
  });
@@ -783,7 +840,7 @@ function list2(parent) {
783
840
  }
784
841
 
785
842
  // src/commands/component/update.ts
786
- import { Option as Option3 } from "commander";
843
+ import { Option as Option4 } from "commander";
787
844
  var ASSIGNEE_TYPES2 = [
788
845
  "PROJECT_DEFAULT",
789
846
  "COMPONENT_LEAD",
@@ -791,7 +848,8 @@ var ASSIGNEE_TYPES2 = [
791
848
  "UNASSIGNED"
792
849
  ];
793
850
  function update(parent) {
794
- const cmd = parent.command("update <id>").description("Update an existing component (only provided fields are changed)").option("--name <name>", "New component name").option("--description <text>", "New component description").option("--lead <username>", "Username of the component lead (empty string clears it)").addOption(new Option3("--assignee-type <type>", "New assignee strategy").choices(ASSIGNEE_TYPES2));
851
+ const cmd = parent.command("update <id>").description("Update an existing component (only provided fields are changed)").option("--name <name>", "New component name").option("--lead <username>", "Username of the component lead (empty string clears it)").addOption(new Option4("--assignee-type <type>", "New assignee strategy").choices(ASSIGNEE_TYPES2));
852
+ textOrFileOption(cmd, "description", { description: "New component description" });
795
853
  examples(cmd, [
796
854
  "11289 --name Backend",
797
855
  '11289 --description "Server-side code"',
@@ -799,14 +857,15 @@ function update(parent) {
799
857
  ]);
800
858
  cmd.action(
801
859
  async (id, opts) => {
802
- if (opts.name === void 0 && opts.description === void 0 && opts.lead === void 0 && opts.assigneeType === void 0) {
860
+ const description = resolveTextOrFile(opts, "description", { required: false });
861
+ if (opts.name === void 0 && description === void 0 && opts.lead === void 0 && opts.assigneeType === void 0) {
803
862
  throw new Error("Provide at least one of --name, --description, --lead, --assignee-type");
804
863
  }
805
864
  const client = getClient();
806
865
  const result = await client.components.update({
807
866
  id,
808
867
  name: opts.name,
809
- description: opts.description,
868
+ description,
810
869
  leadUserName: opts.lead,
811
870
  assigneeType: opts.assigneeType
812
871
  });
@@ -1201,11 +1260,12 @@ function clone(parent) {
1201
1260
  // src/commands/issue/comment/create.ts
1202
1261
  function create2(parent) {
1203
1262
  const cmd = parent.command("create <key>").description("Add a comment to an issue");
1204
- bodyOption(cmd, { mandatory: true });
1263
+ bodyOption(cmd);
1205
1264
  examples(cmd, ['PROJ-123 --body "Fixed in latest build"']);
1206
1265
  cmd.action(async (key, opts) => {
1207
1266
  const client = getClient();
1208
- const result = await client.issues.addComment({ issueKeyOrId: key, body: opts.body });
1267
+ const body = resolveTextOrFile(opts, "body");
1268
+ const result = await client.issues.addComment({ issueKeyOrId: key, body });
1209
1269
  output(transformComment(result));
1210
1270
  });
1211
1271
  }
@@ -1226,14 +1286,15 @@ function deleteComment(parent) {
1226
1286
  function update2(parent) {
1227
1287
  const cmd = parent.command("update <key>").description("Update an existing comment");
1228
1288
  subEntityOption(cmd, "comment", { mandatory: true });
1229
- bodyOption(cmd, { mandatory: true });
1289
+ bodyOption(cmd);
1230
1290
  examples(cmd, ['PROJ-123 --comment-id 12345 --body "Updated comment text"']);
1231
1291
  cmd.action(async (key, opts) => {
1232
1292
  const client = getClient();
1293
+ const body = resolveTextOrFile(opts, "body");
1233
1294
  const result = await client.issues.editComment({
1234
1295
  issueKeyOrId: key,
1235
1296
  commentId: String(opts.commentId),
1236
- body: opts.body
1297
+ body
1237
1298
  });
1238
1299
  output(transformComment(result));
1239
1300
  });
@@ -1254,7 +1315,8 @@ function registerCommentCommands(parent) {
1254
1315
 
1255
1316
  // src/commands/issue/create.ts
1256
1317
  function create3(parent) {
1257
- 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("--description <text>", "Issue description in wiki markup").option("--assignee <username>", "Assignee username").option("--reporter <username>", "Reporter username").option("--priority <name>", "Priority name (e.g., High, Medium, Low)").option("--labels <labels>", "Comma-separated labels").option("--components <names>", "Comma-separated component names").option("--fix-versions <versions>", "Comma-separated fix version names").option("--due-date <date>", "Due date in YYYY-MM-DD format").option("--parent <key>", "Parent issue key (for subtasks)").option("--custom-fields <json>", `Additional custom fields as JSON (e.g., '{"customfield_10100": "EPIC-1"}')`);
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 <username>", "Assignee username").option("--reporter <username>", "Reporter username").option("--priority <name>", "Priority name (e.g., High, Medium, Low)").option("--labels <labels>", "Comma-separated labels").option("--components <names>", "Comma-separated component names").option("--fix-versions <versions>", "Comma-separated fix version names").option("--due-date <date>", "Due date in YYYY-MM-DD format").option("--parent <key>", "Parent issue key (for subtasks)").option("--custom-fields <json>", `Additional custom fields as JSON (e.g., '{"customfield_10100": "EPIC-1"}')`);
1319
+ textOrFileOption(cmd, "description", { description: "Issue description in wiki markup" });
1258
1320
  examples(cmd, [
1259
1321
  '--project PROJ --type Task --summary "Fix login bug"',
1260
1322
  '--project PROJ --type Story --summary "New feature" --assignee jsmith --priority High',
@@ -1262,12 +1324,13 @@ function create3(parent) {
1262
1324
  ]);
1263
1325
  cmd.action(
1264
1326
  async (opts) => {
1327
+ const description = resolveTextOrFile(opts, "description", { required: false });
1265
1328
  const client = getClient();
1266
1329
  const result = await client.issues.create({
1267
1330
  projectKeyOrId: opts.project,
1268
1331
  issueTypeName: opts.type,
1269
1332
  summary: opts.summary,
1270
- description: opts.description,
1333
+ description,
1271
1334
  assignee: opts.assignee,
1272
1335
  reporter: opts.reporter,
1273
1336
  priority: opts.priority,
@@ -1454,18 +1517,20 @@ function linkTypes(parent) {
1454
1517
 
1455
1518
  // src/commands/issue/link.ts
1456
1519
  function link(parent) {
1457
- 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")').option("--comment <text>", "Optional comment");
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")');
1521
+ commentOption(cmd, { description: "Optional comment" });
1458
1522
  examples(cmd, [
1459
1523
  "--type Relates --from AI-154 --to AI-149",
1460
1524
  ["--type Blocks --from PROJ-456 --to PROJ-123", "PROJ-456 blocks PROJ-123"]
1461
1525
  ]);
1462
1526
  cmd.action(async (opts) => {
1527
+ const comment = resolveTextOrFile(opts, "comment", { required: false });
1463
1528
  const client = getClient();
1464
1529
  await client.links.create({
1465
1530
  typeName: opts.type,
1466
1531
  inwardIssueKey: opts.from,
1467
1532
  outwardIssueKey: opts.to,
1468
- comment: opts.comment
1533
+ comment
1469
1534
  });
1470
1535
  output({
1471
1536
  created: true,
@@ -1499,13 +1564,15 @@ function search2(parent) {
1499
1564
 
1500
1565
  // src/commands/issue/transition.ts
1501
1566
  function transition(parent) {
1502
- const cmd = parent.command("transition <key>").description("Transition issue to a new status").requiredOption("--to <idOrName>", "Transition ID, or status name (case-insensitive)").option("--comment <text>", "Comment to add during transition");
1567
+ const cmd = parent.command("transition <key>").description("Transition issue to a new status").requiredOption("--to <idOrName>", "Transition ID, or status name (case-insensitive)");
1568
+ commentOption(cmd, { description: "Comment to add during transition" });
1503
1569
  examples(cmd, [
1504
1570
  "PROJ-123 --to 31",
1505
1571
  'PROJ-123 --to "In Review"',
1506
1572
  'PROJ-123 --to Done --comment "Verified in staging"'
1507
1573
  ]);
1508
1574
  cmd.action(async (key, opts) => {
1575
+ const comment = resolveTextOrFile(opts, "comment", { required: false });
1509
1576
  const client = getClient();
1510
1577
  let transitionId;
1511
1578
  if (/^\d+$/.test(opts.to)) {
@@ -1528,7 +1595,7 @@ function transition(parent) {
1528
1595
  }
1529
1596
  transitionId = matches[0].id;
1530
1597
  }
1531
- await client.issues.transition({ issueKeyOrId: key, transitionId, comment: opts.comment });
1598
+ await client.issues.transition({ issueKeyOrId: key, transitionId, comment });
1532
1599
  output({ transitioned: true, issue: transformIssueRef(key) });
1533
1600
  });
1534
1601
  }
@@ -1559,20 +1626,20 @@ function unlink2(parent) {
1559
1626
  }
1560
1627
 
1561
1628
  // src/utils/multi-value.ts
1562
- import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
1629
+ import { InvalidArgumentError as InvalidArgumentError3 } from "commander";
1563
1630
  function parseMultiValue(flagName, raw) {
1564
1631
  const items = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
1565
1632
  if (items.length === 0) {
1566
- throw new InvalidArgumentError2(`${flagName} cannot be empty`);
1633
+ throw new InvalidArgumentError3(`${flagName} cannot be empty`);
1567
1634
  }
1568
1635
  const lonePrefix = items.find((s) => s === "+" || s === "-");
1569
1636
  if (lonePrefix !== void 0) {
1570
- throw new InvalidArgumentError2(`${flagName} has an empty value after '${lonePrefix}' prefix`);
1637
+ throw new InvalidArgumentError3(`${flagName} has an empty value after '${lonePrefix}' prefix`);
1571
1638
  }
1572
1639
  const prefixed = items.filter((s) => s.startsWith("+") || s.startsWith("-"));
1573
1640
  const bare = items.filter((s) => !s.startsWith("+") && !s.startsWith("-"));
1574
1641
  if (prefixed.length > 0 && bare.length > 0) {
1575
- throw new InvalidArgumentError2(
1642
+ throw new InvalidArgumentError3(
1576
1643
  `${flagName} mixes set and mutate syntax. Either all values have +/- prefix, or none do.`
1577
1644
  );
1578
1645
  }
@@ -1594,7 +1661,8 @@ function buildSetValue(parsed, wrap) {
1594
1661
  return parsed.values.map(wrap);
1595
1662
  }
1596
1663
  function update3(parent) {
1597
- const cmd = parent.command("update <key>").description("Update issue fields").option("--fields <json>", "JSON string of fields to update (advanced; merges with shortcuts, wins on conflict)").option("--no-notify-users", "Suppress notification emails (default: notify)").option("--attachments <paths>", "Comma-separated local file paths to attach").option("--summary <text>", "Set the issue summary").option("--description <text>", "Set the issue description (wiki markup)").option("--priority <name>", "Set the priority by name (e.g. High)").option("--assignee <user>", 'Set the assignee. Username, "me", or "none" to unassign.').option("--labels <list>", 'Set labels ("a,b,c") or mutate ("+add,-remove")').option("--components <list>", 'Set components ("a,b") or mutate ("+add,-remove")').option("--fix-versions <list>", 'Set fix versions ("1.0,2.0") or mutate ("+1.0,-0.9")');
1664
+ const cmd = parent.command("update <key>").description("Update issue fields").option("--fields <json>", "JSON string of fields to update (advanced; merges with shortcuts, wins on conflict)").option("--no-notify-users", "Suppress notification emails (default: notify)").option("--attachments <paths>", "Comma-separated local file paths to attach").option("--summary <text>", "Set the issue summary").option("--priority <name>", "Set the priority by name (e.g. High)").option("--assignee <user>", 'Set the assignee. Username, "me", or "none" to unassign.').option("--labels <list>", 'Set labels ("a,b,c") or mutate ("+add,-remove")').option("--components <list>", 'Set components ("a,b") or mutate ("+add,-remove")').option("--fix-versions <list>", 'Set fix versions ("1.0,2.0") or mutate ("+1.0,-0.9")');
1665
+ textOrFileOption(cmd, "description", { description: "Set the issue description (wiki markup)" });
1598
1666
  examples(cmd, [
1599
1667
  'PROJ-123 --summary "New title"',
1600
1668
  "PROJ-123 --priority High --assignee me",
@@ -1604,7 +1672,8 @@ function update3(parent) {
1604
1672
  "PROJ-123 --attachments /path/to/file.pdf,/path/to/image.png"
1605
1673
  ]);
1606
1674
  cmd.action(async (key, opts) => {
1607
- const hasShortcut = opts.summary !== void 0 || opts.description !== void 0 || opts.priority !== void 0 || opts.assignee !== void 0 || opts.labels !== void 0 || opts.components !== void 0 || opts.fixVersions !== void 0;
1675
+ const description = resolveTextOrFile(opts, "description", { required: false });
1676
+ const hasShortcut = opts.summary !== void 0 || description !== void 0 || opts.priority !== void 0 || opts.assignee !== void 0 || opts.labels !== void 0 || opts.components !== void 0 || opts.fixVersions !== void 0;
1608
1677
  if (!opts.fields && !opts.attachments && !hasShortcut) {
1609
1678
  throw new Error(
1610
1679
  "Provide at least one of --fields, --attachments, or a shortcut flag (--summary, --priority, --labels, ...)"
@@ -1613,7 +1682,7 @@ function update3(parent) {
1613
1682
  const fields = {};
1614
1683
  const updateOps = {};
1615
1684
  if (opts.summary !== void 0) fields.summary = opts.summary;
1616
- if (opts.description !== void 0) fields.description = opts.description;
1685
+ if (description !== void 0) fields.description = description;
1617
1686
  if (opts.priority !== void 0) fields.priority = { name: opts.priority };
1618
1687
  if (opts.assignee !== void 0) {
1619
1688
  const resolved = await resolveUserToken(opts.assignee);
@@ -1674,18 +1743,20 @@ function update3(parent) {
1674
1743
 
1675
1744
  // src/commands/issue/worklog/create.ts
1676
1745
  function create4(parent) {
1677
- const cmd = parent.command("create <key>").description("Log time spent on an issue").requiredOption("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')").option("--comment <text>", "Worklog comment").option("--started <datetime>", "Start time in ISO 8601 format");
1746
+ const cmd = parent.command("create <key>").description("Log time spent on an issue").requiredOption("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')").option("--started <datetime>", "Start time in ISO 8601 format");
1747
+ commentOption(cmd, { description: "Worklog comment" });
1678
1748
  examples(cmd, [
1679
1749
  "PROJ-123 --time 2h",
1680
1750
  'PROJ-123 --time "1d 4h" --comment "Backend implementation"',
1681
1751
  'PROJ-123 --time 3h --started "2026-03-19T09:00:00.000+0000"'
1682
1752
  ]);
1683
1753
  cmd.action(async (key, opts) => {
1754
+ const comment = resolveTextOrFile(opts, "comment", { required: false });
1684
1755
  const client = getClient();
1685
1756
  const result = await client.issues.addWorklog({
1686
1757
  issueKeyOrId: key,
1687
1758
  timeSpent: opts.time,
1688
- comment: opts.comment,
1759
+ comment,
1689
1760
  started: opts.started
1690
1761
  });
1691
1762
  output(transformWorklog(result));
@@ -1693,12 +1764,12 @@ function create4(parent) {
1693
1764
  }
1694
1765
 
1695
1766
  // src/commands/issue/worklog/delete.ts
1696
- import { Option as Option4 } from "commander";
1767
+ import { Option as Option5 } from "commander";
1697
1768
  var ADJUST_ESTIMATE = ["new", "leave", "manual", "auto"];
1698
1769
  function deleteWorklog(parent) {
1699
1770
  const cmd = parent.command("delete <key>").description("Delete a worklog entry");
1700
1771
  subEntityOption(cmd, "worklog", { mandatory: true });
1701
- cmd.addOption(new Option4("--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(
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(
1702
1773
  "--increase-by <amount>",
1703
1774
  'Amount to increase the estimate by; required when --adjust-estimate is "manual"'
1704
1775
  );
@@ -1738,12 +1809,13 @@ function list4(parent) {
1738
1809
  }
1739
1810
 
1740
1811
  // src/commands/issue/worklog/update.ts
1741
- import { Option as Option5 } from "commander";
1812
+ import { Option as Option6 } from "commander";
1742
1813
  var ADJUST_ESTIMATE2 = ["new", "leave", "auto"];
1743
1814
  function update4(parent) {
1744
1815
  const cmd = parent.command("update <key>").description("Update an existing worklog entry");
1745
1816
  subEntityOption(cmd, "worklog", { mandatory: true });
1746
- cmd.option("--time <timeSpent>", "Time spent (e.g., '2h', '30m', '1d 4h')").option("--comment <text>", "Worklog comment").option("--started <datetime>", "Start time in ISO 8601 format").addOption(new Option5("--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"');
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"');
1818
+ commentOption(cmd, { description: "Worklog comment" });
1747
1819
  examples(cmd, [
1748
1820
  'PROJ-123 --worklog-id 12345 --time "1h 30m"',
1749
1821
  'PROJ-123 --worklog-id 12345 --comment "Revised note"',
@@ -1751,12 +1823,13 @@ function update4(parent) {
1751
1823
  ]);
1752
1824
  cmd.action(
1753
1825
  async (key, opts) => {
1826
+ const comment = resolveTextOrFile(opts, "comment", { required: false });
1754
1827
  const client = getClient();
1755
1828
  const result = await client.issues.updateWorklog({
1756
1829
  issueKeyOrId: key,
1757
1830
  worklogId: String(opts.worklogId),
1758
1831
  timeSpent: opts.time,
1759
- comment: opts.comment,
1832
+ comment,
1760
1833
  started: opts.started,
1761
1834
  adjustEstimate: opts.adjustEstimate,
1762
1835
  newEstimate: opts.newEstimate
@@ -1900,10 +1973,10 @@ function issues2(parent) {
1900
1973
  }
1901
1974
 
1902
1975
  // src/commands/sprint/list.ts
1903
- import { Option as Option6 } from "commander";
1976
+ import { Option as Option7 } from "commander";
1904
1977
  var SPRINT_STATES = ["future", "active", "closed"];
1905
1978
  function list6(parent) {
1906
- const cmd = parent.command("list").description("List sprints for a board").requiredOption("--board <id>", "Board ID", positiveInt).addOption(new Option6("--state <state>", "Filter by sprint state").choices(SPRINT_STATES));
1979
+ const cmd = parent.command("list").description("List sprints for a board").requiredOption("--board <id>", "Board ID", positiveInt).addOption(new Option7("--state <state>", "Filter by sprint state").choices(SPRINT_STATES));
1907
1980
  examples(cmd, ["--board 42", "--board 42 --state active"]);
1908
1981
  cmd.action(async (opts) => {
1909
1982
  const client = getClient();
@@ -1916,10 +1989,10 @@ function list6(parent) {
1916
1989
  }
1917
1990
 
1918
1991
  // src/commands/sprint/update.ts
1919
- import { Argument as Argument4, Option as Option7 } from "commander";
1992
+ import { Argument as Argument4, Option as Option8 } from "commander";
1920
1993
  var SPRINT_STATES2 = ["future", "active", "closed"];
1921
1994
  function update5(parent) {
1922
- 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 Option7("--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");
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");
1923
1996
  examples(cmd, [
1924
1997
  '100 --name "Sprint 10 - Extended"',
1925
1998
  "100 --state active",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jiradc-cli",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "publish": true,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,8 +23,8 @@
23
23
  "typescript": "^5.7.2",
24
24
  "vitest": "^4.0.16",
25
25
  "cli-utils": "1.0.0",
26
- "config-typescript": "0.0.0",
27
- "config-eslint": "0.0.0"
26
+ "config-eslint": "0.0.0",
27
+ "config-typescript": "0.0.0"
28
28
  },
29
29
  "engines": {
30
30
  "node": ">=22.0.0"