{"id":50912745,"url":"https://github.com/gilbertwong96/ado_cli","last_synced_at":"2026-06-16T12:00:23.873Z","repository":{"id":364495779,"uuid":"1267131894","full_name":"gilbertwong96/ado_cli","owner":"gilbertwong96","description":"Self-contained Azure DevOps CLI in Elixir. OAuth login (including MSA), embedded skills for AI agents, cross-platform via Burrito.","archived":false,"fork":false,"pushed_at":"2026-06-13T08:45:44.000Z","size":275,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-13T09:22:25.625Z","etag":null,"topics":["azure-devops","burrito","cli","devops","elixir","oauth"],"latest_commit_sha":null,"homepage":"https://github.com/gilbertwong96/ado_cli","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gilbertwong96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-12T08:49:51.000Z","updated_at":"2026-06-13T08:45:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gilbertwong96/ado_cli","commit_stats":null,"previous_names":["gilbertwong96/ado_cli"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/gilbertwong96/ado_cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilbertwong96%2Fado_cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilbertwong96%2Fado_cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilbertwong96%2Fado_cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilbertwong96%2Fado_cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gilbertwong96","download_url":"https://codeload.github.com/gilbertwong96/ado_cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gilbertwong96%2Fado_cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34404748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure-devops","burrito","cli","devops","elixir","oauth"],"created_at":"2026-06-16T12:00:14.586Z","updated_at":"2026-06-16T12:00:23.862Z","avatar_url":"https://github.com/gilbertwong96.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ado\n\n\u003e **AI-native Azure DevOps CLI** — structured JSON output, embedded skills for\n\u003e LLM agents, and a self-discoverable command tree. Built for humans **and**\n\u003e AI agents (pi, Claude Code, Copilot, Cursor, etc.) to share.\n\nA self-contained, cross-platform command-line tool for managing Azure DevOps —\nprojects, repositories, work items, pipelines, pull requests, releases, and\nmore. Works with both **cloud** (`dev.azure.com`) and **self-hosted** Azure\nDevOps Server.\n\nBuilt with [Finch](https://hex.pm/packages/finch),\n[CLI Mate](https://hex.pm/packages/cli_mate), and\n[Burrito](https://hex.pm/packages/burrito).\n\n[![CI](https://github.com/gilbertwong96/ado_cli/actions/workflows/ci.yml/badge.svg)](https://github.com/gilbertwong96/ado_cli/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/gilbertwong96/ado_cli/graph/badge.svg)](https://codecov.io/gh/gilbertwong96/ado_cli)\n[![Elixir](https://img.shields.io/badge/elixir-1.20+-purple.svg)](https://elixir-lang.org)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Website](https://img.shields.io/badge/website-gilbertwong96.github.io%2Fado_cli-blue)](https://gilbertwong96.github.io/ado_cli/)\n\n---\n\n## Why \"AI-native\"?\n\nMost CLIs are designed for humans and retrofitted for AI agents with `--json`\nflags that nobody uses. `ado` is designed the other way around:\n\n| Feature | Human-friendly | AI-agent-friendly |\n|---|---|---|\n| Output | Tables + colors | Stable JSON envelopes on every command |\n| Discovery | `ado --help` → 3 levels deep | `ado schema --json` — full command tree in 1 round trip |\n| Documentation | Embedded `man` pages | `ado skills list` / `ado skills read NAME --json` |\n| Error handling | Pretty stack traces | `{ok: false, error: {code, status, message, details}}` |\n| Auth | Browser OAuth (interactive) | PAT, device code, browser — all machine-discoverable |\n| Distribution | `brew install ado` | Single self-contained binary, no runtime deps |\n\nEvery command supports `--json` for machine consumption. Every error has a\nstable `code` (e.g. `auth_required`, `not_found`, `validation_error`) so agents\ncan match on it instead of parsing English.\n\n**For LLM agents:** run `ado skills install` to install the embedded skills to\nyour agent's skill directory (`~/.pi/agent/skills/`, `~/.claude/skills/`, etc.)\nso they load natively on startup.\n\n---\n\n## Installation\n\n### npm (recommended)\n\n```bash\nnpm install -g @gilbertwong1996/ado\nnpm approve-scripts @gilbertwong1996/ado      # npm 11+: allow the postinstall to auto-install shell completion\n```\n\n\u003e **npm 11+ note**: newer npm versions gate lifecycle scripts behind explicit\n\u003e approval. Run the second command above once — the postinstall will then\n\u003e auto-install shell completion on every `npm install -g` afterward.\n\n### Pre-built binaries\n\nDownload the binary for your platform from the\n[latest release](https://github.com/gilbertwong96/ado_cli/releases/latest) and\nput it on your `$PATH`:\n\n```bash\n# Example for Apple Silicon Mac (pick the right binary for your platform)\ncurl -L -o ado https://github.com/gilbertwong96/ado_cli/releases/latest/download/ado-0.4.1-macos-aarch64\nchmod +x ado \u0026\u0026 sudo mv ado /usr/local/bin/\n```\n\n### From source\n\nRequires Elixir 1.20+ and Mix:\n\n```bash\ngit clone https://github.com/gilbertwong96/ado_cli.git\ncd ado_cli\nmix deps.get\nmix escript.build\ncp ado /usr/local/bin/\n```\n\nOr build standalone binaries with Burrito:\n\n```bash\nMIX_ENV=prod mix release\n# Binaries in burrito_out/ (macOS aarch64, Linux x86_64/aarch64, Windows x86_64/aarch64)\n```\n\n\u003e **Note**: `mix release` in dev produces an OTP system service (`start`, `stop`, `eval`)\n\u003e — not a CLI tool. Use `mix escript.build` for dev iteration.\n\n---\n\n## Quick Start\n\n```bash\n# Set credentials\nexport ADO_ORG=myorg\nexport ADO_PAT=mypersonalaccesstoken\n\n# List projects\nado projects list\n\n# Create a work item\nado workitems create MyProject --type Bug --title \"Fix login page\"\n\n# Open a pull request\nado prs create MyProject MyRepo --title \"Add feature\" --source dev --target main\n```\n\n## Shell Completion\n\n`\u003cTAB\u003e` works out of the box once you source the generated script:\n\n```bash\n# bash (add to ~/.bashrc)\neval \"$(ado completion bash)\"\n\n# zsh (add to ~/.zshrc; also works as a one-liner)\nado completion zsh \u003e \"${fpath[1]}/_ado\"\n\n# fish (add to ~/.config/fish/config.fish)\nado completion fish | source\n\n# PowerShell (add to $PROFILE)\nado completion powershell | Out-String | Invoke-Expression\n```\n\nAfter installing, pressing `\u003cTAB\u003e` after `ado ` shows every top-level\nsubcommand; after `ado prs ` shows `abandon`, `comments`, `complete`,\n`create`, `diff`, `list`, `show`; and so on at every nesting level.\n\nRe-run the completion command after upgrading `ado` to pick up new\nsubcommands and options.\n\n---\n\n## For LLM Agents (pi, Claude Code, Copilot, Cursor, Codex)\n\nRun `ado schema --json` to discover the full command tree, or install the\nembedded skills so your agent loads them natively:\n\n```bash\n# Install skills to your agent's skill directory\nado skills install                          # pi + claude + cursor + codex\nado skills install --target pi              # ~/.pi/agent/skills/\nado skills install --target claude          # ~/.claude/skills/\nado skills install --target cursor          # ~/.cursor/skills/\nado skills install --target codex           # ~/.codex/skills/\nado skills install --target copilot --repo .# ./.github/ado-cli/  (per-repo)\n\n# Verify the install\nls ~/.pi/agent/skills/                       # you should see ado-cli/, ado-auth/, ado-ci/\n```\n\nOnce installed, the agent can `ado skills list`, `ado skills read \u003cname\u003e`, and\n`ado schema \u003ccommand\u003e --json` as native operations, with no shell-out overhead.\n\n---\n\n## Authentication\n\nMultiple auth methods, auto-resolved in priority order. **No `az` CLI required.**\n\n| Priority | Method | How |\n|----------|--------|-----|\n| 1 | CLI flags | `--org ORG --pat TOKEN` |\n| 2 | Environment variables | `ADO_ORG` + `ADO_PAT` |\n| 3 | Config file | `~/.ado_cli/config.json` (persistent) |\n\nAuth via `ado login` is browser-based OAuth — no `az login` is detected or\nrequired. The CLI is self-contained.\n\n### Login (persistent)\n\nThree login methods are supported. Pick the one that fits your situation:\n\n#### 1. Browser OAuth (default) — recommended for interactive use\n\nOpens your default browser to the Microsoft sign-in page, then captures the\nauth code on a local callback. Works with both work/school (AAD) and personal\n(MSA) Microsoft accounts. Personal accounts (e.g. `me@outlook.com`) on\n`*.visualstudio.com` orgs are supported via an ARM-first token-exchange flow.\n\n```bash\n# Open browser, sign in, get redirected back. Org auto-detected.\nado login\n\n# Hint the org (avoids the auto-detect query)\nado login --org myorg\n```\n\nWhat happens:\n1. `ado` opens `https://login.microsoftonline.com/...` in your browser\n2. You sign in with AAD or MSA credentials\n3. The CLI captures the auth code on a localhost callback\n4. The CLI exchanges the code for an ARM token, then for an Azure DevOps\n   access token, and saves the token to `~/.ado_cli/config.json`\n5. Org is auto-detected from the token (or use `--org` to pin it)\n\n#### 2. Device code — recommended for SSH / no-browser sessions\n\nFor headless terminals, remote boxes, or any machine without a browser\nreachable from the same shell. The CLI prints a URL and a code; you visit\nthe URL in any browser (laptop, phone) and enter the code to authenticate.\n\n```bash\nado login --method device --org myorg\n```\n\nExample output:\n\n```\nTo sign in, use a web browser to open:\n  https://microsoft.com/devicelogin\nAnd enter the code: ABC123XYZ\n```\n\nThe CLI polls the token endpoint every few seconds; once you complete the\nsign-in on the other device, the CLI saves the token and you're logged in.\n\n#### 3. Personal Access Token (PAT) — recommended for CI / scripts\n\nStores a PAT in `~/.ado_cli/config.json` for repeated use. Best for\nautomation, CI runners, and scripts. See\n[How to create a PAT](https://learn.microsoft.com/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate).\n\n```bash\nado login --method pat --org myorg --pat mytoken\n```\n\nRequired scopes for full CLI coverage: `vso.work`, `vso.code`, `vso.project`,\n`vso.build`, `vso.release` (or \"Full access\" if you prefer).\n\n#### 4. Environment variables (no login) — recommended for ephemeral CI\n\nSkip `ado login` entirely by setting env vars in the runner / shell:\n\n```bash\nexport ADO_ORG=myorg\nexport ADO_PAT=mytoken\nado projects list\n```\n\n`ADO_PAT` is only read from the environment; it is never written to the\nconfig file. `ADO_ORG` is also accepted as a CLI flag (`--org myorg`).\n\n#### Check status / log out\n\n```bash\nado whoami       # Show current auth method, org, server\nado logout       # Remove ~/.ado_cli/config.json\n```\n\n### Auth priority order\n\nWhen you run a command, the CLI resolves credentials in this order:\n\n1. `--pat` / `--org` CLI flags (per-invocation)\n2. `ADO_PAT` / `ADO_ORG` env vars (per-session)\n3. `~/.ado_cli/config.json` (persistent, set via `ado login`)\n\nThe first source that provides both an org and a token wins.\n\n---\n\n## Self-Hosted Azure DevOps Server\n\nFor on-premises / private cloud Azure DevOps Server:\n\n```bash\n# CLI flag\nado --server https://ado.internal.example.com --org DefaultCollection projects list\n\n# Environment variable\nexport ADO_SERVER=https://ado.internal.example.com\n\n# Login with server\nado login --method pat --server https://ado.internal.example.com --org DefaultCollection --pat xxx\n```\n\nWhen `--server` is set, `--org` becomes the collection name (e.g. `DefaultCollection`).\n\n---\n\n## Commands\n\nThe CLI covers **24 service areas** of Azure DevOps. The canonical,\nup-to-date reference is the `ado-cli` skill:\n\n```bash\nado skills read ado-cli\n# Or read on disk: cat priv/skills/ado-cli/SKILL.md\n```\n\nQuick examples:\n\n```bash\n# Projects\nado projects list\nado projects create MyProject --description \"My project\" --visibility private\n\n# Repos \u0026 PRs\nado repos list MyProject\nado repos create MyProject MyRepo\nado prs create MyProject MyRepo --title \"Add feature\" --source dev --target main\nado prs complete MyProject MyRepo 42 --merge-strategy squash --delete-source\n\n# Work items\nado workitems list MyProject --type Bug --state Active\nado workitems query MyProject --wiql \"SELECT [System.Id] FROM WorkItems WHERE [System.AssignedTo] = @Me\"\nado workitems create MyProject --type Bug --title \"Fix login\" --tags \"bug,critical\"\n\n# Pipelines (YAML)\nado pipelines list MyProject --top 10\nado pipelines run MyProject 42 --branch main --variables \"ENV=staging,DEBUG=true\"\n\n# Watch a build in real-time (live status + streaming logs)\nado ci watch MyProject 99\nado ci watch MyProject --latest --definition 42 --branch main\n\n# Pipelines (Classic builds)\nado pipelines-builds queue MyProject --definition 5 --branch main\nado pipelines-builds cancel MyProject 99\n\n# Variable groups + per-pipeline variables (secrets)\nado pipelines vars create MyProject --name prod-secrets --variables \"DB_HOST=db,DB_PASS=secret\" --secret DB_PASS\nado pipelines variables create MyProject 42 --key DEPLOY_TOKEN --value \"ghp_xxx\" --secret\n\n# Iterations, areas, wikis\nado iterations list MyProject MyTeam\nado areas create MyProject --name Backend\nado wikis create MyProject --name Engineering\n\n# Users, teams, security\nado users list\nado teams members list MyProject MyTeam\nado security groups create MyProject --name \"Deployers\"\nado security permissions namespaces\n\n# Banners + packages\nado banners set --message \"Maintenance in progress\" --type warning\nado packages list MyProject MyFeed\nado imports create MyProject new-repo --url https://github.com/org/repo.git\n\n# CI / scriptable\nado --json projects list | jq '.[].name'\n```\n\nFor the complete command reference including all options, flags, and JSON\noutput schemas, see the embedded `ado-cli` skill (`ado skills read ado-cli`).\nEvery command also supports `--help` for inline reference:\n\n```bash\nado --help\nado projects --help\nado pipelines vars create --help\n```\n\n---\n\n## Global Options\n\n```\n-o, --org ORG       Azure DevOps organization / collection name [env: ADO_ORG]\n-t, --pat TOKEN     Personal Access Token [env: ADO_PAT]\n-s, --server URL    Self-hosted Azure DevOps Server URL [env: ADO_SERVER]\n-v, --verbose       Enable verbose output\n    --json          Output raw JSON instead of formatted tables\n    --help          Show help for any command\n```\n\n---\n\n## Development\n\n### Setup\n\n```bash\n# Install dependencies\nmix deps.get\n\n# Compile\nmix compile\n\n# Run tests\nmix test\n\n# Run in dev mode\nmix run -e 'AdoCli.CLI.run(System.argv())' -- projects list\n```\n\n### Build\n\n```bash\n# Escript (fast CLI binary for dev)\nmix escript.build\n./ado projects list\n\n# Burrito native binaries (for distribution)\nMIX_ENV=prod mix release\n# → burrito_out/  (macOS aarch64, Linux x86_64/aarch64, Windows x86_64/aarch64)\n```\n\n\u003e `mix release` in dev produces an OTP system service (`start`/`stop`/`eval`).\n\u003e Use `mix escript.build` for CLI iteration.\n\n### Documentation\n\n```bash\n# Generate HTML docs\nmix docs\n# Open doc/index.html\n\n# Also outputs: doc/llms.txt (AI context), doc/ado_cli.epub\n```\n\n### Quality\n\n```bash\n# Full CI pipeline (compile, format, credo, deps check, xref, dialyzer)\nmix ci\n\n# Quick checks\nmix lint         # Credo static analysis\nmix inspect      # Project structure map (reach)\nmix health       # Dead code \u0026 smell detection\nmix test         # Unit tests\n```\n\n---\n\n## Quality Tools\n\n| Tool | Purpose | Mix Task |\n|------|---------|----------|\n| [Credo](https://hex.pm/packages/credo) | Static code analysis | `mix credo --strict` |\n| [Dialyxir](https://hex.pm/packages/dialyxir) | Type checking | `mix dialyzer` |\n| [ex_dna](https://hex.pm/packages/ex_dna) | Code duplication detection | `mix ex_dna` |\n| [ex_slop](https://hex.pm/packages/ex_slop) | AI-generated code slop checks | (loaded by Credo) |\n| [Reach](https://hex.pm/packages/reach) | Program dependence graph | `mix reach.map` |\n| [mix_audit](https://hex.pm/packages/mix_audit) | Dependency vulnerability audit | `mix deps.audit` |\n| [ExDoc](https://hex.pm/packages/ex_doc) | Documentation generation | `mix docs` |\n\n---\n\n## Project Structure\n\n```\nado_cli/\n├── lib/\n│   ├── ado_cli.ex                    # Main module (escript entry point)\n│   ├── ado_cli/\n│   │   ├── application.ex            # Burrito entry point\n│   │   ├── auth.ex                   # Multi-provider authentication (PAT, browser, device)\n│   │   ├── client.ex                 # Finch HTTP client with redirect handling\n│   │   ├── config_file.ex            # ~/.ado_cli/config.json persistence\n│   │   ├── skills.ex                 # Embedded skill file reader\n│   │   └── cli/\n│   │       ├── cli.ex                # CLI dispatch \u0026 global options\n│   │       ├── helpers.ex            # Shared output/error helpers\n│   │       ├── projects.ex           # projects list|show|create|update|delete\n│   │       ├── repos.ex              # repos list|show|create|delete\n│   │       ├── branch_policies.ex    # branch-policies list|show|create|update|delete\n│   │       ├── work_items.ex         # workitems list|show|query|create|update|delete|comments\n│   │       ├── pipelines.ex          # pipelines list|show|run|create|update|delete|vars|variables\n│   │       ├── builds.ex             # pipelines-builds (classic) list|show|queue|cancel|tags|definitions\n│   │       ├── folders.ex            # pipelines-folders list|create|delete\n│   │       ├── run_artifacts.ex      # pipelines-artifacts list|download\n│   │       ├── pull_requests.ex      # prs list|show|create|complete|abandon|approve|vote|comments\n│   │       ├── releases.ex           # releases list|show\n│   │       ├── iterations.ex         # iterations list|show|create|update|delete\n│   │       ├── areas.ex              # areas list|show|create|update|delete\n│   │       ├── wikis.ex              # wikis and pages list|show|create|update\n│   │       ├── teams.ex              # teams list|show|create|update|delete|members\n│   │       ├── users.ex              # users list|show|add|remove\n│   │       ├── extensions.ex         # extensions list|show|install|uninstall|enable|disable\n│   │       ├── agent_pools.ex        # agent-pools list|show|queues\n│   │       ├── connections.ex        # connections list|show\n│   │       ├── security.ex           # security groups + permissions\n│   │       ├── banners.ex            # banners show|set|delete\n│   │       ├── packages.ex           # packages list|versions|show\n│   │       ├── imports.ex            # imports list|show|create (GitHub→AzDo migration)\n│   │       ├── auth_commands.ex      # login command\n│   │       ├── logout.ex             # logout command\n│   │       ├── whoami.ex             # whoami command\n│   │       └── skills.ex             # skills list|read command\n│   └── mix/tasks/ci/\n│       └── dialyzer.ex              # CI dialyzer with Finch false-positive filter\n├── priv/skills/                      # Embedded skill content (loaded at compile time)\n│   ├── ado-cli/                      # Main reference\n│   ├── ado-auth/                     # Auth details\n│   └── ado-ci/                       # CI/CD patterns\n├── config/\n│   └── config.exs                    # Application configuration\n├── test/\n├── .credo.exs                        # Credo configuration (strict mode)\n├── AGENTS.md                         # CI quality gate principles\n└── mix.exs                           # Project definition \u0026 aliases\n```\n\n## Command Reference\n\nThe CLI covers **24 service areas** of Azure DevOps. The canonical,\nup-to-date reference is the **`ado-cli` skill** embedded in the binary:\n\n```bash\nado skills read ado-cli\n```\n\nOr see the on-disk source at `priv/skills/ado-cli/SKILL.md`. The skill\nincludes the full command table, conventions, and quick-start examples.\n\n---\n\n## API Coverage\n\nAll commands use Azure DevOps REST API v7.1 (configurable via `ADO_API_VERSION`).\nThe CLI covers **24 service areas** of Azure DevOps. See the embedded\n`ado-cli` skill (`ado skills read ado-cli`) for the full command reference\nand per-endpoint coverage.\n\n| Service area | Endpoint | Status |\n|--------------|----------|--------|\n| Core / Projects | `_apis/projects` | list, show, create, update, delete |\n| Git / Repos | `{project}/_apis/git/repositories` | list, show, create, delete |\n| Git / Pull Requests | `{project}/_apis/git/repositories/{id}/pullrequests` | list, show, create, complete, abandon, vote, comments |\n| Git / Policies | `{project}/_apis/policy/configurations` | list, show, create, update, delete |\n| Git / Imports | `{project}/_apis/git/importRequests` | list, show, create |\n| Work Items | `{project}/_apis/wit/wiql`, `_apis/wit/workitems/{id}` | query, show, create, update, delete, comments, attachments |\n| Sprints / Iterations | `{project}/_apis/work/teamsettings/iterations` | list, show, create, update, delete |\n| Area Paths | `{project}/_apis/wit/classificationNodes/areas` | list, show, create, update, delete |\n| Pipelines (YAML) | `{project}/_apis/pipelines`, `/runs` | list, show, run, create, update, delete |\n| Pipelines (Variables) | `{project}/_apis/pipelines/{id}/variables` | list, create, delete |\n| Variable Groups | `{project}/_apis/distributedtask/variablegroups` | list, show, create, update, delete |\n| Pipelines (Classic) | `{project}/_apis/build/builds` | list, show, queue, cancel, tags, definitions |\n| Pipelines (Folders) | `{project}/_apis/pipelines/folders` | list, create, delete |\n| Pipeline Artifacts | `{project}/_apis/build/builds/{id}/artifacts` | list, download |\n| Releases | `{project}/_apis/release/releases` | list, show |\n| Wikis | `{project}/_apis/wiki/wikis`, `pages` | list, show, create, update, delete |\n| Teams | `_apis/teams` | list, show, create, update, delete, members |\n| Users | `_apis/accesscontrolentries` | list, show, add, remove |\n| Extensions | `_apis/extensionmanagement/installedextensions` | list, show, install, uninstall, enable, disable |\n| Agent Pools | `_apis/distributedtask/pools`, `/queues` | list, show, queues |\n| Service Connections | `{project}/_apis/serviceendpoint/endpoints` | list, show |\n| Security Groups | `_apis/graph/groups` | list, show, create, delete, members |\n| Security Permissions | `_apis/securitynamespaces`, `_apis/permissions` | namespaces, list |\n| Admin Banners | `_apis/settings/entries/banners` | show, set, delete |\n| Universal Packages | `{project}/_apis/packaging/feeds/{id}/packages` | list, versions, show |\n\n---\n\n## CI Pipeline\n\nEvery commit must pass the full CI gate (`mix ci`):\n\n| Step | Check |\n|------|-------|\n| 1 | `compile --all-warnings --warnings-as-errors` |\n| 2 | `format --check-formatted` |\n| 3 | `credo --strict` |\n| 4 | `deps.unlock --check-unused` |\n| 5 | `deps.audit` |\n| 6 | `xref graph --label compile-connected --fail-above 0` |\n| 7 | `dialyzer` (with Finch false-positive filtering) |\n\nSee `AGENTS.md` for the full quality gate specification.\n\n---\n\n## Watch a build in real-time\n\n`ado ci watch` streams live status and per-line log output\nfor an Azure DevOps build — like `tail -f` for CI:\n\n```bash\n# Watch build #123 in MyProject\nado ci watch MyProject 123\n\n# Watch the latest build on a specific pipeline + branch\nado ci watch MyProject --latest --definition 42 --branch main\n\n# Tighter polling (default 2s)\nado ci watch MyProject 123 --poll-interval 500\n```\n\nThe watcher polls the Azure DevOps Build API every 2s (configurable)\nand prints:\n\n- Build status (running / succeeded / failed / canceled)\n- Job/step transitions from the timeline\n- New log lines as they're written by the running step\n\nThe underlying streaming mechanism uses `?id=N` on the log endpoint,\nwhich returns log content up to line N. The watcher increments N\neach tick and only prints lines it hasn't seen before.\n\nThe watch exits automatically when the build reaches a terminal\nstate, or on Ctrl+C.\n\n---\n\n## Skills for AI Agents\n\n`ado` ships with embedded skill files (YAML-frontmatter Markdown) for use by\nAI coding agents. The skills teach agents how to use the CLI, not the\nunderlying REST API — agents should never call the Azure DevOps REST API\ndirectly when the CLI is available.\n\n### What's in the binary\n\nThree skills are embedded at compile time and exposed via:\n\n```bash\nado skills list                       # List all available skills\nado skills read ado-cli               # Main reference: setup, auth, all 24 command groups\nado skills read ado-auth              # Authentication details (PAT, browser, MSA, troubleshooting)\nado skills read ado-ci                # CI/CD patterns: GitHub Actions, GitLab CI, secrets, scripts\n```\n\nSkills are also on disk in `priv/skills/{name}/SKILL.md` for repository-level\ninspection or to copy into an agent's `~/.claude/skills/` directory.\n\n### For AI agents: how to use these skills\n\n1. **Read `ado-cli` first** when you need to discover available commands. The\n   `Command Groups` table in that skill is the canonical reference — it\n   covers all 24 service areas (projects, repos, workitems, pipelines,\n   vars, builds, artifacts, folders, prs, releases, iterations, areas,\n   wikis, teams, users, extensions, agent-pools, connections, security\n   groups, security permissions, banners, packages, imports, branch-policies).\n\n2. **Read `ado-auth`** before invoking any command, to confirm which auth\n   method is in effect and how to handle the `Not authenticated` error. The\n   skill explains PAT vs browser OAuth vs device code, MSA personal org\n   support, and the priority order of CLI flags / env vars / config file.\n\n3. **Read `ado-ci`** when running `ado` in a pipeline / CI script. The\n   skill documents:\n   - The recommended env-var-based auth (`ADO_ORG` + `ADO_PAT`)\n   - JSON output (`ado --json ... | jq ...`) for scripting\n   - Exit codes (`0` success, `1` generic, `2` API error, `3` auth)\n   - GitHub Actions and GitLab CI examples\n\n4. **Always prefer `--json` flag** when scripting. The CLI emits stable\n   JSON in non-tabular mode; `--json` also skips table-formatting errors\n   that can appear in CI environments that don't handle ANSI escapes well.\n\n5. **Always quote project and repo names** that contain spaces:\n   ```bash\n   ado repos list \"Employee Management\"\n   ```\n\n6. **Never log credentials.** The CLI masks PATs in error output, but\n   don't echo them yourself. Pass via `ADO_PAT` env var or `--pat` flag\n   only.\n\n### Loading skills into an agent\n\nIf your agent supports the `skills` discovery protocol:\n\n```bash\n# Quick check\nado skills list | head\n\n# Dump a skill to a file (e.g., for an agent's skill directory)\nado skills read ado-cli \u003e ~/.claude/skills/ado-cli/SKILL.md\n```\n\nIf your agent does **not** support the skills protocol, paste the output of\n`ado skills read ado-cli` into its context — it contains the full command\nreference (~130 lines).\n\n### Skills vs REST API\n\nThe skills deliberately **do not** document the Azure DevOps REST API.\nAgents reading the skills will call the CLI rather than constructing\nHTTP requests by hand. This is intentional: the CLI handles auth, retries,\nresult pagination, and cross-org quirks that vary between AAD / MSA /\nself-hosted deployments.\n\n---\n\n## Publishing\n\n`ado` is distributed through two channels:\n\n1. **GitHub Releases** — single self-contained binary per platform.\n2. **npm** — 6 packages under the `@gilbertwong1996` scope, one of\n   which (the main `@gilbertwong1996/ado`) is a thin Node.js wrapper\n   that picks the right platform binary via `optionalDependencies`.\n\n\u003e **Note:** The npm scope is `@gilbertwong1996` (the maintainer's npm\n\u003e username), but the GitHub repo is `gilbertwong96/ado_cli` (the\n\u003e maintainer's GitHub handle). These are different accounts.\n\n**All publishing happens from your local laptop, not from CI.** Tag a\nrelease, push the tag, wait for the CI release job to attach the\nbinaries, then run the publish script. The CI release job produces the\nGitHub Release artifacts; npm publishing is intentionally a manual\nstep so the maintainer (currently just you) can verify the artifacts\nbefore they go public.\n\n### Release flow\n\n```bash\n# 1. Bump version in mix.exs, commit, tag\n$EDITOR mix.exs                          # bump version: \"0.2.0\" -\u003e \"0.4.1\"\ngit add -u \u0026\u0026 git commit -m \"v0.2.0\"\ngit tag -a v0.2.0 -m \"Release 0.2.0\"\ngit push github main v0.2.0\n```\n\nPushing the tag triggers the CI `release` job, which cross-compiles\nthe Burrito binary for all 5 platforms and uploads them as artifacts.\nThe `release-attach` job then creates the GitHub Release with the 5\nbinaries attached.\n\nWait a few minutes for CI to finish. Verify the release is up:\n\n```bash\ngh release view v0.2.0\n```\n\nThen publish to npm locally:\n\n```bash\n# Downloads binaries from the v0.2.0 release + publishes all 6 pkgs\n./scripts/npm-publish.sh 0.2.0\n```\n\nThat's it. The script handles everything else.\n\n### What the publish script does\n\n`scripts/npm-publish.sh VERSION` runs four steps:\n\n1. **`gh release download v${VERSION}`** — fetches the 5 binaries\n   (`ado-${VERSION}-{macos-aarch64,macos-x86_64,linux-x86_64,linux-aarch64,windows-x86_64.exe}`)\n   from the GitHub Release you just tagged.\n2. **Copies each binary** into\n   `npm/@gilbertwong1996-ado-\u003cplatform\u003e-\u003carch\u003e/bin/ado{,.exe}`.\n3. **`jq` bumps the version** in all 6 `package.json` files\n   (`@gilbertwong1996/ado` and the 5 platform packages).\n4. **`npm publish --access public`** for the 5 platform packages first,\n   then the main package last (so its `optionalDependencies` resolve\n   cleanly).\n\n### Useful flags\n\n```bash\n./scripts/npm-publish.sh 0.2.0 --dry-run       # show what would happen, no network\n./scripts/npm-publish.sh 0.2.0 --skip-download  # binaries already in place\n```\n\n### Verifying a publish\n\n```bash\n# Check the published package on npm\nnpm view @gilbertwong1996/ado\nnpm view @gilbertwong1996/ado-darwin-arm64 dist.integrity\n\n# Install from npm and smoke-test\nnpm install -g @gilbertwong1996/ado\nado --help\nado projects list --json\nado skills install --target pi\n```\n\n### Prerequisites\n\n| Tool | Why | How to get it |\n|---|---|---|\n| `gh` | Download release binaries | `brew install gh \u0026\u0026 gh auth login` |\n| `npm` | Publish packages | `brew install node` (bundles npm) |\n| `jq` | Edit `package.json` files | `brew install jq` |\n| An `npm` token with publish rights on `@gilbertwong1996/*` | Auth | `npm login` then verify with `npm whoami` |\n\nThe script uses whatever `npm` authentication is in your environment\n(usually `~/.npmrc`). No tokens are hard-coded.\n\n### Why local-only publishing?\n\nA few reasons:\n\n- **You're the only maintainer.** There's no team to coordinate with,\n  and no separation-of-duties that requires a CI service identity.\n- **OIDC provenance doesn't work locally.** `npm publish --provenance`\n  requires a GitHub Actions OIDC token, which only Actions has. Your\n  local publish will show no provenance badge on npmjs.com — that's\n  fine for a single-maintainer project.\n- **You want to verify before going public.** The script's `--dry-run`\n  flag lets you inspect exactly what would be published without\n  actually publishing.\n- **The `NPM_TOKEN` secret is fragile.** Long-lived npm tokens in CI\n  are a security liability. A local publish uses your own short-lived\n  login session.\n\nIf a second maintainer joins later, the script can still be invoked\nfrom CI by exporting the same `gh` and `npm` auth that you'd use\nlocally. The script has no assumptions about where it runs.\n\n### Rolling back a bad publish\n\nnpm allows unpublishing within 72 hours of release:\n\n```bash\nnpm unpublish @gilbertwong1996/ado@0.2.0\n```\n\nAfter 72 hours, you'll need to publish a new patch version. Prefer\nfix-forward over rollback.\n\n### Why the 6-package split?\n\n| Package | Size | Who downloads |\n|---|---|---|\n| `@gilbertwong1996/ado` | ~3 KB (Node.js wrapper) | Everyone |\n| `@gilbertwong1996/ado-darwin-arm64` | ~9 MB | Apple Silicon Mac users only |\n| `@gilbertwong1996/ado-darwin-x64` | ~9 MB | Intel Mac users only |\n| `@gilbertwong1996/ado-linux-arm64` | ~15 MB | Linux aarch64 users only |\n| `@gilbertwong1996/ado-linux-x64` | ~16 MB | Linux x86_64 users only |\n| `@gilbertwong1996/ado-win32-x64` | ~22 MB | Windows users only |\n\n`os`, `cpu`, and `libc` fields in each `package.json` make npm pick\nonly the right one at install time. A Mac user never downloads the\n22 MB Windows binary, and vice versa.\n\n---\n\n## License\n\nCopyright © 2026 Gilbert Wong\n\nThis project is licensed under the **Apache License, Version 2.0** — see the\n[LICENSE](LICENSE) file for the full text. You may obtain a copy of the\nlicense at \u003chttps://www.apache.org/licenses/LICENSE-2.0\u003e.\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgilbertwong96%2Fado_cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgilbertwong96%2Fado_cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgilbertwong96%2Fado_cli/lists"}