azdo-cli 0.2.0-develop.137 → 0.2.0-develop.141

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 +18 -7
  2. package/dist/index.js +27 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@ Azure DevOps CLI focused on work item read/write workflows.
12
12
  - Update work item state (`set-state`)
13
13
  - Assign and unassign work items (`assign`)
14
14
  - Set any work item field by reference name (`set-field`)
15
- - Create or update Tasks from markdown documents (`upsert`)
15
+ - Create or update work items from markdown documents (`upsert`)
16
16
  - Read rich-text fields as markdown (`get-md-field`)
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`)
@@ -65,8 +65,8 @@ azdo get-item 12345
65
65
  # 3) Update state
66
66
  azdo set-state 12345 "Active"
67
67
 
68
- # 4) Create or update a Task from markdown
69
- azdo upsert --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
68
+ # 4) Create or update a work item from markdown
69
+ azdo upsert --type "User Story" --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
70
70
  ```
71
71
 
72
72
  ## Command Cheat Sheet
@@ -77,7 +77,7 @@ azdo upsert --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
77
77
  | `azdo set-state <id> <state>` | Change work item state | `--json`, `--org`, `--project` |
78
78
  | `azdo assign <id> [name]` | Assign or unassign owner | `--unassign`, `--json`, `--org`, `--project` |
79
79
  | `azdo set-field <id> <field> <value>` | Update any field | `--json`, `--org`, `--project` |
80
- | `azdo upsert [id]` | Create or update a Task from markdown | `--content`, `--file`, `--json`, `--org`, `--project` |
80
+ | `azdo upsert [id]` | Create or update a work item from markdown | `--content`, `--file`, `--type`, `--json`, `--org`, `--project` |
81
81
  | `azdo get-md-field <id> <field>` | Get field as markdown | `--org`, `--project` |
82
82
  | `azdo set-md-field <id> <field> [content]` | Set markdown field | `--file`, `--json`, `--org`, `--project` |
83
83
  | `azdo list-fields <id>` | List all fields of a work item | `--json`, `--org`, `--project` |
@@ -189,11 +189,14 @@ azdo pr comments
189
189
 
190
190
  ## azdo upsert
191
191
 
192
- `azdo upsert` accepts a single markdown task document and either creates a new Azure DevOps Task or updates an existing one. Omit `[id]` to create; pass `[id]` to update that work item in place.
192
+ `azdo upsert` accepts a single markdown work-item document and either creates a new Azure DevOps work item or updates an existing one. Omit `[id]` to create; pass `[id]` to update that work item in place. Create mode defaults to `Task`, and `--type <work item type>` lets you create `Bug`, `User Story`, `Feature`, `Epic`, and other Azure DevOps work item types.
193
193
 
194
194
  ```bash
195
- # Create from inline content
196
- azdo upsert --content $'---\nTitle: Improve markdown import UX\nAssigned To: user@example.com\nState: New\n---'
195
+ # Create a Bug from inline content
196
+ azdo upsert --type Bug --content $'---\nTitle: Improve markdown import UX\nAssigned To: user@example.com\nState: New\n---'
197
+
198
+ # Preserve the default Task create behavior
199
+ azdo upsert --content $'---\nTitle: Follow-up task\nAssigned To: user@example.com\nState: New\n---'
197
200
 
198
201
  # Update from a file
199
202
  azdo upsert 12345 --file ./task-import.md
@@ -206,9 +209,16 @@ The command requires exactly one source flag:
206
209
 
207
210
  - `azdo upsert [id] --content <markdown>`
208
211
  - `azdo upsert [id] --file <path>`
212
+ - `azdo upsert --type <work-item-type> --content <markdown>`
209
213
 
210
214
  If `--file` succeeds, the source file is deleted after the Azure DevOps write completes. If parsing, validation, or the API call fails, the file is preserved. If deletion fails after a successful write, the command still succeeds and prints a warning.
211
215
 
216
+ Type rules:
217
+
218
+ - `--type` is optional for create and defaults to `Task`.
219
+ - `--type` is only valid when creating a new work item.
220
+ - Human-readable and JSON success output include the resulting work item type.
221
+
212
222
  ### Task Document Format
213
223
 
214
224
  The document starts with YAML front matter for scalar fields, followed by optional `##` heading sections for markdown rich-text fields.
@@ -257,6 +267,7 @@ Clear semantics:
257
267
  {
258
268
  "action": "created",
259
269
  "id": 12345,
270
+ "workItemType": "User Story",
260
271
  "fields": {
261
272
  "System.Title": "Improve markdown import UX",
262
273
  "System.Description": "Implement a single-command task import flow."
package/dist/index.js CHANGED
@@ -1391,7 +1391,7 @@ function buildAppliedFields(fields) {
1391
1391
  function ensureTitleForCreate(fields) {
1392
1392
  const titleField = fields.find((field) => field.refName === "System.Title");
1393
1393
  if (!titleField || titleField.op === "clear" || titleField.value === null || titleField.value.trim() === "") {
1394
- fail2("Title is required when creating a task.");
1394
+ fail2("Title is required when creating a work item.");
1395
1395
  }
1396
1396
  }
1397
1397
  function writeSuccess(result, options) {
@@ -1403,7 +1403,7 @@ function writeSuccess(result, options) {
1403
1403
  const verb = result.action === "created" ? "Created" : "Updated";
1404
1404
  const fields = Object.keys(result.fields).join(", ");
1405
1405
  const suffix = fields ? ` (${fields})` : "";
1406
- process.stdout.write(`${verb} task #${result.id}${suffix}
1406
+ process.stdout.write(`${verb} ${result.workItemType} #${result.id}${suffix}
1407
1407
  `);
1408
1408
  }
1409
1409
  function cleanupSourceFile(sourceFile) {
@@ -1417,11 +1417,26 @@ function cleanupSourceFile(sourceFile) {
1417
1417
  `);
1418
1418
  }
1419
1419
  }
1420
- function buildUpsertResult(action, writeResult, fields) {
1420
+ function resolveCreateType(id, options) {
1421
+ if (options.type === void 0) {
1422
+ return "Task";
1423
+ }
1424
+ if (id !== void 0) {
1425
+ fail2("--type can only be used when creating a work item.");
1426
+ }
1427
+ const trimmedType = options.type.trim();
1428
+ if (trimmedType === "") {
1429
+ fail2("--type must be a non-empty work item type.");
1430
+ }
1431
+ return trimmedType;
1432
+ }
1433
+ function buildUpsertResult(action, writeResult, fields, fallbackWorkItemType) {
1421
1434
  const appliedFields = buildAppliedFields(fields);
1435
+ const workItemType = writeResult.fields["System.WorkItemType"];
1422
1436
  return {
1423
1437
  action,
1424
1438
  id: writeResult.id,
1439
+ workItemType: typeof workItemType === "string" && workItemType.trim() !== "" ? workItemType : fallbackWorkItemType,
1425
1440
  fields: appliedFields
1426
1441
  };
1427
1442
  }
@@ -1456,10 +1471,11 @@ function handleUpsertError(err, id, context) {
1456
1471
  }
1457
1472
  function createUpsertCommand() {
1458
1473
  const command = new Command9("upsert");
1459
- command.description("Create or update a Task from a markdown document").argument("[id]", "work item ID to update; omit to create a new Task").option("--content <markdown>", "task document content").option("--file <path>", "read task document from file").option("--json", "output result as JSON").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").action(async (idStr, options) => {
1474
+ command.description("Create or update a work item from a markdown document").argument("[id]", "work item ID to update; omit to create a new work item").option("--content <markdown>", "task document content").option("--file <path>", "read task document from file").option("--type <workItemType>", "create mode work item type (defaults to Task)").option("--json", "output result as JSON").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").action(async (idStr, options) => {
1460
1475
  validateOrgProjectPair(options);
1461
1476
  const id = idStr === void 0 ? void 0 : parseWorkItemId(idStr);
1462
1477
  const { content, sourceFile } = loadSourceContent(options);
1478
+ const createType = resolveCreateType(id, options);
1463
1479
  let context;
1464
1480
  try {
1465
1481
  context = resolveContext(options);
@@ -1472,14 +1488,19 @@ function createUpsertCommand() {
1472
1488
  const credential = await resolvePat();
1473
1489
  let writeResult;
1474
1490
  if (action === "created") {
1475
- writeResult = await createWorkItem(context, "Task", credential.pat, operations);
1491
+ writeResult = await createWorkItem(context, createType, credential.pat, operations);
1476
1492
  } else {
1477
1493
  if (id === void 0) {
1478
1494
  fail2("Work item ID is required for updates.");
1479
1495
  }
1480
1496
  writeResult = await applyWorkItemPatch(context, id, credential.pat, operations);
1481
1497
  }
1482
- const result = buildUpsertResult(action, writeResult, document.fields);
1498
+ const result = buildUpsertResult(
1499
+ action,
1500
+ writeResult,
1501
+ document.fields,
1502
+ action === "created" ? createType : "Work item"
1503
+ );
1483
1504
  writeSuccess(result, options);
1484
1505
  cleanupSourceFile(sourceFile);
1485
1506
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azdo-cli",
3
- "version": "0.2.0-develop.137",
3
+ "version": "0.2.0-develop.141",
4
4
  "description": "Azure DevOps CLI tool",
5
5
  "type": "module",
6
6
  "bin": {