azdo-cli 0.2.0-008-pull-request-handling.101 → 0.2.0-008-pull-request-handling.102

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 (3) hide show
  1. package/README.md +13 -0
  2. package/dist/index.js +73 -7
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -17,6 +17,7 @@ Azure DevOps CLI focused on work item read/write workflows.
17
17
  - Set rich-text fields as markdown from inline text, file, or stdin (`set-md-field`)
18
18
  - Check branch pull request status, open PRs to `develop`, and review active comments (`pr`)
19
19
  - Persist org/project/default fields in local config (`config`)
20
+ - List all fields of a work item (`list-fields`)
20
21
  - Store PAT in OS credential store (or use `AZDO_PAT`)
21
22
 
22
23
  ## Installation
@@ -65,6 +66,7 @@ azdo upsert --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
65
66
  | `azdo upsert [id]` | Create or update a Task from markdown | `--content`, `--file`, `--json`, `--org`, `--project` |
66
67
  | `azdo get-md-field <id> <field>` | Get field as markdown | `--org`, `--project` |
67
68
  | `azdo set-md-field <id> <field> [content]` | Set markdown field | `--file`, `--json`, `--org`, `--project` |
69
+ | `azdo list-fields <id>` | List all fields of a work item | `--json`, `--org`, `--project` |
68
70
  | `azdo pr <subcommand>` | Manage pull requests for the current branch | `status`, `open`, `comments`, `--json`, `--org`, `--project` |
69
71
  | `azdo config <subcommand>` | Manage saved settings | `set`, `get`, `list`, `unset`, `wizard`, `--json` |
70
72
  | `azdo clear-pat` | Remove stored PAT | none |
@@ -102,6 +104,16 @@ azdo assign 12345 --unassign
102
104
  azdo set-field 12345 System.Title "Updated title"
103
105
  ```
104
106
 
107
+ ### List Fields
108
+
109
+ ```bash
110
+ # List all fields of a work item
111
+ azdo list-fields 12345
112
+
113
+ # JSON output
114
+ azdo list-fields 12345 --json
115
+ ```
116
+
105
117
  ### Markdown Display
106
118
 
107
119
  The `get-item` command can convert HTML rich-text fields to readable markdown. Resolution order:
@@ -271,6 +283,7 @@ azdo clear-pat
271
283
  ## JSON Output
272
284
 
273
285
  These commands support `--json` for machine-readable output:
286
+ - `list-fields`
274
287
  - `set-state`
275
288
  - `assign`
276
289
  - `set-field`
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command11 } from "commander";
4
+ import { Command as Command12 } from "commander";
5
5
 
6
6
  // src/version.ts
7
7
  import { readFileSync } from "fs";
@@ -92,6 +92,25 @@ async function readWriteResponse(response, errorCode) {
92
92
  fields: data.fields
93
93
  };
94
94
  }
95
+ async function getWorkItemFields(context, id, pat) {
96
+ const url = new URL(
97
+ `https://dev.azure.com/${encodeURIComponent(context.org)}/${encodeURIComponent(context.project)}/_apis/wit/workitems/${id}`
98
+ );
99
+ url.searchParams.set("api-version", "7.1");
100
+ url.searchParams.set("$expand", "all");
101
+ const response = await fetchWithErrors(url.toString(), { headers: authHeaders(pat) });
102
+ if (response.status === 400) {
103
+ const serverMessage = await readResponseMessage(response);
104
+ if (serverMessage) {
105
+ throw new Error(`BAD_REQUEST: ${serverMessage}`);
106
+ }
107
+ }
108
+ if (!response.ok) {
109
+ throw new Error(`HTTP_${response.status}`);
110
+ }
111
+ const data = await response.json();
112
+ return data.fields;
113
+ }
95
114
  async function getWorkItem(context, id, pat, extraFields) {
96
115
  const url = new URL(
97
116
  `https://dev.azure.com/${encodeURIComponent(context.org)}/${encodeURIComponent(context.project)}/_apis/wit/workitems/${id}`
@@ -1451,8 +1470,54 @@ function createUpsertCommand() {
1451
1470
  return command;
1452
1471
  }
1453
1472
 
1454
- // src/commands/pr.ts
1473
+ // src/commands/list-fields.ts
1455
1474
  import { Command as Command10 } from "commander";
1475
+ function stringifyValue(value) {
1476
+ if (value === null || value === void 0) return "";
1477
+ if (typeof value === "object") return JSON.stringify(value);
1478
+ return String(value);
1479
+ }
1480
+ function formatFieldList(fields) {
1481
+ const entries = Object.entries(fields).sort(([a], [b]) => a.localeCompare(b));
1482
+ const maxKeyLen = Math.min(
1483
+ Math.max(...entries.map(([k]) => k.length)),
1484
+ 50
1485
+ );
1486
+ return entries.map(([key, value]) => {
1487
+ const display = stringifyValue(value);
1488
+ const truncated = display.length > 120 ? display.slice(0, 117) + "..." : display;
1489
+ return `${key.padEnd(maxKeyLen + 2)}${truncated}`;
1490
+ }).join("\n");
1491
+ }
1492
+ function createListFieldsCommand() {
1493
+ const command = new Command10("list-fields");
1494
+ command.description("List all fields of an Azure DevOps work item").argument("<id>", "work item ID").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--json", "output result as JSON").action(
1495
+ async (idStr, options) => {
1496
+ const id = parseWorkItemId(idStr);
1497
+ validateOrgProjectPair(options);
1498
+ let context;
1499
+ try {
1500
+ context = resolveContext(options);
1501
+ const credential = await resolvePat();
1502
+ const fields = await getWorkItemFields(context, id, credential.pat);
1503
+ if (options.json) {
1504
+ process.stdout.write(JSON.stringify({ id, fields }, null, 2) + "\n");
1505
+ } else {
1506
+ process.stdout.write(`Work Item ${id} \u2014 ${Object.keys(fields).length} fields
1507
+
1508
+ `);
1509
+ process.stdout.write(formatFieldList(fields) + "\n");
1510
+ }
1511
+ } catch (err) {
1512
+ handleCommandError(err, id, context, "read");
1513
+ }
1514
+ }
1515
+ );
1516
+ return command;
1517
+ }
1518
+
1519
+ // src/commands/pr.ts
1520
+ import { Command as Command11 } from "commander";
1456
1521
 
1457
1522
  // src/services/pr-client.ts
1458
1523
  function buildPullRequestsUrl(context, repo, sourceBranch, opts) {
@@ -1633,7 +1698,7 @@ async function resolvePrCommandContext(options) {
1633
1698
  };
1634
1699
  }
1635
1700
  function createPrStatusCommand() {
1636
- const command = new Command10("status");
1701
+ const command = new Command11("status");
1637
1702
  command.description("Check pull requests for the current branch").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--json", "output JSON").action(async (options) => {
1638
1703
  validateOrgProjectPair(options);
1639
1704
  let context;
@@ -1662,7 +1727,7 @@ function createPrStatusCommand() {
1662
1727
  return command;
1663
1728
  }
1664
1729
  function createPrOpenCommand() {
1665
- const command = new Command10("open");
1730
+ const command = new Command11("open");
1666
1731
  command.description("Open a pull request from the current branch to develop").option("--title <title>", "pull request title").option("--description <description>", "pull request description").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--json", "output JSON").action(async (options) => {
1667
1732
  validateOrgProjectPair(options);
1668
1733
  const title = options.title?.trim();
@@ -1715,7 +1780,7 @@ ${result.pullRequest.url}
1715
1780
  return command;
1716
1781
  }
1717
1782
  function createPrCommentsCommand() {
1718
- const command = new Command10("comments");
1783
+ const command = new Command11("comments");
1719
1784
  command.description("List active pull request comments for the current branch").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").option("--json", "output JSON").action(async (options) => {
1720
1785
  validateOrgProjectPair(options);
1721
1786
  let context;
@@ -1754,7 +1819,7 @@ function createPrCommentsCommand() {
1754
1819
  return command;
1755
1820
  }
1756
1821
  function createPrCommand() {
1757
- const command = new Command10("pr");
1822
+ const command = new Command11("pr");
1758
1823
  command.description("Manage Azure DevOps pull requests");
1759
1824
  command.addCommand(createPrStatusCommand());
1760
1825
  command.addCommand(createPrOpenCommand());
@@ -1763,7 +1828,7 @@ function createPrCommand() {
1763
1828
  }
1764
1829
 
1765
1830
  // src/index.ts
1766
- var program = new Command11();
1831
+ var program = new Command12();
1767
1832
  program.name("azdo").description("Azure DevOps CLI tool").version(version, "-v, --version");
1768
1833
  program.addCommand(createGetItemCommand());
1769
1834
  program.addCommand(createClearPatCommand());
@@ -1774,6 +1839,7 @@ program.addCommand(createSetFieldCommand());
1774
1839
  program.addCommand(createGetMdFieldCommand());
1775
1840
  program.addCommand(createSetMdFieldCommand());
1776
1841
  program.addCommand(createUpsertCommand());
1842
+ program.addCommand(createListFieldsCommand());
1777
1843
  program.addCommand(createPrCommand());
1778
1844
  program.showHelpAfterError();
1779
1845
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.2.0-008-pull-request-handling.101",
3
+ "version": "0.2.0-008-pull-request-handling.102",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,8 @@
14
14
  "lint": "eslint src/",
15
15
  "typecheck": "tsc --noEmit",
16
16
  "format": "prettier --check src/",
17
- "test": "npm run build && vitest run"
17
+ "test": "npm run build && vitest run tests/unit",
18
+ "test:integration": "npm run build && vitest run tests/integration"
18
19
  },
19
20
  "repository": {
20
21
  "type": "git",