Skip to content
| Marketplace
Sign in
Visual Studio Code>SCM Providers>Azure DevOps BoardNew to Visual Studio Code? Get it now.
Azure DevOps Board

Azure DevOps Board

pratyakash

| (0) | Free
Browse your assigned Azure DevOps work items in the sidebar or a kanban board, powered by the Azure CLI. No tokens to configure.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Azure DevOps Board

Your assigned Azure DevOps work items in VS Code, grouped by state. Two views over the same data:

  • Sidebar tree — quick access, native keyboard navigation and context menus.
  • Board panel — Azure Board: Open Board opens a React webview in an editor tab: category tabs, a ⌘K palette, and a detail sheet. Works from 320px up.

Click any item to read its description and acceptance criteria as rendered markdown.

Install

Search Azure DevOps Board in the Extensions view, or:

ext install pratyakash.azure-devops-board

Why it needs no credentials

Every call shells out to the Azure CLI (az boards), so authentication, token refresh, and org defaults are the CLI's problem. The extension stores no secrets and has zero runtime dependencies.

Requirements

The Azure CLI with its Azure DevOps extension:

az extension add --name azure-devops

Nothing else. If az boards works in your terminal, this works.

Setup

Install the extension, open the Azure Boards view in the activity bar, and click Sign in to Azure DevOps. You are asked for:

  1. your organization URL, e.g. https://dev.azure.com/my-org
  2. your project name

Both are saved to settings, then az login runs in a terminal. The board loads by itself once the sign-in completes — no manual refresh.

Already configured az devops configure --defaults? Those are used when the settings are left empty.

Accounts

The board shows work items assigned to whoever az is signed in as — that is what @Me resolves to in the query. Run Azure Board: Switch Account (or click the account row in the sidebar) to sign in as someone else, or sign out.

Choice Command it runs
Sign in az login --allow-no-subscriptions
Sign out az logout

--allow-no-subscriptions is not incidental: an account with Azure DevOps access but no Azure subscription — the normal case for a developer — fails plain az login with "No subscriptions found" and ends up signed out.

The command runs in a terminal, and the extension never sees the credential. Signing in is a browser flow, so it is handed to az, which already manages the token. There is deliberately no token box here: that would mean this extension storing a secret the Azure CLI is responsible for.

Settings

Setting Default Meaning
adoboard.organization "" Organization URL. Empty falls back to the az devops configure default.
adoboard.project "" Project name. Same fallback.
adoboard.promotedStates ["Ready for QA"] States given a tab of their own instead of being folded into their Azure DevOps category. A state your process doesn't use simply never matches.

What it does

  • Board tree — one WIQL query for every open item assigned to you, bucketed by state (largest bucket first). States Done, Completed, Closed, Removed, and Resolved are excluded.
  • Sprint filter — the Sprint: … row at the top of the tree (or the funnel icon in the view title) opens a searchable picker: All sprints, a Current sprint shortcut (whichever iteration contains today), then every project iteration newest-first. The active choice is marked, shown in the tree row, and persists per workspace. Picking a grouping node such as MyProject\Previous Sprints includes its children.
  • Current-branch item — pinned at the top when the branch name carries a ticket id (fix/next_71253 → 71253).
  • Detail view — description + acceptance criteria converted from ADO's HTML to markdown and opened in a preview. A virtual document, not a webview.
  • Category tabs, not columns. Azure DevOps gives User Story 27 states, so a column-per-state board rendered 13 columns and needed ~3,500px. Each state carries a category, and those collapse the same board to 3 tabs — To do (71), In progress (40), Resolved (9). The real state is kept as a heading inside each tab, so nothing is lost. One column below 640px, a grid above.
  • ⌘K palette to jump to any work item by id, title, type, or state.
  • Detail sheet — clicking a card slides in its description and acceptance criteria, rather than taking over an editor tab.
  • Stat header — open, in progress, blocked, and the current branch's item, over a bar showing the whole backlog's distribution.
  • Sprint dropdown beside the text filter; neither round-trips to az to filter. Iterations are labelled by path, not bare name — a project commonly has both MyProject\22 and MyProject\Previous Sprints\22. The live sprint is hoisted to the top and marked — current, exactly once, so no two options share a value.
  • Drag a card onto a state section to change its state. Sections the card cannot legally enter dim during the drag. To cross categories, hover the target tab for a moment mid-drag and it springs open, then drop.
  • Change state from the card via its Move to… select, which lists only states valid for that work item's type — on a real Agile process 53% of state/type combinations are invalid (a Task has 7 states and no Ready for Dev, a User Story has 27), so an unfiltered list would mostly offer moves the server rejects. Every move raises a toast with an Undo.
  • Commands — Open Board, Refresh, Switch Account, Select Sprint, Open in Browser, Copy Work Item Id, Open Work Item for Current Branch.
  • Signed out, it says so and nothing else. No empty board, no sprint filter, no board button — just one sign-in action, in the sidebar and the panel alike.

Architecture

src/az.ts                    `az` CLI calls, WIQL building     pure Node, tested
src/format.ts                HTML->markdown, iterations, URLs  pure, tested
src/board.ts                 view model + message protocol     pure, tested, shared
src/sprint.ts                sprint selection state            shared by both views
src/tree.ts                  sidebar TreeDataProvider          VS Code glue
src/panel.ts                 webview host, CSP, messaging      VS Code glue
src/webview/App.tsx          React kanban app                  esbuild
src/webview/globals.css      Tailwind v4 theme                 @tailwindcss/cli
src/webview/components/ui/   shadcn/ui components              vendored by the CLI
src/webview/lib/utils.ts     shadcn `cn` helper
src/markdown.ts              tiny markdown parser              pure, tested

Work item bodies are HTML authored by anyone with board access. format.ts converts them to markdown, markdown.ts parses that, and Markdown.tsx renders React elements — nothing reaches the DOM as markup, and only http(s) links become clickable (isHttpUrl, enforced again before openExternal).

Styling

The panel uses shadcn/ui on Tailwind v4 and Radix primitives. shadcn is a generator, not a dependency — npx shadcn@latest add copies component source into src/webview/components/ui/, and that code is owned and editable here.

Two things the setup needs that a Next/Vite project gets for free:

  • The @/* alias lives in the root tsconfig.json. The shadcn CLI resolves its aliases against that file specifically; without it the CLI writes to a literal directory named @. esbuild mirrors the alias in esbuild.mjs.
  • CSS is a separate build step. esbuild does not run Tailwind, so npm run compile invokes @tailwindcss/cli over globals.css and esbuild only bundles the TSX. globals.css declares @source explicitly because the input file is not at the project root.

Dark mode keys off VS Code's own vscode-dark / vscode-high-contrast body class via a Tailwind @custom-variant, not prefers-color-scheme — only the body class follows the user's editor theme rather than their OS setting.

board.ts deliberately imports nothing — the webview bundle pulls from it, so a vscode or node: import would either break esbuild or drag the extension host into the browser bundle.

Develop

npm install
npm test          # Node's built-in runner, native TS — no build step
npm run type:check # both tsconfigs: extension (Node/CJS) and webview (DOM/JSX)
npm run compile   # tsc for the extension, esbuild for the webview
npm run watch     # esbuild watch for the React app

Press F5 to launch an Extension Development Host.

There are two tsconfigs because the two halves target different runtimes: the extension is CommonJS on Node with no DOM, the webview is ESM in a browser with JSX. tsconfig.webview.json only type-checks; esbuild does the bundling.

Tests cover the pure logic — HTML conversion, branch parsing, WIQL escaping, URL building, board grouping, and message validation. tree.ts, panel.ts, doc.ts, and extension.ts are VS Code API glue, exercised by running it.

Known limits

  • State is the only writable field. No comments, assignment, or time logging.
  • A move patches one card, it does not refetch. The card is moved locally on drop, the write runs, and only that card is confirmed or sent back to the state it came from. Nothing else re-renders and the scroll position is kept. The sidebar tree is patched in step, also without a second query. The trade-off: if a workflow rule silently rewrites the state to something other than what was asked for, the board won't notice until the next Refresh.
  • HTML conversion is regex-based — it handles what ADO's editor emits (div/p/br/li/b/i/a/img). Tables and deeply nested lists will flatten. Swap in turndown if that starts mattering.
  • Sprints come from the project iteration list, not a team backlog. The @CurrentIteration WIQL macro and az boards iteration team list both need a team context that az boards query can't supply, so "current sprint" is computed by comparing today against each iteration's start/finish dates. A gap between sprints means no current sprint, and the shortcut is hidden.
  • Tree grouping is by state, not by sprint — the sprint is a filter.
  • With a sprint filter active, the branch-pinned item only appears if that work item is in the selected sprint.
  • Items are fetched once per refresh; there's no background polling.
  • The panel no longer matches your editor's exact colors. It follows the light/dark mode but uses its own violet palette, which is the point of the theme and the cost of it. The sidebar tree is still fully native.
  • The webview bundles React, Radix, and Tailwind output — ~336 KB of JS and ~50 KB of CSS in a 143 KB package. The tree view costs nothing by comparison.
  • Microsoft's @vscode/webview-ui-toolkit is deprecated, which is why the panel uses shadcn/Radix rather than an official VS Code component library.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft