@nowline/export-mermaid 0.5.0 → 0.6.0

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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,MAAM,WAAW,cAAc;IAC3B,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AA8BD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAmExF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,MAAM,WAAW,cAAc;IAC3B,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAuCD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CA8DxF"}
package/dist/index.js CHANGED
@@ -22,6 +22,20 @@
22
22
  // ```
23
23
  //
24
24
  // <%% lossy comment %%>
25
+ //
26
+ // Every emitted task carries an explicit start token (`after <id>` or an
27
+ // absolute `YYYY-MM-DD` date). Mermaid's positional task parser strips a
28
+ // leading status keyword (`done`/`active`/`crit`/`milestone`) and then reads
29
+ // the remaining comma fields as `[start, duration]` (2 fields) or
30
+ // `[id, start, duration]` (3 fields). A task that named an id but omitted the
31
+ // start (`:done, my-id, 2w`) collapses to two fields after the status strip,
32
+ // so Mermaid mis-reads the id as a start date and throws `Invalid date: my-id`
33
+ // at render time. To keep an explicit id we therefore MUST emit a start token:
34
+ // - declared `after:` deps -> `after <ids>`
35
+ // - otherwise a lane follower -> `after <previous item in the lane>`
36
+ // - otherwise a lane/track leader -> the roadmap start date
37
+ // This mirrors Nowline's default "each item starts after the preceding item in
38
+ // its lane" semantics (specs/rendering.md § Item Bars).
25
39
  import { displayLabel, getProp, getProps, hasProp, roadmapTitle } from '@nowline/export-core';
26
40
  import { durationToMermaid } from './duration.js';
27
41
  function emptyCounts() {
@@ -41,6 +55,7 @@ function emptyCounts() {
41
55
  export function exportMermaid(inputs, options = {}) {
42
56
  const ast = inputs.ast;
43
57
  const title = roadmapTitle(ast.roadmapDecl ?? undefined);
58
+ const startDate = resolveStartDate(inputs);
44
59
  const drops = emptyCounts();
45
60
  const out = [];
46
61
  out.push(`# ${title}`);
@@ -56,27 +71,24 @@ export function exportMermaid(inputs, options = {}) {
56
71
  if (anchors.length > 0) {
57
72
  out.push(' section Anchors');
58
73
  for (const anchor of anchors) {
59
- const date = getProp(anchor, 'date');
74
+ // Anchors are date markers; fall back to the roadmap start when an
75
+ // anchor omits `date:` so Mermaid always sees a valid start token.
76
+ const date = getProp(anchor, 'date') ?? startDate;
60
77
  const id = anchor.name ?? slugify(displayLabel(anchor));
61
- if (date) {
62
- out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
63
- }
64
- else {
65
- out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, after , 0d`);
66
- }
78
+ out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
67
79
  }
68
80
  }
69
81
  // Swimlanes → sections; their items become tasks.
70
82
  const swimlanes = ast.roadmapEntries.filter((e) => e.$type === 'SwimlaneDeclaration');
71
83
  for (const lane of swimlanes) {
72
- emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out);
84
+ emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out, startDate);
73
85
  }
74
86
  // Top-level milestones.
75
87
  const milestones = ast.roadmapEntries.filter((e) => e.$type === 'MilestoneDeclaration');
76
88
  if (milestones.length > 0) {
77
89
  out.push(' section Milestones');
78
90
  for (const m of milestones) {
79
- emitMilestone(m, drops, out);
91
+ emitMilestone(m, drops, out, startDate);
80
92
  }
81
93
  }
82
94
  out.push('```');
@@ -89,30 +101,33 @@ export function exportMermaid(inputs, options = {}) {
89
101
  }
90
102
  return out.join('\n');
91
103
  }
92
- function emitSwimlane(lane, breadcrumb, drops, out) {
104
+ function emitSwimlane(lane, breadcrumb, drops, out, startDate) {
93
105
  const sectionLabel = breadcrumb.join('.');
94
106
  out.push(` section ${escapeMermaidText(sectionLabel)}`);
107
+ // Each lane starts its own sequential chain; the first non-`after` item
108
+ // anchors at the roadmap start date.
109
+ const chain = { prevId: null };
95
110
  for (const child of lane.content) {
96
- emitSwimlaneChild(child, breadcrumb, drops, out);
111
+ emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate);
97
112
  }
98
113
  // Nested swimlanes — count for the lossy report.
99
114
  // SwimlaneContent doesn't include nested swimlanes per the grammar, so
100
115
  // there's nothing to recurse into here. If `nested` lives on the
101
116
  // roadmap-level layout model, that's a separate count tracked elsewhere.
102
117
  }
103
- function emitSwimlaneChild(child, breadcrumb, drops, out) {
118
+ function emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate) {
104
119
  if (child.$type === 'ItemDeclaration') {
105
- emitItem(child, drops, out);
120
+ emitItem(child, drops, out, chain, startDate);
106
121
  return;
107
122
  }
108
123
  if (child.$type === 'GroupBlock') {
109
124
  drops.group += 1;
110
- emitGroup(child, breadcrumb, drops, out);
125
+ emitGroup(child, breadcrumb, drops, out, chain, startDate);
111
126
  return;
112
127
  }
113
128
  if (child.$type === 'ParallelBlock') {
114
129
  drops.parallel += 1;
115
- emitParallel(child, breadcrumb, drops, out);
130
+ emitParallel(child, breadcrumb, drops, out, chain, startDate);
116
131
  return;
117
132
  }
118
133
  if (child.$type === 'DescriptionDirective') {
@@ -120,68 +135,114 @@ function emitSwimlaneChild(child, breadcrumb, drops, out) {
120
135
  return;
121
136
  }
122
137
  }
123
- function emitGroup(group, breadcrumb, drops, out) {
138
+ function emitGroup(group, breadcrumb, drops, out, chain, startDate) {
139
+ // A group is a visual container within a lane — its items continue the
140
+ // lane's sequential chain.
124
141
  for (const child of group.content) {
125
142
  if (child.$type === 'ItemDeclaration') {
126
- emitItem(child, drops, out);
143
+ emitItem(child, drops, out, chain, startDate);
127
144
  }
128
145
  else if (child.$type === 'GroupBlock') {
129
146
  drops.group += 1;
130
- emitGroup(child, breadcrumb, drops, out);
147
+ emitGroup(child, breadcrumb, drops, out, chain, startDate);
131
148
  }
132
149
  else if (child.$type === 'ParallelBlock') {
133
150
  drops.parallel += 1;
134
- emitParallel(child, breadcrumb, drops, out);
151
+ emitParallel(child, breadcrumb, drops, out, chain, startDate);
135
152
  }
136
153
  else if (child.$type === 'DescriptionDirective') {
137
154
  drops.description += 1;
138
155
  }
139
156
  }
140
157
  }
141
- function emitParallel(parallel, breadcrumb, drops, out) {
158
+ function emitParallel(parallel, breadcrumb, drops, out, chain, startDate) {
159
+ // Tracks run concurrently: each starts from the parallel's entry point
160
+ // (the lane cursor as it was on entry), not after the previous track.
161
+ const entryId = chain.prevId;
162
+ let lastTrackEnd = entryId;
142
163
  for (const child of parallel.content) {
143
164
  if (child.$type === 'ItemDeclaration') {
144
- emitItem(child, drops, out);
165
+ const trackChain = { prevId: entryId };
166
+ emitItem(child, drops, out, trackChain, startDate);
167
+ lastTrackEnd = trackChain.prevId;
145
168
  }
146
169
  else if (child.$type === 'GroupBlock') {
147
170
  drops.group += 1;
148
- emitGroup(child, breadcrumb, drops, out);
171
+ const trackChain = { prevId: entryId };
172
+ emitGroup(child, breadcrumb, drops, out, trackChain, startDate);
173
+ lastTrackEnd = trackChain.prevId;
149
174
  }
150
175
  else if (child.$type === 'DescriptionDirective') {
151
176
  drops.description += 1;
152
177
  }
153
178
  }
179
+ // After the block, the lane continues from the last track (lossy — Mermaid
180
+ // can't express "after the latest of N tracks").
181
+ chain.prevId = lastTrackEnd;
154
182
  }
155
- function emitItem(item, drops, out) {
183
+ function emitItem(item, drops, out, chain, startDate) {
156
184
  countDrops(item, drops);
157
185
  const id = item.name ?? slugify(displayLabel(item));
158
186
  const status = mapStatus(getProp(item, 'status'));
159
187
  const after = getProps(item, 'after');
160
188
  const duration = durationToMermaid(getProp(item, 'duration') ?? getProp(item, 'size')) ?? '1d';
161
- const _ref = after.length > 0 ? `after ${after.join(' ')}` : 'after , 0d'.replace(', 0d', '');
162
- const meta = [status, id, after.length > 0 ? `after ${after.join(' ')}` : '', duration]
163
- .filter((s) => s !== '')
164
- .join(', ');
189
+ const start = startTokenFor(after, chain, startDate);
190
+ const meta = [status, id, start, duration].filter((s) => s !== '').join(', ');
165
191
  out.push(` ${escapeTaskName(displayLabel(item))} :${meta}`);
192
+ // Advance the lane cursor so the next sequential item chains after this one.
193
+ chain.prevId = id;
166
194
  }
167
- function emitMilestone(milestone, drops, out) {
195
+ function emitMilestone(milestone, drops, out, startDate) {
168
196
  const id = milestone.name ?? slugify(displayLabel(milestone));
169
197
  const date = getProp(milestone, 'date');
198
+ const after = getProps(milestone, 'after');
199
+ let start;
170
200
  if (date) {
171
- out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${date}, 0d`);
201
+ start = date;
202
+ }
203
+ else if (after.length > 0) {
204
+ start = `after ${after.join(' ')}`;
172
205
  }
173
206
  else {
174
- const after = getProps(milestone, 'depends');
175
- if (after.length > 0) {
176
- out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, after ${after.join(' ')}, 0d`);
177
- }
178
- else {
179
- out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, 0d`);
180
- }
207
+ // A milestone with neither a date nor predecessors still needs a start
208
+ // token; anchor it at the roadmap start so Mermaid renders it.
209
+ start = startDate;
181
210
  }
211
+ out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${start}, 0d`);
182
212
  if (hasProp(milestone, 'style'))
183
213
  drops.style += 1;
184
214
  }
215
+ /**
216
+ * Start token for a task: declared `after:` deps win, otherwise chain after the
217
+ * previous item in the lane, otherwise anchor the lane/track leader at the
218
+ * roadmap start date. Always non-empty so Mermaid never mis-reads the task id
219
+ * as a start date.
220
+ */
221
+ function startTokenFor(after, chain, startDate) {
222
+ if (after.length > 0)
223
+ return `after ${after.join(' ')}`;
224
+ if (chain.prevId)
225
+ return `after ${chain.prevId}`;
226
+ return startDate;
227
+ }
228
+ /**
229
+ * Absolute anchor date (`YYYY-MM-DD`) for lane leaders. Prefers the roadmap's
230
+ * declared `start:`, falling back to the layout-computed timeline start (always
231
+ * present) so the export renders even when the source omits `start:`.
232
+ */
233
+ function resolveStartDate(inputs) {
234
+ const decl = inputs.ast.roadmapDecl;
235
+ const declared = decl ? getProp(decl, 'start') : undefined;
236
+ if (declared && /^\d{4}-\d{2}-\d{2}$/.test(declared.trim()))
237
+ return declared.trim();
238
+ return formatIsoDate(inputs.model.timeline.startDate);
239
+ }
240
+ function formatIsoDate(d) {
241
+ const y = d.getUTCFullYear();
242
+ const m = String(d.getUTCMonth() + 1).padStart(2, '0');
243
+ const day = String(d.getUTCDate()).padStart(2, '0');
244
+ return `${y}-${m}-${day}`;
245
+ }
185
246
  function countDrops(item, drops) {
186
247
  if (getProps(item, 'labels').length > 0)
187
248
  drops.labels += 1;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nowline/export-mermaid",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Nowline Mermaid exporter — Markdown+Mermaid gantt transpilation",
5
5
  "license": "Apache-2.0",
6
6
  "engines": {
@@ -21,9 +21,9 @@
21
21
  "src/"
22
22
  ],
23
23
  "dependencies": {
24
- "@nowline/core": "0.5.0",
25
- "@nowline/layout": "0.5.0",
26
- "@nowline/export-core": "0.5.0"
24
+ "@nowline/core": "0.6.0",
25
+ "@nowline/export-core": "0.6.0",
26
+ "@nowline/layout": "0.6.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^25.9.1",
package/src/index.ts CHANGED
@@ -22,6 +22,20 @@
22
22
  // ```
23
23
  //
24
24
  // <%% lossy comment %%>
25
+ //
26
+ // Every emitted task carries an explicit start token (`after <id>` or an
27
+ // absolute `YYYY-MM-DD` date). Mermaid's positional task parser strips a
28
+ // leading status keyword (`done`/`active`/`crit`/`milestone`) and then reads
29
+ // the remaining comma fields as `[start, duration]` (2 fields) or
30
+ // `[id, start, duration]` (3 fields). A task that named an id but omitted the
31
+ // start (`:done, my-id, 2w`) collapses to two fields after the status strip,
32
+ // so Mermaid mis-reads the id as a start date and throws `Invalid date: my-id`
33
+ // at render time. To keep an explicit id we therefore MUST emit a start token:
34
+ // - declared `after:` deps -> `after <ids>`
35
+ // - otherwise a lane follower -> `after <previous item in the lane>`
36
+ // - otherwise a lane/track leader -> the roadmap start date
37
+ // This mirrors Nowline's default "each item starts after the preceding item in
38
+ // its lane" semantics (specs/rendering.md § Item Bars).
25
39
 
26
40
  import type {
27
41
  AnchorDeclaration,
@@ -71,9 +85,19 @@ function emptyCounts(): DropCounts {
71
85
  };
72
86
  }
73
87
 
88
+ /**
89
+ * Mutable per-lane chaining cursor. `prevId` is the id the NEXT sequential
90
+ * task should start after; `null` means "anchor at the roadmap start date"
91
+ * (lane / parallel-track leader).
92
+ */
93
+ interface Chain {
94
+ prevId: string | null;
95
+ }
96
+
74
97
  export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}): string {
75
98
  const ast = inputs.ast;
76
99
  const title = roadmapTitle(ast.roadmapDecl ?? undefined);
100
+ const startDate = resolveStartDate(inputs);
77
101
  const drops = emptyCounts();
78
102
 
79
103
  const out: string[] = [];
@@ -94,17 +118,11 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
94
118
  if (anchors.length > 0) {
95
119
  out.push(' section Anchors');
96
120
  for (const anchor of anchors) {
97
- const date = getProp(anchor, 'date');
121
+ // Anchors are date markers; fall back to the roadmap start when an
122
+ // anchor omits `date:` so Mermaid always sees a valid start token.
123
+ const date = getProp(anchor, 'date') ?? startDate;
98
124
  const id = anchor.name ?? slugify(displayLabel(anchor));
99
- if (date) {
100
- out.push(
101
- ` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`,
102
- );
103
- } else {
104
- out.push(
105
- ` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, after , 0d`,
106
- );
107
- }
125
+ out.push(` ${escapeTaskName(displayLabel(anchor))} :milestone, ${id}, ${date}, 0d`);
108
126
  }
109
127
  }
110
128
 
@@ -113,7 +131,7 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
113
131
  (e): e is SwimlaneDeclaration => e.$type === 'SwimlaneDeclaration',
114
132
  );
115
133
  for (const lane of swimlanes) {
116
- emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out);
134
+ emitSwimlane(lane, [lane.name ?? slugify(displayLabel(lane))], drops, out, startDate);
117
135
  }
118
136
 
119
137
  // Top-level milestones.
@@ -123,7 +141,7 @@ export function exportMermaid(inputs: ExportInputs, options: MermaidOptions = {}
123
141
  if (milestones.length > 0) {
124
142
  out.push(' section Milestones');
125
143
  for (const m of milestones) {
126
- emitMilestone(m, drops, out);
144
+ emitMilestone(m, drops, out, startDate);
127
145
  }
128
146
  }
129
147
 
@@ -145,11 +163,15 @@ function emitSwimlane(
145
163
  breadcrumb: readonly string[],
146
164
  drops: DropCounts,
147
165
  out: string[],
166
+ startDate: string,
148
167
  ): void {
149
168
  const sectionLabel = breadcrumb.join('.');
150
169
  out.push(` section ${escapeMermaidText(sectionLabel)}`);
170
+ // Each lane starts its own sequential chain; the first non-`after` item
171
+ // anchors at the roadmap start date.
172
+ const chain: Chain = { prevId: null };
151
173
  for (const child of lane.content) {
152
- emitSwimlaneChild(child, breadcrumb, drops, out);
174
+ emitSwimlaneChild(child, breadcrumb, drops, out, chain, startDate);
153
175
  }
154
176
  // Nested swimlanes — count for the lossy report.
155
177
  // SwimlaneContent doesn't include nested swimlanes per the grammar, so
@@ -162,19 +184,21 @@ function emitSwimlaneChild(
162
184
  breadcrumb: readonly string[],
163
185
  drops: DropCounts,
164
186
  out: string[],
187
+ chain: Chain,
188
+ startDate: string,
165
189
  ): void {
166
190
  if (child.$type === 'ItemDeclaration') {
167
- emitItem(child, drops, out);
191
+ emitItem(child, drops, out, chain, startDate);
168
192
  return;
169
193
  }
170
194
  if (child.$type === 'GroupBlock') {
171
195
  drops.group += 1;
172
- emitGroup(child, breadcrumb, drops, out);
196
+ emitGroup(child, breadcrumb, drops, out, chain, startDate);
173
197
  return;
174
198
  }
175
199
  if (child.$type === 'ParallelBlock') {
176
200
  drops.parallel += 1;
177
- emitParallel(child, breadcrumb, drops, out);
201
+ emitParallel(child, breadcrumb, drops, out, chain, startDate);
178
202
  return;
179
203
  }
180
204
  if (child.$type === 'DescriptionDirective') {
@@ -188,16 +212,20 @@ function emitGroup(
188
212
  breadcrumb: readonly string[],
189
213
  drops: DropCounts,
190
214
  out: string[],
215
+ chain: Chain,
216
+ startDate: string,
191
217
  ): void {
218
+ // A group is a visual container within a lane — its items continue the
219
+ // lane's sequential chain.
192
220
  for (const child of group.content as GroupContent[]) {
193
221
  if (child.$type === 'ItemDeclaration') {
194
- emitItem(child, drops, out);
222
+ emitItem(child, drops, out, chain, startDate);
195
223
  } else if (child.$type === 'GroupBlock') {
196
224
  drops.group += 1;
197
- emitGroup(child, breadcrumb, drops, out);
225
+ emitGroup(child, breadcrumb, drops, out, chain, startDate);
198
226
  } else if (child.$type === 'ParallelBlock') {
199
227
  drops.parallel += 1;
200
- emitParallel(child, breadcrumb, drops, out);
228
+ emitParallel(child, breadcrumb, drops, out, chain, startDate);
201
229
  } else if (child.$type === 'DescriptionDirective') {
202
230
  drops.description += 1;
203
231
  }
@@ -209,51 +237,106 @@ function emitParallel(
209
237
  breadcrumb: readonly string[],
210
238
  drops: DropCounts,
211
239
  out: string[],
240
+ chain: Chain,
241
+ startDate: string,
212
242
  ): void {
243
+ // Tracks run concurrently: each starts from the parallel's entry point
244
+ // (the lane cursor as it was on entry), not after the previous track.
245
+ const entryId = chain.prevId;
246
+ let lastTrackEnd = entryId;
213
247
  for (const child of parallel.content) {
214
248
  if (child.$type === 'ItemDeclaration') {
215
- emitItem(child, drops, out);
249
+ const trackChain: Chain = { prevId: entryId };
250
+ emitItem(child, drops, out, trackChain, startDate);
251
+ lastTrackEnd = trackChain.prevId;
216
252
  } else if (child.$type === 'GroupBlock') {
217
253
  drops.group += 1;
218
- emitGroup(child, breadcrumb, drops, out);
254
+ const trackChain: Chain = { prevId: entryId };
255
+ emitGroup(child, breadcrumb, drops, out, trackChain, startDate);
256
+ lastTrackEnd = trackChain.prevId;
219
257
  } else if (child.$type === 'DescriptionDirective') {
220
258
  drops.description += 1;
221
259
  }
222
260
  }
261
+ // After the block, the lane continues from the last track (lossy — Mermaid
262
+ // can't express "after the latest of N tracks").
263
+ chain.prevId = lastTrackEnd;
223
264
  }
224
265
 
225
- function emitItem(item: ItemDeclaration, drops: DropCounts, out: string[]): void {
266
+ function emitItem(
267
+ item: ItemDeclaration,
268
+ drops: DropCounts,
269
+ out: string[],
270
+ chain: Chain,
271
+ startDate: string,
272
+ ): void {
226
273
  countDrops(item, drops);
227
274
  const id = item.name ?? slugify(displayLabel(item));
228
275
  const status = mapStatus(getProp(item, 'status'));
229
276
  const after = getProps(item, 'after');
230
277
  const duration = durationToMermaid(getProp(item, 'duration') ?? getProp(item, 'size')) ?? '1d';
231
- const _ref = after.length > 0 ? `after ${after.join(' ')}` : 'after , 0d'.replace(', 0d', '');
278
+ const start = startTokenFor(after, chain, startDate);
232
279
 
233
- const meta = [status, id, after.length > 0 ? `after ${after.join(' ')}` : '', duration]
234
- .filter((s) => s !== '')
235
- .join(', ');
280
+ const meta = [status, id, start, duration].filter((s) => s !== '').join(', ');
236
281
  out.push(` ${escapeTaskName(displayLabel(item))} :${meta}`);
282
+ // Advance the lane cursor so the next sequential item chains after this one.
283
+ chain.prevId = id;
237
284
  }
238
285
 
239
- function emitMilestone(milestone: MilestoneDeclaration, drops: DropCounts, out: string[]): void {
286
+ function emitMilestone(
287
+ milestone: MilestoneDeclaration,
288
+ drops: DropCounts,
289
+ out: string[],
290
+ startDate: string,
291
+ ): void {
240
292
  const id = milestone.name ?? slugify(displayLabel(milestone));
241
293
  const date = getProp(milestone, 'date');
294
+ const after = getProps(milestone, 'after');
295
+ let start: string;
242
296
  if (date) {
243
- out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${date}, 0d`);
297
+ start = date;
298
+ } else if (after.length > 0) {
299
+ start = `after ${after.join(' ')}`;
244
300
  } else {
245
- const after = getProps(milestone, 'depends');
246
- if (after.length > 0) {
247
- out.push(
248
- ` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, after ${after.join(' ')}, 0d`,
249
- );
250
- } else {
251
- out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, 0d`);
252
- }
301
+ // A milestone with neither a date nor predecessors still needs a start
302
+ // token; anchor it at the roadmap start so Mermaid renders it.
303
+ start = startDate;
253
304
  }
305
+ out.push(` ${escapeTaskName(displayLabel(milestone))} :milestone, ${id}, ${start}, 0d`);
254
306
  if (hasProp(milestone, 'style')) drops.style += 1;
255
307
  }
256
308
 
309
+ /**
310
+ * Start token for a task: declared `after:` deps win, otherwise chain after the
311
+ * previous item in the lane, otherwise anchor the lane/track leader at the
312
+ * roadmap start date. Always non-empty so Mermaid never mis-reads the task id
313
+ * as a start date.
314
+ */
315
+ function startTokenFor(after: readonly string[], chain: Chain, startDate: string): string {
316
+ if (after.length > 0) return `after ${after.join(' ')}`;
317
+ if (chain.prevId) return `after ${chain.prevId}`;
318
+ return startDate;
319
+ }
320
+
321
+ /**
322
+ * Absolute anchor date (`YYYY-MM-DD`) for lane leaders. Prefers the roadmap's
323
+ * declared `start:`, falling back to the layout-computed timeline start (always
324
+ * present) so the export renders even when the source omits `start:`.
325
+ */
326
+ function resolveStartDate(inputs: ExportInputs): string {
327
+ const decl = inputs.ast.roadmapDecl;
328
+ const declared = decl ? getProp(decl, 'start') : undefined;
329
+ if (declared && /^\d{4}-\d{2}-\d{2}$/.test(declared.trim())) return declared.trim();
330
+ return formatIsoDate(inputs.model.timeline.startDate);
331
+ }
332
+
333
+ function formatIsoDate(d: Date): string {
334
+ const y = d.getUTCFullYear();
335
+ const m = String(d.getUTCMonth() + 1).padStart(2, '0');
336
+ const day = String(d.getUTCDate()).padStart(2, '0');
337
+ return `${y}-${m}-${day}`;
338
+ }
339
+
257
340
  function countDrops(item: ItemDeclaration, drops: DropCounts): void {
258
341
  if (getProps(item, 'labels').length > 0) drops.labels += 1;
259
342
  if (hasProp(item, 'remaining')) drops.remaining += 1;