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.
- package/README.md +13 -0
- package/dist/index.js +73 -7
- 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
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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",
|