diff --git a/skills/azure-devops-cli/SKILL.md b/skills/azure-devops-cli/SKILL.md index c8e420fb5..b2a5298cd 100644 --- a/skills/azure-devops-cli/SKILL.md +++ b/skills/azure-devops-cli/SKILL.md @@ -79,6 +79,61 @@ az artifacts # Azure Artifacts └── universal # Universal Packages ``` +## Posting long comments on Windows + +On Windows the `az` command resolves to `az.cmd`, a batch wrapper invoked by `cmd.exe`. The whole command line is capped at ~8191 characters, so a long `--discussion`, `--description`, or `--content` value can be silently truncated or fail. Detect the shell before composing a long argument and route accordingly. Skipping this is the most common reason the agent burns 3-5 turns falling back to raw token retrieval and REST calls. + +### Detect the shell first + +| Environment | Signal | Action | +|---|---|---| +| PowerShell on Windows | `$IsWindows -eq $true` and `$PSVersionTable.PSVersion` is set | Use `azps.ps1` (see below) | +| PowerShell on macOS / Linux | `$IsWindows -eq $false` | Plain `az` is fine, no cmd.exe wrapper | +| bash / zsh / sh | `$BASH_VERSION` or `$ZSH_VERSION` set, or `uname` works | Plain `az` is fine, no cmd.exe wrapper | +| Windows `cmd.exe` | `%ComSpec%` ends in `cmd.exe`, no `$PSVersionTable` | Use `azps.ps1` if PowerShell is installed, otherwise see `az devops invoke` fallback below | + +### Option 1: `azps.ps1` (PowerShell on Windows) + +`azps.ps1` ships with the Azure CLI installer and invokes the Python entry point directly. No `cmd.exe` length cap. + +```powershell +# Read the long body into a variable and pass it through. No quoting headaches. +$body = Get-Content -Raw .\comment.md +azps.ps1 boards work-item update --id 1234 --discussion $body +``` + +### Option 2: dedicated `--file-path` flag where Azure CLI offers one + +Some commands have a native file flag and you should prefer it over any inline body: + +- `az devops wiki page create` and `az devops wiki page update` take `--file-path` (with optional `--encoding`). +- Use it on any shell, including Windows. + +```bash +az devops wiki page create --path 'My page' --wiki myproject --file-path ./page.md --encoding utf-8 +``` + +### Option 3: `az devops invoke` fallback + +When no `--file-path` exists (work-item `--discussion`, PR `--description`) and you're not in PowerShell, post the body via the underlying REST API. `az devops invoke` runs inside the Python entry point, so it isn't subject to the `cmd.exe` cap either, and it takes the request body from a file with `--in-file`: + +```bash +# Post a long discussion comment to work item 1234. +# REST: POST /{project}/_apis/wit/workItems/{id}/comments?api-version=7.0-preview.3 +az devops invoke \ + --area wit --resource comments \ + --route-parameters project={project} workItemId=1234 \ + --api-version 7.0-preview.3 \ + --http-method POST \ + --in-file ./comment.json +``` + +Where `comment.json` is `{ "text": "" }`. This is the universal escape hatch when neither `azps.ps1` nor `--file-path` is available. `az devops invoke` itself accepts `--in-file` natively. + +### Don't rely on `@` for plain string args + +The Azure CLI `@` convention is documented for JSON parameters (see [the official quoting guide](https://learn.microsoft.com/en-us/cli/azure/use-azure-cli-successfully-quoting)). It is not guaranteed to expand plain string args like `--discussion` or `--description`, so don't reach for it as a substitute for the three options above. + ## Reference Files Read the relevant reference file based on the user's task. Each file contains complete command syntax and examples for its domain. diff --git a/skills/azure-devops-cli/references/boards-and-iterations.md b/skills/azure-devops-cli/references/boards-and-iterations.md index b1c99a71a..7de6486e8 100644 --- a/skills/azure-devops-cli/references/boards-and-iterations.md +++ b/skills/azure-devops-cli/references/boards-and-iterations.md @@ -56,6 +56,10 @@ az boards work-item create \ --type Bug \ --discussion "Initial investigation completed" +# For a long --discussion body on Windows, see "Posting long comments on Windows" +# in SKILL.md. Short version: use azps.ps1 in PowerShell, or fall back to +# 'az devops invoke' with --in-file when no native --file-path flag is available. + # Open in browser after creation az boards work-item create --title "Bug" --type Bug --open ``` @@ -85,6 +89,14 @@ az boards work-item update \ --id {work-item-id} \ --discussion "Work in progress" +# Long comment on Windows: read the body into a PowerShell variable and call +# azps.ps1 instead of az.cmd, or fall back to 'az devops invoke' with --in-file. +# Full guidance in SKILL.md under "Posting long comments on Windows". +# +# PowerShell example: +# $body = Get-Content -Raw .\comment.md +# azps.ps1 boards work-item update --id 1234 --discussion $body + # Update with custom fields az boards work-item update \ --id {work-item-id} \