Skip to content
| Marketplace
Sign in
Visual Studio Code>Visualization>JIRA Triage LedgerNew to Visual Studio Code? Get it now.
JIRA Triage Ledger

JIRA Triage Ledger

BW Digital Systems & Publishing

| (0) | Free
Runs the triage cycle over a JIRA backlog and enforces what a prompt cannot: repositories refreshed before anything is read, every verdict kept in a ledger the team shares, nothing posted without a tick.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

JIRA Triage Ledger

Runs the triage → report → comment → state cycle over a JIRA backlog, in whatever project the editor has open.

It is not a JIRA client and it does not replace anybody's judgement. It does the part a prompt cannot: it prepares a deterministic input, enforces the steps, keeps state the whole team shares, and shows the result.

What it does

Renders a report as something to work with. One tab per section, keyed on the section letter so a report and its translation are read the same way. Conflicts and proposed comments carry colour, owed work warns, findings stay quiet. Verdict tables are painted rather than reproduced: the decision cell is a pill, the decisions are counted into tiles above the grid, and the long columns are clamped to two lines so the eye can travel down the column that matters. A table fills the panel and wraps inside it: no table scrolls sideways and neither does the page, because a reader who has to drag a bar to reach the last column loses the column the row is about.

Holds the next run to the corrections the last one raised — as hard as your team needs. When a report proposes fixes to a hand-maintained file, jiraTriage.gates.corrections decides what happens: off leaves them in the report, warn marks the report that raised them until each is answered, block refuses to start the next run. Each is answered separately as applied or dismissed — dismissing is a real answer, because the gate wants the reading and not the edit. A finding raised again next week folds into one held item carrying its age, so a correction nobody applies gets louder rather than newer. It ships off: a triage raises map corrections on most runs, and a mark that is always lit is not a mark.

Opens a report in the same tick as the click. The tree node carries the path, the file is read synchronously, and the Markdown is rendered by a renderer compiled into the bundle. No loading screen, nothing waiting on a scan.

Separates "we looked and there is nothing" from "nobody looked". A group nobody established renders differently from an empty one and never shows a zero. An empty list read as a real zero is a wrong answer that looks like a right one.

Brings every repository level before anything is judged. The remote-tracking refs are refreshed first, because ahead/behind figures are exactly as old as your last fetch — without that, a checkout nobody has fetched reports level whatever the server holds, and the report describes a tree the team does not have. Repositories that are behind are fast-forwarded; one that will not fast-forward is reported rather than merged, and a dirty one is never touched at all.

Records who decided what. The working directory is shared, so a run one person files is read by another. Reports name whoever filed them, and verdicts, acknowledgements and runs carry the address git already knows you by — nothing to set up, and nothing that can disagree with the commit carrying the record. Where git has no address, records are written without an author rather than with a guessed one.

Shows every proposed comment as its own row, with the reason beside it. Which ones go out is the reader’s judgement on the text in front of them; nothing here measures a comment or refuses one. The evidence belongs in the report, and the procedure says so — because evidence in a comment is noise, not because it takes up room.

Deletes a report only when you say so, and says what it is not deleting. Right-click a report — or several — and it names every file it is about to take, including the translation, because half a report is worse than none. The files go to the recycle bin and anything committed is still in the history. The verdicts, the comment register and the answered corrections stay: they are the decisions the report describes, not the report.

Says whether a report has left this machine. A row says not committed, changed since commit or not pushed; one already in the upstream says nothing, because that is the ordinary end and a mark on every row is a mark nobody reads. One report goes out from its own context entry, or everything waiting goes in one commit from the title bar — confined to the working directory, so nothing half-finished elsewhere in the repository is swept up with it. When somebody else has filed reports this checkout has not got, the list says so and offers to fast-forward. It reads git and never rewrites it: what is committed, when, and by whom is your workflow.

Says one thing in the status bar, and it is the most urgent one. Three facts compete for that line: somebody else has filed reports this checkout has not got, nothing of any kind has run here for too long, and the kind you run has fallen behind while something else has not. The first is cleared by pressing, and nothing else on screen says it. Red is spent on the second and nothing else, because it is the only one that means nobody is looking at the backlog at all; your own kind lagging while the team works is amber, and reports waiting are neither, because news in red is how a warning becomes furniture. Days are counted in working days, so a weekend does not turn the alarm into furniture either.

Shows every kind of run at once, in the State view. One line per kind with the date of the last one and how long ago, the kind you run marked as yours, and a line for what other people have filed that has not reached this checkout. The strip has room for one of those and picks it; the pane has room for all of them. A kind nothing has ever run and nobody here runs is left out rather than listed as never run — a project that does not do sprint plans is not behind on sprint plans. Where nothing could count what is waiting it says which of the three reasons that was, rather than a nought.

Checks the reports repository on a timer, every fifteen minutes by default, so a report a colleague pushed this morning appears without anybody starting a run. Refs only: no branch moves, nothing is merged, and the working tree is left byte for byte — which is why it does this on its own, while winding the directory forward stays behind the row you press. jiraTriage.preflight.fetchEvery sets the interval and 0 switches it off.

Configures itself in a form. Every project fact this extension reads has a field behind the gear: the tracker, the repositories, the documentation, the languages, the sprint's workflow order and tiers. Values are read from the file's own words and written back into it value by value, so the comments beside each key survive. The whole file exports to one path and replaces from another, which is how a second project starts from a worked example rather than a list of key names.

Says what the button is about to do. The run panel opens with one sentence naming the whole arc, and it names the destination, because the three are three different experiences: one starts a program, one fills a text box, one changes the clipboard and waits for a paste.

Reads JIRA itself, if you let it. With jiraTriage.jira.enabled on and a token stored, it sweeps the threads this account is in and answers two questions nothing else can between runs: what is waiting for your reply, and what came back to you after you already answered. The sweep reads what a search can offer it — the issues assigned to you or that you raised, still open, changed recently — and says so on screen beside its answer, because JIRA cannot be searched for the threads you only commented in. A run reads the threads themselves and its report is the wider answer. It checks your priority anchors against what JIRA holds, so an epic somebody closed last week stops silently producing confident verdicts. It takes the backlog snapshot itself — and writes nothing unless it read the whole backlog, because a snapshot replaces its predecessor whole and a truncated one reads exactly like a backlog that shrank. Off by default: it reaches the network on your own account.

Audits the documentation as a second kind of run. Run Documentation Audit asks the other question: every documented capability against the code that was meant to build it, in one matrix, with the coverage arithmetic reconciled rather than declared. It files its own report beside the triages and reads in the same panel.

Runs the procedure in a console of its own. The agent is started on the task, or handed it when one is already working; the console closes itself when the agent finishes cleanly, and stays open when it does not. Starting a run is the instruction to run it, so nothing waits for a keypress.

The report

Every proposed comment is a row of its own with the reason beside it, and which ones go out is your judgement on the text in front of you — nothing here measures a comment or refuses one. Where a report exists in more than one language the header offers both, and switching keeps your ticks and the tab you were on.

The State view

Where each kind of run stands, and then five questions in three bands: what is asking for something, what was checked and found clear, and what nobody could check. A group that has not been established never renders as a zero.

A run

What the button is about to do, said before it does it, and then who is being waited on.

Install

From the Marketplace, or build a package and install it:

npm install
npm run vsix
code --install-extension jira-triage-ledger-0.2.0.vsix

Getting started

Open the folder you work in and run Set Up JIRA Access from the view title. It is five steps on one page, each saying what it is for, with a button that does it and a badge saying whether it is behind you. The first step asks for the two values nothing can guess — the address you open JIRA at, and the letters your issues start with — in two input boxes, and writes them into .jira-triage.json for you. A later step asks JIRA a single question, so a wrong address or a revoked token is found there rather than twenty minutes into a run.

The rest of the configuration is that file, which Open Project Configuration creates from a commented template:

{
  "jira": { "site": "example.atlassian.net", "projectKey": "PROJ" },
  "repos": ["doc", "backend", "frontend"],
  "docs": { "root": "doc", "files": ["architecture.md"], "enabled": true },
  "storage": ".jira-reports"
}

The folder holding that file is the project root and every path is relative to it. storage is the extension's own working directory: reports, ledger, anchors and procedure overrides live there, scratch/ inside it is git-ignored, and the ignore rules are maintained by the extension rather than left to a person. Nothing is created until there is something to write.

The working directory is the extension's only footprint in your project. It holds no copy of your code, your issues or your documentation — it holds what the runs produced.

Setting up JIRA access

Reading JIRA is what answers three of the five questions in the State view, and it is off until you turn it on. Set Up JIRA Access walks through it; the short version:

  1. Say where JIRA is. Set JIRA Address asks for the host you open issues at — acme.atlassian.net, or jira.company.com/jira where the server lives under a context path — and then for the project key. Both go into .jira-triage.json. The template ships with a placeholder host, and a configuration still carrying it is refused rather than tried: every request against a placeholder fails in a way that reads like JIRA being down.

  2. Get a token. id.atlassian.com → Security → API tokens → Create API token. Give it a label you will recognise. Copy it before you close the page — Atlassian shows it once and never again.

  3. Store it. Set JIRA API Token, paste, Enter. It goes into VS Code's secret store, which is the operating system's credential store: Credential Manager on Windows, Keychain on macOS, the keyring on Linux. Never into settings, never into a file, never into a URL.

  4. Say whose it is. jiraTriage.jira.account is the email address of the account that made the token. Atlassian authenticates by the pair, and the sweep recognises your own comments by that address — set it wrong and every comment you wrote reads as somebody else speaking last. Empty falls back to your git config user.email.

  5. Turn it on. jiraTriage.jira.enabled. Storing a token does not do it: reading reaches the network on your own account, so it stays your decision. The command offers to do it for you once a token is stored.

  6. Check it. Test JIRA Connection asks JIRA for one issue and says what came back. A wrong address, a typo in the project key, a revoked token and a VPN that is off all look identical until something actually uses them.

A token belongs to one account and carries exactly that account's permissions. This extension only ever reads with it — canPost is a hard false — and revoking it on that page stops it working everywhere, immediately.

Runs

Run asks which, and remembers the answer. Six kinds, each asking a different question of the same backlog, and the last one you ran is offered first so Enter repeats it.

Technical triage — what each issue actually is, judged against your own documentation and code before it is judged against the reporter's wish, with proposed comments to tick and send.

Management triage — how the work stands. Load per person against a stated capacity, an overload named only when the numbers say so, what is at risk, what is waiting on a person, and what is filed under the wrong type. No proposed comments: a comment that cites code is written by whoever read the code.

Estimation check — what work costs here, calibrated on issues this team has already closed. The calibration is the first table in the report, and a band with too little closed work behind it stays unset and says so. With nothing to calibrate on the report is one section long, because pricing without calibration is not a worse estimate, it is guessing in a table.

Sprint plan — what fits in the next sprint, ordered by priority anchor and by dependency. The first item that does not fit is shown rather than dropped: where the line falls is the answer you are looking for.

Sprint check — how the sprint that is running is going, several times a day if you want. Six detectors are computed rather than sensed: the issue that closes the sprint, what has stopped moving, what went backwards, what was added, an estimate zeroed with work still to do, and what changed hands. How long a thing has stood still is counted across checks, which no single fetch can see. It asks once per sprint when work stops — the date it counts working days to — and forgets it when that date passes, rather than counting to last sprint's.

Documentation audit — every documented capability against the code that was meant to build it.

None of them writes anything to JIRA, and none of them re-judges what another has decided: the verdicts live in the ledger and the later runs read them.

The management triage and the sprint plan need to know who the team is. That lives in .jira-triage.json under team, because it is a fact about the project rather than about you — the commented template shows the shape. With no roster both still run: they report the people they can see in the assignments and say the roster is missing, rather than deciding for themselves who counts.

Reports you already have

Point storage at a directory that already holds reports and they appear in the list, under the names they already have. Two naming conventions are read: the newer one, where the prefix is the run kind — triage_2026-09-11.md — and the older one that a slash-command workflow writes, jira_triage_2026-09-11.md and jira_status_report_2026-09-11.md. A _pl suffix marks a translation and pairs it with its original; _v2 marks a second version of the same day's report.

A status report is a kind this extension reads and does not run. There is no procedure for one, so Run will not offer it, and the engine refuses a run of a kind it has no method for rather than handing it somebody else's. Listing is a weaker claim than running, and it is the one worth making about a file that was already written.

Nothing is copied or converted. The files stay where they are and are read in place, so a directory shared through git stays shared, and nothing in it is rewritten by being listed.

Procedures

The three procedures — triage, documentation audit, comment — are compiled into the extension. A project can replace any of them by dropping a file of the same name into <storage>/procedures/, which is read in preference to the built-in one. Create Procedure Override writes the built-in there for you to edit, because an override is almost always the built-in with a paragraph changed and a procedure written from nothing loses the parts nobody remembers are load-bearing. Procedures change more often than extensions get released, so a wording fix should not need a version bump.

Settings

Everything specific to one project lives in .jira-triage.json, which the team shares. The editor settings are the ones that differ between people and machines; these are the ones worth knowing about, with their defaults:

Setting Default What it decides
jiraTriage.handoff.target terminal Console, chat input, or the clipboard. Only the console submits.
jiraTriage.handoff.command claude The agent started in that console. Any agent that takes a task on its command line works.
jiraTriage.gates.corrections off What an unanswered correction does: nothing, mark the report, or refuse the next run.
jiraTriage.preflight.fetch true Refresh the remote-tracking refs before reading the figures. Permission to know.
jiraTriage.preflight.fetchEvery 15 Minutes between refreshes of the reports repository. 0 switches the loop off.
jiraTriage.preflight.pull true Fast-forward repositories that are behind. Permission to change.
jiraTriage.jira.enabled false Let the extension query JIRA itself. Off until you say otherwise.
jiraTriage.cadence.triage weekdays How often a run of any kind is expected before the status bar says so.
jiraTriage.badge waiting What the number on the activity-bar icon counts.
jiraTriage.jira.maxThreads 60 How many conversations one sweep reads before it stops.

The rest are in Settings under JIRA Triage Ledger, in six groups, each described for somebody who has not read this file.

What it deliberately is not

Not a JIRA client. No backlog browsing, no issue editing, no sprint management. One cycle, done properly.

Not universal, and it says so. The method assumes a documentation repository treated as the source of truth, with an issue judged against it before it is judged against the reporter's wish. Without such documentation the sieve degenerates into "everything is a wish", which is why docs.enabled: false is a real option rather than an oversight.

Not a writer to JIRA. It reads, when you let it. It never posts: comments are drafted by the agent, approved by you in the report, and go out through the agent. A comment is practically irreversible and a worklog is completely irreversible, so the write path stays where a person is already looking.

Requirements

VS Code 1.104 or later, and git on the PATH for the repository preflight. An agent on the PATH — claude by default, configurable — for the runs themselves. No runtime dependencies.

Reading JIRA is optional and off until you turn it on. It needs an Atlassian API token, stored through Set JIRA API Token in the editor's secret store — never in settings, never in a file, never in a URL.

What leaves your machine

Your JIRA site, and only when you turn reading on: searches and comment threads, over HTTPS, authenticated as you. Nothing else. There is no telemetry, no update check and no service belonging to this extension — it has no runtime dependencies to phone home with. What the agent does with the task it is handed is between you and your agent.

Building from source

npm install
npm run compile     # type-check, lint, bundle
npm test            # the whole suite, no extension host

Every surface is decided in a module that does not import vscode, so all of them render without an editor:

node scripts/preview.ts <project directory>
node scripts/preview.ts <project directory> --pages ./out-pages

That prints the tree, the State view, the badge, the status bar and the gate results from the same functions the editor calls. scripts/gallery.ts goes further: it writes every screen in every state it can be in — the first run, the empty ones, the broken ones, a report with nothing in it, a run stopped at a gate — as a browsable index. Those are the states nobody has on their disk when they want to look at them, and they are exactly the ones that ship wrong. The three webview pages — view/reportPage.ts, view/statePage.ts, view/runPage.ts — return their HTML the same way, so a page can be written to a file and opened in a browser. That is not a convenience: the verdict tables spent a release rendering as two columns instead of four, with every unit test passing, because a cell had been given a display that stops it being a table cell.

Licence

MIT.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft