vitaliy-bobrov/dsh-plugin-bmad-sprint-board

dsh-plugin-bmad-sprint-board

仓库尚未提供可用的公开描述。

Uncategorizeddsh-plugin-bundledsh-plugins

BMAD Sprint Board

A DSH Harness plugin that reads a BMAD v7 project and shows it in the Session sidebar: every initiative, what is being worked on, and what the ticket store disagrees with the tickets on disk.

Read-only. It never writes to your ticket store. Every action it offers is a string you copy.

Requirements │ BMAD Sprint board │ Chat
-------------------------------------------
Status   Epic   Tickets   Initiatives

tools  done    4 epics   16 tickets      <- initiative, active when set

GAPS (2)
  L1  plans not linked in the ticket store        high
      16 plan files match a ticket by name, but no entry
      declares them with a ticket key             [Ask agent · prompt]
  C1  epic settled with open tickets              high
      epic-tools-landing says done, 2 tickets open

BLOCKED (1)  IN PROGRESS (2)  DONE (13)  UNKNOWN (29)

What you get

Four views, one tab

View · Shows Status · One foldable lane per ticket state, with a gaps board beneath it Epic · One section per epic: its status, its tickets, and its progress Tickets · Every ticket in the initiative, grouped by state, across all epics Initiatives · Every initiative with its status and counts, marking the active one

Selecting an initiative in Initiatives loads it into the other three views. The selection is local: nothing is written back, so looking at another initiative cannot change which one BMAD considers active.

BMAD v7 only

This is version 2. Version 1 read BMAD v6 -- sprint-status.yaml, epics.md, spec-*.md -- and none of those exist in a v7 project. The two are different data models, not different formatting, so the plugin is released in two versions:

BMAD · Install v7 · dsh-plugin-bmad-sprint-board (this one, 2.x) v6 · dsh-plugin-bmad-sprint-board@1.0.0

Opened on a v6 project, 2.x says so and points at 1.0.0 rather than rendering an empty board.

The gaps board

The board is a check on the ticket store, not a mirror of it.

Detector · Fires when L1 unreadable ticket files · a file in a ticket folder is neither a leaf ticket nor a plan, so the store ignores it L2 unlisted leaves · a leaf ticket exists on disk with no entry in the ticket index L3 plans no ticket claims · a plan file corresponds to no index entry L4 unrecognised status · a ticket carries a status word this board does not know C1 epic settled with open tickets · an epic says done while tickets inside it are not C2 initiative settled with open tickets · an initiative says done while tickets inside it are not E1 initiative declares no epics · the folder exists and its store lists no epics

L1 is the one that matters on a migrated project. The ticket store decides what a file is from its frontmatter type: story, spike or bug is a leaf that carries the ticket, anything else declaring a ticket key is a plan over one, and anything else is ignored. A file named story-x-plan.md whose type is feature and which names no ticket is therefore *neither* — invisible to the tooling, which reports its ticket as backlog however finished the work is. Every number it prints is wrong while every file on disk looks correct.

The board's lanes are the store's lanes. States come from tickets.py's own table rather than being invented: an empty status is backlog, because a planned story looks exactly like that before bmad-build writes its plan — a plan is an artefact of building, not a precondition of existing. Only a status word the store does not define becomes *unknown*, and it is shown but never counted as settled.

How it reads a v7 project

It resolves the same two keys the official tooling does, by merging the same three files lowest priority first:

_bmad/config.toml                 [core] output_folder
_bmad/custom/config.toml          team overrides
_bmad/custom/config.user.toml     [core] active_initiative

which is what _bmad/scripts/resolve_config.py does. The board agrees with that script rather than assuming a layout.

Install

From npm, into the web profile:

dsh plugin --profile web add dsh-plugin-bmad-sprint-board

Or from the repository, and from a local clone:

dsh plugin --profile web add github:vitaliy-bobrov/dsh-plugin-bmad-sprint-board
dsh plugin --profile web add /path/to/bmad-sprint-board-bundle

Substitute your own profile name for web. Nothing needs building, the package has no dependencies, and it runs no install scripts. Reload the page afterwards: the Client half registers on the next load, and the Host half contributes nothing to register.

The same three, through the agent's tool rather than the CLI:

plugin_manager({ action: "install_bundle",
                 target: "dsh-plugin-bmad-sprint-board" })

Peer dependency

The manifest declares one peer, and the range is not the obvious one:

"peerDependencies": { "@deepseek-ai/dsh": "^0.2.0-0" }

A plain ^0.2.0 is rejected. The compatibility check compares the range against the running version with prereleases included, and against a runtime such as 0.2.0-rc.2 a bare ^0.2.0 does not match — so the install is refused before pnpm runs. ^0.2.0-0 resolves to >=0.2.0-0 <0.3.0-0: prereleases of 0.2.0, every later 0.2.x, and nothing beyond.

Category

UI & Experience. It adds a sidebar tab and reads. It contributes no tool, no model and no service, and it writes nothing.

Extending

The plugin is two layers, and only the second knows about DSH:

What · Where Parsers · src/toml.js, src/frontmatter.js — the two readers BMAD's files need The project model · src/config.js, src/store.js, src/model.js, src/scan.js — pure, no DSH, no DOM The checks · src/detect.js How it renders · src/shell-*.js — CSS, components, slot registration

Adding a view is one entry in the view list in src/shell-post.js plus a body function; the switcher, the fold state and the snapshot are already shared.

Adding a detector is a function returning gaps shaped { id, title, severity, subject, evidence, action } and one push in detectInitiative(). src/model.test.js shows the shape: each detector is tested against a fixture that should fire it *and* a clean fixture beside it, because a detector nobody has checked can stay quiet is one nobody has checked.

node build.mjs          # reassemble client.js from src/
node build.mjs --check  # fail if client.js and src/ have drifted apart
node --test src/*.test.js

client.js is committed on purpose: an install from a registry or a git URL does no build, so the assembled bundle has to be present. Edit src/, rebuild, and --check will tell you if you forget.

More

  • Implementation notes

— the parsing, the linking rules and the bundle layout. None of it is needed to install or use the plugin.

Licence

MIT — see LICENSE.