VS Code Extensions
Predecessor Tree Viewer

Predecessor Tree Viewer

by NirushaD

Visualise the full predecessor dependency chain for any Test Case, Bug, or Change Request — directly from the work item form or the Boards hub.

Downloads

5

Rating

— (0)

Version

1.5.8

Last updated

Jul 25, 2026

Azure DevOps extension that renders the full dependency chain for any Test Case, Bug, or Change Request — as a collapsible list or an interactive graph, inside the work item form and in a dedicated Boards hub. Configurable per-user and org-wide, with CSV/text export.


Version history

See CHANGELOG.md for the full release history.


Project structure

ado-predecessor-tree/
├── src/
│   ├── config.ts               # Config schema, defaults, persistence (per-user + org)
│   ├── treeService.ts          # API fetching + tree building (config-driven)
│   ├── exporters.ts            # CSV download + copy-as-text
│   ├── TreeExplorer.tsx        # Toolbar, stats, search, list view, view switch
│   ├── GraphView.tsx           # Layered SVG dependency graph
│   ├── SettingsPanel.tsx       # Config editor (apply / save org default)
│   ├── TreeView.css            # Styles (shared by all views)
│   ├── hub/
│   │   ├── hub.html            # HTML template for hub page
│   │   └── index.tsx           # Hub app entry point
│   └── form-panel/
│       ├── form-panel.html     # HTML template for form panel
│       └── index.tsx           # Form panel entry point
├── images/
│   ├── icon.png                # 128×128 extension icon
│   └── screenshot-*.png        # Marketplace screenshots (list, graph, form, settings, nav)
├── dist/                       # Built output (generated by webpack)
├── vss-extension.json          # Extension manifest
├── webpack.config.js
├── tsconfig.json
├── package.json
├── overview.md                 # Marketplace listing description
└── LICENSE.md

Note: there is no longer a TreeView.tsx — it was replaced by TreeExplorer.tsx. The TreeView.css file remains and is still used.


One-time setup

1. Prerequisites

  • Node.js 18+
  • tfx-cli (installed as a dev dependency — no global install needed)

2. Create a Visual Studio Marketplace publisher

  1. Go to https://marketplace.visualstudio.com/manage
  2. Sign in with your Microsoft account
  3. Click Create publisher
  4. Choose a publisher ID (e.g. nirusha-tools) — this is permanent and public
  5. Fill in display name and optionally a logo

3. Update the manifest

In vss-extension.json, replace:

  • "publisher": "NirushaD" → your actual publisher ID
  • "NirushaD" in links → your GitHub username/org

4. Create a Personal Access Token for publishing

  1. In Azure DevOps, go to User Settings → Personal Access Tokens
  2. Create a new token with:
    • Organisation: All accessible organisations
    • Scopes: Marketplace (Publish)
  3. Copy the token — you will use it as MARKETPLACE_PAT

Build

npm install
npm run build

Output lands in ./dist/.


Icons and screenshots

The marketplace listing uses a 128×128 PNG at images/icon.png and the images/screenshot-*.png files referenced from overview.md (list view, graph view, work item form panel, settings panel, and Boards navigation). If you update a screenshot, keep the filename and it flows through to the listing on the next publish.


Package

npm run package

This produces ./release/NirushaD.predecessor-tree-viewer-1.0.0.vsix.


Publish

Option A — Command line

MARKETPLACE_PAT=<your-token> npm run publish

Option B — Marketplace UI

  1. Go to https://marketplace.visualstudio.com/manage
  2. Click New extension → Azure DevOps
  3. Upload the .vsix file from ./release/

First publish is PRIVATE by default

Your extension starts as Private. To make it public:

  1. Go to your publisher page on the Marketplace
  2. Click the extension → Share/Publish
  3. Select Make public

Microsoft performs a light review before public extensions are visible to all ADO users (typically 1–3 business days for new publishers).


Install on your own organisation (while private)

  1. On the Marketplace page for your extension, click Share
  2. Enter your ADO organisation name
  3. In your ADO org: Organisation Settings → Extensions → Browse marketplace
  4. Search for your extension by name and install it

Local development / testing

You can test against a real ADO org without publishing using tfx:

# Publish to your org directly (private, no marketplace)
npx tfx extension publish \
  --manifest-globs vss-extension.json \
  --token <your-PAT> \
  --share-with <your-org-name>

Then install from Organisation Settings → Extensions.


Bumping the version for updates

  1. Increment "version" in vss-extension.json (semver: 1.0.0 → 1.0.1)
  2. Run npm run package and npm run publish

ADO organisations that have installed your extension will receive the update automatically.


Configuration

All behaviour that used to be hardcoded now lives in src/config.ts as DEFAULT_CONFIG, and every field is editable at runtime from the in-app Settings panel (the ⚙ button in the toolbar).

Setting What it controls Default
Work item types to include Only these types appear in the tree Bug, Defect, Change Request
Test case type Roots of this type follow Tests / Tested By links Test Case
Hidden states Items in these states are hidden by default (toggleable) Closed
Relations to follow from the root Which links to follow at level 0 (descendants always follow Predecessor) Predecessor
Severity field Reference name of the severity field Microsoft.VSTS.Common.Severity
Extra columns Additional fields shown inline and in exports none
Maximum depth Safety cap on recursion 20

Per-user vs organisation defaults

Settings persist through ADO's Extension Data Service:

  • Apply for me → stored at User scope; affects only the current user.
  • Save as org default → stored at Default scope; becomes the baseline for everyone in the organisation. Requires the acting user to have permission to write extension data (typically a collection/organisation admin).

Effective config is resolved as: DEFAULT_CONFIG ← org default ← (view preferences are separate and always per-user). If persistence is unavailable for any reason, the extension silently falls back to DEFAULT_CONFIG so the tree always renders.

View preferences (list/graph, show-closed, expand depth) are always per-user and saved automatically as you change them.


How the tree is built

  1. BFS collection (collectItemsByBFS) walks outward from the root using getWorkItemsBatch with $expand: relations. From the root it follows the configured root relations; below the root it follows Predecessor only. It collects the full reachable graph regardless of state, so the show/hide-Closed toggle is instant and needs no re-fetch.

    ADO API constraint: getWorkItemsBatch cannot combine $expand: relations with an explicit fields list — relations come back empty. The code omits fields and lets the relations expand return the full field set.

  2. Tree construction (buildNode) shapes the cached items into a tree, filtering to the configured types, labelling each link, and flagging excluded-state and duplicate (cycle) nodes. Closed items are flagged, not dropped — the UI hides them based on the toggle.

  3. Views consume the same TreeNode:

    • TreeExplorer renders the list, toolbar, search, and stats.
    • GraphView collapses repeated IDs into unique nodes and rings any node with in-degree > 1 (a shared blocker).

Extending

Add a new relation category

In src/config.ts, add a key to RelationKey, its raw ADO rel string to REL_STRING, and a label to REL_LABEL. It then appears automatically as a checkbox in the Settings panel's "Relations to follow from the root".

Restrict the form panel to certain work item types

Add a filter to the form contribution in vss-extension.json:

"properties": {
  "name": "Dependency Tree",
  "uri": "dist/form-panel.html",
  "height": 400,
  "filter": { "workItemTypes": ["Test Case", "Bug", "Change Request"] }
}

Adjust the CSV schema

exportCsv in src/exporters.ts flattens the tree to rows. The column set mirrors the indented CSV produced by the daily PowerShell extract; add or reorder columns there.

Add a column from a custom field

No code change needed — open Settings → Extra columns, give it a label and the field's reference name (e.g. Custom.FunctionGroup), and Apply.


Policies

Related extensions