Azure DevOps work item fetcher for agentic coding tools
Project description
azwi
azwi fetches Azure DevOps work item context for agentic coding tools such as Codex CLI and Claude Code.
The tool is designed for deterministic, machine-friendly Markdown or JSON output with clean stdout on success and stderr-only logging.
Install and run
Local checkout:
uv run ./azwi.py --help
uv run ./azwi.py 2195 --org my-org
Packaged command:
uvx azwi --help
azwi 2195 --org my-org
Authentication
azwi reads an Azure DevOps PAT from:
AZWI_PAT
Required PAT scopes:
- Work Items: Read
- Code: Read
The PAT is not stored in ~/.azwi/config.toml.
Primary usage
azwi <work_item_id> [--org ORG] [--section SECTION ...] [--format {markdown,json}]
Examples:
azwi 2195
azwi 2195 --section acceptance
azwi 2195 --section metadata --section comments --comment-limit 20
azwi 2195 --format markdown
azwi 2195 --output wi-2195.md
azwi 2195 --output wi-2195.md --download-images assets
azwi 2195 --field-acceptance Custom.Acceptance
azwi 2195 --extra-field Custom.DevNotes
azwi fields --type Bug --project Payments
azwi config show
Commands
Fetch a work item:
azwi <work_item_id> [options]
List fields for a work item type:
azwi fields --type Bug [--project PROJECT] [--org ORG]
Manage config:
azwi config show
azwi config set-defaults --org my-org --project Payments
azwi config set-field --global --acceptance Microsoft.VSTS.Common.AcceptanceCriteria
azwi config set-field --project Payments --description Custom.DevDescription
azwi config add-extra-field --project Payments Custom.ReleaseNotes
Output
Default sections:
- metadata
- description
- acceptance
- comments
- prs
Formats:
jsonmarkdown
Default format:
json
JSON includes stable top-level work_item metadata plus a sections object containing rendered Markdown text and source field reference names for text fields. Markdown remains available as an explicit render mode for prompt-friendly output.
Configuration
azwi uses ~/.azwi/config.toml for non-secret defaults and field mappings.
Supported config layers:
- top-level defaults
- top-level project overrides
- org-specific defaults
- org-specific project overrides
- per-invocation CLI overrides
Example:
[defaults]
org = "my-org"
project = "ProjectA"
[defaults.fields]
description = "System.Description"
acceptance = "Microsoft.VSTS.Common.AcceptanceCriteria"
repro_steps = "Microsoft.VSTS.TCM.ReproSteps"
system_info = "Microsoft.VSTS.TCM.SystemInfo"
[projects."ProjectB".fields]
acceptance = "Custom.AcceptanceNotes"
extra_fields = ["Custom.ReleaseNotes"]
[orgs."other-org".defaults]
project = "ProjectX"
[orgs."other-org".defaults.fields]
acceptance = "Custom.Acceptance"
azwi config show renders the effective resolved config. PATs are never written to the config file.
Image download behavior
Use --download-images DIR together with --output to download remote Markdown image URLs and rewrite them to local relative paths.
Relative DIR paths resolve from the current working directory, not from the output file location.
Packaging and publishing
This repo supports both:
uv run ./azwi.py ...via the PEP 723 metadata block in the root wrapperuvx azwi ...via the package defined inpyproject.toml
Build:
uv build --no-sources
Release workflow:
- tag a release such as
v0.9.2 - GitHub Actions builds the package
- publish to PyPI using Trusted Publishing
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file azwi-0.9.3.tar.gz.
File metadata
- Download URL: azwi-0.9.3.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e32724ae3ebbd2530a0aadadbd885d19235ad54a530548cd53cd5d28f085b683
|
|
| MD5 |
9570f7bd6a09ac64aca164fd5a634240
|
|
| BLAKE2b-256 |
dace189b73809996ba78aa40e4a64b6473c4d0660e2b52f0439c766bb718caa9
|
File details
Details for the file azwi-0.9.3-py3-none-any.whl.
File metadata
- Download URL: azwi-0.9.3-py3-none-any.whl
- Upload date:
- Size: 19.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13d8156c20687a95ab6b887c943462e6e5c77404d3ba956c6e52f3dde8d0d1d5
|
|
| MD5 |
a5f40f20684df3a415ce1b84253dfc67
|
|
| BLAKE2b-256 |
806689d330e7b3572e4848f7816a9275589e52efe0939bf39a4ca3f621b01d98
|