@ikunin/sprintpilot 2.3.3 → 2.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  addon:
2
2
  name: sprintpilot
3
- version: 2.3.3
3
+ version: 2.3.5
4
4
  description: Sprintpilot — autopilot and multi-agent addon for BMad Method (git workflow, parallel agents, autonomous story execution)
5
5
  bmad_compatibility: ">=6.2.0"
6
6
  modules:
@@ -260,12 +260,28 @@ function buildEdges(strategies, nodes, depsDoc, { includeCrossEpic = false } = {
260
260
  out.push([a, b]);
261
261
  }
262
262
  };
263
+ // Track whether explicit produced any edges in this build — if it did,
264
+ // ordering is suppressed for the same nodeset to avoid the back-edge
265
+ // cycle bug: when an explicit dep points "backwards" against story
266
+ // order (e.g. 6-1 depends on 6-3 — explicit emits 6-3 → 6-1), the
267
+ // linear ordering chain (6-1 → 6-2 → 6-3) closes a fake cycle that
268
+ // the user never declared. Explicit deps express the user's intent
269
+ // in full; ordering is only a fallback when none are provided.
270
+ let explicitProducedEdges = false;
263
271
  for (const strat of strategies) {
264
272
  if (strat === 'explicit') {
265
- pushEdges(edgesFromExplicit(depsDoc, nodes));
266
- if (includeCrossEpic) pushEdges(edgesFromCrossEpic(depsDoc, nodes));
273
+ const explicit = edgesFromExplicit(depsDoc, nodes);
274
+ pushEdges(explicit);
275
+ if (explicit.length > 0) explicitProducedEdges = true;
276
+ if (includeCrossEpic) {
277
+ const cross = edgesFromCrossEpic(depsDoc, nodes);
278
+ pushEdges(cross);
279
+ if (cross.length > 0) explicitProducedEdges = true;
280
+ }
267
281
  } else if (strat === 'ordering') {
268
- pushEdges(edgesFromOrdering(nodes));
282
+ if (!explicitProducedEdges) {
283
+ pushEdges(edgesFromOrdering(nodes));
284
+ }
269
285
  } else if (strat === 'files') {
270
286
  // files strategy opt-in, not implemented yet — a future
271
287
  // sprintpilot-infer-dependencies skill populates the explicit sidecar.
@@ -492,11 +508,16 @@ function renderMermaid(dag, plan) {
492
508
  const epicIssueIds = issueIdByEpicId(plan);
493
509
  const { intra, cross } = bucketEdges(dag.edges);
494
510
  const lines = [];
511
+ // The diagram-type declaration MUST be the first non-blank line.
512
+ // Strict markdown→mermaid renderers (Claude Code's chat renderer
513
+ // included) sniff for `flowchart`/`graph`/etc. as the first content
514
+ // line; leading `%%` comments cause them to silently skip rendering.
515
+ // Comments after the type declaration are fine.
516
+ lines.push('flowchart LR');
495
517
  lines.push(`%% plan-id: ${plan?.plan_id ?? 'unknown'}`);
496
518
  lines.push(`%% generated: ${plan?.generated ?? new Date().toISOString()}`);
497
519
  lines.push('%% Sprint plan DAG — node fill encodes plan_status; cross-epic edges are dashed.');
498
520
  lines.push('%% Story labels are prefixed with their issue_id when set in plan.stories.');
499
- lines.push('flowchart LR');
500
521
 
501
522
  // Group nodes by epic (if any). When sprint-wide, emit subgraphs.
502
523
  const epicGroups = new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikunin/sprintpilot",
3
- "version": "2.3.3",
3
+ "version": "2.3.5",
4
4
  "description": "Sprintpilot — autopilot and multi-agent addon for BMad Method v6: git workflow, parallel agents, autonomous story execution",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {