@rasensio/aidlc 1.21.0 → 1.23.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.
Files changed (63) hide show
  1. package/dist/commands/roadmap.d.ts.map +1 -1
  2. package/dist/commands/roadmap.js +19 -1
  3. package/dist/commands/roadmap.js.map +1 -1
  4. package/dist/commands/start.d.ts.map +1 -1
  5. package/dist/commands/start.js +31 -1
  6. package/dist/commands/start.js.map +1 -1
  7. package/dist/concurrency/common-dir.d.ts +13 -0
  8. package/dist/concurrency/common-dir.d.ts.map +1 -1
  9. package/dist/concurrency/common-dir.js +17 -1
  10. package/dist/concurrency/common-dir.js.map +1 -1
  11. package/dist/concurrency/detect.d.ts +28 -1
  12. package/dist/concurrency/detect.d.ts.map +1 -1
  13. package/dist/concurrency/detect.js +69 -5
  14. package/dist/concurrency/detect.js.map +1 -1
  15. package/dist/concurrency/types.d.ts +20 -0
  16. package/dist/concurrency/types.d.ts.map +1 -1
  17. package/dist/events/event-bus.d.ts +2 -0
  18. package/dist/events/event-bus.d.ts.map +1 -1
  19. package/dist/events/event-bus.js +76 -9
  20. package/dist/events/event-bus.js.map +1 -1
  21. package/dist/roadmap/paths.d.ts +99 -3
  22. package/dist/roadmap/paths.d.ts.map +1 -1
  23. package/dist/roadmap/paths.js +144 -17
  24. package/dist/roadmap/paths.js.map +1 -1
  25. package/dist/roadmap/sync/body.d.ts +109 -23
  26. package/dist/roadmap/sync/body.d.ts.map +1 -1
  27. package/dist/roadmap/sync/body.js +260 -23
  28. package/dist/roadmap/sync/body.js.map +1 -1
  29. package/dist/roadmap/sync/collect.d.ts +9 -0
  30. package/dist/roadmap/sync/collect.d.ts.map +1 -1
  31. package/dist/roadmap/sync/collect.js +48 -3
  32. package/dist/roadmap/sync/collect.js.map +1 -1
  33. package/dist/roadmap/sync/execute.d.ts.map +1 -1
  34. package/dist/roadmap/sync/execute.js +12 -2
  35. package/dist/roadmap/sync/execute.js.map +1 -1
  36. package/dist/roadmap/sync/gh.d.ts +10 -0
  37. package/dist/roadmap/sync/gh.d.ts.map +1 -1
  38. package/dist/roadmap/sync/gh.js +24 -0
  39. package/dist/roadmap/sync/gh.js.map +1 -1
  40. package/dist/roadmap/sync/markdown.d.ts +79 -0
  41. package/dist/roadmap/sync/markdown.d.ts.map +1 -0
  42. package/dist/roadmap/sync/markdown.js +165 -0
  43. package/dist/roadmap/sync/markdown.js.map +1 -0
  44. package/dist/roadmap/sync/marker.d.ts +10 -1
  45. package/dist/roadmap/sync/marker.d.ts.map +1 -1
  46. package/dist/roadmap/sync/marker.js +16 -1
  47. package/dist/roadmap/sync/marker.js.map +1 -1
  48. package/dist/roadmap/sync/plan.d.ts +7 -0
  49. package/dist/roadmap/sync/plan.d.ts.map +1 -1
  50. package/dist/roadmap/sync/plan.js +22 -4
  51. package/dist/roadmap/sync/plan.js.map +1 -1
  52. package/dist/roadmap/sync/render.d.ts.map +1 -1
  53. package/dist/roadmap/sync/render.js +2 -0
  54. package/dist/roadmap/sync/render.js.map +1 -1
  55. package/dist/roadmap/sync/sanitize.d.ts +56 -0
  56. package/dist/roadmap/sync/sanitize.d.ts.map +1 -0
  57. package/dist/roadmap/sync/sanitize.js +140 -0
  58. package/dist/roadmap/sync/sanitize.js.map +1 -0
  59. package/dist/roadmap/sync/types.d.ts +30 -2
  60. package/dist/roadmap/sync/types.d.ts.map +1 -1
  61. package/dist/roadmap/sync/types.js +9 -2
  62. package/dist/roadmap/sync/types.js.map +1 -1
  63. package/package.json +2 -2
@@ -1,39 +1,209 @@
1
1
  /**
2
- * The body of a created issue.
2
+ * The body of a projected issue.
3
3
  *
4
- * Generated, fixed-shape, and carrying **no item prose except through the title** —
5
- * which lives in the issue title, not here. That is a deliberate narrowing, and it
6
- * closes three problems with one decision:
4
+ * v1.21.0 emitted a fixed six-line notice carrying no item prose at all, on the grounds
5
+ * that projecting prose risked marker injection, mention notifications, and the 65,536
6
+ * character field limit. The hazards were real; the conclusion was not. What shipped was a
7
+ * redirect — thirty issues on a board with thirty copies of one paragraph, unreadable to
8
+ * exactly the person the feature was for: somebody triaging in the tracker who will not
9
+ * clone the repository. `richer-issue-bodies` answers all three hazards instead of avoiding
10
+ * them: `sanitize.ts` neutralises comments and autolink triggers code-awarely, and the
11
+ * budget below bounds the field.
7
12
  *
8
- * - **Marker injection.** An item that merely *quotes* a marker — this feature's own
9
- * requirements document does — would put a second marker into a different issue, making
10
- * the id→issue map ambiguous enough to retitle or close the wrong issue.
11
- * - **Notification side effects.** Item prose containing `@name` or `#123` sends
12
- * notifications and creates cross-links the moment it is published, which is the class
13
- * of harm the per-status eligibility rule exists to prevent.
14
- * - **Field limits.** GitHub caps bodies at 65,536 characters. A generated body is
15
- * bounded by construction, so no truncation logic exists to get wrong.
13
+ * Two structural decisions carry the rest of the design.
16
14
  *
17
- * The alternative considered was projecting each item's Executive Summary with
18
- * marker-shaped and mention-shaped spans neutralised. Rejected: neutralising `@` and `#`
19
- * mangles legitimate text, and "which spans are dangerous" becomes a judgement somebody
20
- * has to maintain. A reader who wants the detail follows the link.
15
+ * **The region is delimited, and everything outside it is somebody else's.** A body is
16
+ * regenerated on every sync, so it must be possible to say precisely which bytes the
17
+ * projection owns. Text before `BODY_BEGIN` or after `BODY_END` survives untouched, which
18
+ * is what makes a projected issue still usable as a tracker: a reader can add a note to the
19
+ * description and keep it.
21
20
  *
22
- * The body is never rewritten after creation. Comments are the reason to have a tracker
23
- * at all, and an update that replaced the body would delete the context around them.
21
+ * **The body is rewritten, not written once.** v1.21.0 froze it at creation, reasoning that
22
+ * an update "would delete the context around [comments]". That does not hold — GitHub issue
23
+ * comments are separate entities from the body, and a body edit keeps its own revision
24
+ * history — and the cost of freezing is that every issue created before this change stays
25
+ * thin forever while every later item edit makes its issue quietly wrong. The rejected
26
+ * alternative was a one-off migration command; this project has a recorded lesson that a
27
+ * capability needing a manual post-deploy command will be un-run.
24
28
  *
25
- * Requirements: roadmap-issue-projection/AC-23, roadmap-issue-projection/AC-47
29
+ * Nothing volatile may enter this module's output. A timestamp, a commit sha or a metric
30
+ * would make the rendered region differ from the stored one on every single run, so every
31
+ * item would plan `update-body` forever and the projection would never converge — the same
32
+ * defect class as `discover.ts`'s labels-are-objects bug. That is why the region is a pure
33
+ * function of the item and the repository coordinates, and why a test pins that this file
34
+ * imports neither `node:fs` nor `node:child_process`.
35
+ *
36
+ * Requirements: richer-issue-bodies/AC-1 … richer-issue-bodies/AC-4,
37
+ * richer-issue-bodies/AC-6, richer-issue-bodies/AC-7, richer-issue-bodies/AC-16,
38
+ * richer-issue-bodies/AC-17, richer-issue-bodies/AC-21 … richer-issue-bodies/AC-24,
39
+ * richer-issue-bodies/AC-28
26
40
  *
27
41
  * @module
28
42
  */
43
+ import { lastProseBreakBefore } from './markdown.js';
29
44
  import { renderMarker } from './marker.js';
45
+ import { sanitizeItemBody } from './sanitize.js';
46
+ /** Start of the projection-owned region. */
47
+ export const BODY_BEGIN = '<!-- aidlc-body:begin -->';
48
+ /** End of the projection-owned region. */
49
+ export const BODY_END = '<!-- aidlc-body:end -->';
50
+ /**
51
+ * The ceiling this module will not cross.
52
+ *
53
+ * GitHub's own limit is 65,536. The margin is not decoration: the largest real item in this
54
+ * project's roadmap is 44,481 characters, so nothing today comes close, and the headroom is
55
+ * what keeps a future item from failing a write *after* consent was given — the one moment
56
+ * in the projection where a failure is expensive.
57
+ */
58
+ export const MAX_BODY_LENGTH = 60_000;
59
+ /**
60
+ * A permalink to a file on the default branch.
61
+ *
62
+ * `blob/HEAD/` rather than a resolved branch name, and this was measured rather than
63
+ * reasoned: on 2026-09-07, `github.com/cli/cli/blob/HEAD/README.md` returned 200 while
64
+ * `blob/main/README.md` returned 404, because that repository's default branch is `trunk`.
65
+ * Hardcoding `main` would ship broken links to every project that renamed its default
66
+ * branch. `HEAD` also needs no extra `gh` call and puts no remote state in the body.
67
+ */
68
+ export function fileUrlFor(repo, relPath) {
69
+ return `https://github.com/${repo.owner}/${repo.name}/blob/HEAD/${relPath}`;
70
+ }
71
+ /** The context's URL builder, or null when coordinates are unknown. */
72
+ function urlBuilder(ctx) {
73
+ const { repo } = ctx;
74
+ return repo === null ? null : (relPath) => fileUrlFor(repo, relPath);
75
+ }
76
+ /**
77
+ * The projection-owned region, delimiters included.
78
+ *
79
+ * Facts first, because a triager reads the top of a body the way they read the top of an
80
+ * item. The marker sits *inside* the region, so replacing the region can never orphan or
81
+ * duplicate it.
82
+ */
83
+ export function renderGeneratedRegion(item, ctx) {
84
+ const url = urlBuilder(ctx);
85
+ // Assemble around a prose slot, so the fixed cost is measured rather than estimated.
86
+ const assemble = (prose) => [
87
+ BODY_BEGIN,
88
+ '',
89
+ renderFacts(item, ctx, url),
90
+ '',
91
+ '---',
92
+ '',
93
+ prose,
94
+ '',
95
+ '---',
96
+ '',
97
+ renderFooter(),
98
+ '',
99
+ renderMarker(item.id),
100
+ BODY_END,
101
+ // No trailing newline. `extractRegion` ends AT `BODY_END`, so a region that ended one
102
+ // byte later would never compare equal to the one read back off an issue — every item
103
+ // would plan `update-body` on every run and the projection would never converge. The
104
+ // convergence test is what caught it; the two functions have to agree byte for byte.
105
+ ].join('\n');
106
+ // Trimmed: an item body starts with the newline that followed its closing `---`, and the
107
+ // assembly already puts blank lines around the prose slot. Without this the region renders
108
+ // with a double blank line above the first heading — visible in the first real sample,
109
+ // invisible in every fixture, which is why generated prose gets read as rendered output.
110
+ const sanitized = sanitizeItemBody(item.body, { itemPaths: ctx.itemPaths, fileUrl: url }).trim();
111
+ return assemble(fitProse(sanitized, item, url, assemble('').length));
112
+ }
113
+ /**
114
+ * The facts block.
115
+ *
116
+ * `not recorded` for a key the frontmatter does not carry — an admitted gap a reader can
117
+ * tell apart from a real value, which an empty cell cannot. `promoted_to` is the one
118
+ * exception: absent and explicitly `null` both mean the same thing there, and *not
119
+ * promoted* is what that means.
120
+ */
121
+ function renderFacts(item, ctx, url) {
122
+ const { facts } = item;
123
+ const value = (v) => (v === null ? '_not recorded_' : v);
124
+ const depends = facts.dependsOn.length === 0
125
+ ? '_none_'
126
+ : facts.dependsOn.map((id) => renderItemRef(id, ctx, url)).join(', ');
127
+ const filePath = url === null ? `\`${item.relPath}\`` : `[${item.relPath}](${url(item.relPath)})`;
128
+ // A bullet list, not backslash hard breaks: it survives any renderer, and a screen
129
+ // reader announces four labelled facts rather than one run-on paragraph.
130
+ return [
131
+ `- **Status:** \`${item.status}\``,
132
+ `- **Created:** ${value(facts.createdAt)}`,
133
+ `- **Author:** ${value(facts.author)}`,
134
+ `- **Source:** ${value(facts.source)}`,
135
+ `- **Depends on:** ${depends}`,
136
+ `- **Promoted to:** ${facts.promotedTo === null ? '_not promoted_' : `\`${facts.promotedTo}\``}`,
137
+ `- **Roadmap file:** ${filePath}`,
138
+ ].join('\n');
139
+ }
140
+ /** One `depends_on` entry: a link when the item exists, a named gap when it does not. */
141
+ function renderItemRef(id, ctx, url) {
142
+ const relPath = ctx.itemPaths.get(id);
143
+ if (relPath === undefined)
144
+ return `\`${id}\` (no such item)`;
145
+ if (url === null)
146
+ return `\`${id}\``;
147
+ return `[\`${id}\`](${url(relPath)})`;
148
+ }
149
+ /** The standing explanation, identical on every issue. */
150
+ function renderFooter() {
151
+ return [
152
+ 'Projected from this repository’s AIDLC roadmap by `aidlc roadmap sync`. The roadmap',
153
+ 'file named above is the source of truth — edit it there. This region is regenerated on',
154
+ 'every sync; anything written outside it is preserved. Comments are never copied back',
155
+ 'into the repository.',
156
+ ].join('\n');
157
+ }
30
158
  /**
31
- * Render the body for a newly created issue.
159
+ * Fit sanitized prose inside the remaining budget.
32
160
  *
33
- * Ends with the marker on its own line. That is a creation-time shape only — matching
34
- * never depends on it (see `marker.ts`).
161
+ * The cut point is the last newline before the budget that sits in **prose**, which is what
162
+ * stops truncation leaving a fence open — a body ending mid-fence renders everything after
163
+ * it as one code block. When no safe break exists the prose is dropped entirely rather than
164
+ * cut mid-construct, and the notice says so; that case cannot arise from any real item
165
+ * today and a silent hard slice would be the worse failure if it ever did.
35
166
  */
36
- export function renderIssueBody(item) {
167
+ function fitProse(prose, item, url, fixedLength) {
168
+ const budget = MAX_BODY_LENGTH - fixedLength;
169
+ if (prose.length <= budget)
170
+ return prose;
171
+ const link = url === null ? `\`${item.relPath}\`` : `[${item.relPath}](${url(item.relPath)})`;
172
+ // Reserve room for the notice itself, which is why the break is sought below a reduced
173
+ // limit rather than at the budget.
174
+ const notice = (omitted) => `\n_… ${omitted.toLocaleString('en-US')} further characters are not shown. Read the whole item at ${link}._`;
175
+ const reserve = notice(prose.length).length;
176
+ const cut = lastProseBreakBefore(prose, Math.max(0, budget - reserve));
177
+ if (cut === -1)
178
+ return notice(prose.length).trimStart();
179
+ return prose.slice(0, cut) + notice(prose.length - cut);
180
+ }
181
+ /**
182
+ * The region bytes of an existing body, or null when it carries no region.
183
+ *
184
+ * Delimiters included, so the value can be compared directly against
185
+ * `renderGeneratedRegion`'s output — comparing the insides would let a delimiter change go
186
+ * undetected.
187
+ */
188
+ export function extractRegion(body) {
189
+ const start = body.indexOf(BODY_BEGIN);
190
+ if (start === -1)
191
+ return null;
192
+ const end = body.indexOf(BODY_END, start);
193
+ if (end === -1)
194
+ return null;
195
+ return body.slice(start, end + BODY_END.length);
196
+ }
197
+ /**
198
+ * v1.21.0's body, reproduced exactly.
199
+ *
200
+ * **Frozen history, not a template.** Its only job is to be recognised so it can be
201
+ * replaced, so it must keep emitting the bytes v1.21.0 emitted even as the real renderer
202
+ * changes. A test pins it as a literal for that reason: edit it and issues created before
203
+ * this change stop being recognised, and every one of them gains a new region below a stale
204
+ * notice instead of replacing it.
205
+ */
206
+ export function renderLegacyIssueBody(item) {
37
207
  return [
38
208
  'Projected from this repository’s AIDLC roadmap.',
39
209
  '',
@@ -49,4 +219,71 @@ export function renderIssueBody(item) {
49
219
  '',
50
220
  ].join('\n');
51
221
  }
222
+ /**
223
+ * The body to write: a fresh region merged into whatever the issue already has.
224
+ *
225
+ * Four cases, first match wins:
226
+ *
227
+ * 1. **Both delimiters present** — replace the span between them and keep everything else.
228
+ * This is the steady state, and the reason a human's note survives a sync.
229
+ * 2. **Exactly the legacy notice** — the region alone. An issue created by v1.21.0 stops
230
+ * being thin.
231
+ * 3. **Legacy notice plus other text** — replace only the recognised notice. Whatever
232
+ * somebody added stays.
233
+ * 4. **Anything else** — append the region below the existing body, after stripping any
234
+ * marker naming *this* item, so the body ends up with exactly one.
235
+ *
236
+ * Case 4 deliberately leaves markers naming *other* ids alone. Those are the ambiguity
237
+ * `indexByMarker` exists to refuse, and quietly deleting one would hide a genuine
238
+ * two-issue collision rather than resolve it.
239
+ */
240
+ export function mergeBody(existing, region, itemId) {
241
+ const start = existing.indexOf(BODY_BEGIN);
242
+ if (start !== -1) {
243
+ const end = existing.indexOf(BODY_END, start);
244
+ if (end !== -1) {
245
+ return existing.slice(0, start) + region + existing.slice(end + BODY_END.length);
246
+ }
247
+ }
248
+ const legacy = legacyNoticeFor(itemId, existing);
249
+ if (legacy !== null) {
250
+ if (existing === legacy)
251
+ return region;
252
+ const at = existing.indexOf(legacy);
253
+ if (at !== -1)
254
+ return existing.slice(0, at) + region + existing.slice(at + legacy.length);
255
+ }
256
+ const kept = stripOwnMarkers(existing, itemId).trimEnd();
257
+ return kept.length === 0 ? region : `${kept}\n\n${region}`;
258
+ }
259
+ /**
260
+ * The legacy notice for this item, if the body contains one.
261
+ *
262
+ * `renderLegacyIssueBody` needs a whole `ProjectableItem`, but a merge only knows the id
263
+ * and the body. The file path is recoverable from the notice itself, which is the one place
264
+ * v1.21.0 recorded it — so the notice is rebuilt from what it claims rather than from what
265
+ * the item currently says. That matters: an item that has since moved between statuses has
266
+ * a different `relPath` today, and rebuilding from the item would fail to match its own
267
+ * issue.
268
+ */
269
+ function legacyNoticeFor(itemId, existing) {
270
+ const match = /- \*\*File:\*\* `([^`\n]+)`/.exec(existing);
271
+ if (match === null)
272
+ return null;
273
+ return renderLegacyIssueBody({
274
+ id: itemId,
275
+ relPath: match[1],
276
+ // Unused by the legacy renderer; present only to satisfy the shape.
277
+ title: '',
278
+ status: 'backlog',
279
+ filename: '',
280
+ body: '',
281
+ facts: { createdAt: null, author: null, source: null, promotedTo: null, dependsOn: [] },
282
+ });
283
+ }
284
+ /** Remove markers naming this item, leaving markers for other ids in place. */
285
+ function stripOwnMarkers(body, itemId) {
286
+ const escaped = itemId.replace(/[.*+?^${}()|[\]\\-]/g, '\\$&');
287
+ return body.replace(new RegExp(String.raw `<!--\s*aidlc-item:\s*${escaped}\s*-->\n?`, 'g'), '');
288
+ }
52
289
  //# sourceMappingURL=body.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"body.js","sourceRoot":"","sources":["../../../src/roadmap/sync/body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,OAAO;QACL,iDAAiD;QACjD,EAAE;QACF,iBAAiB,IAAI,CAAC,EAAE,IAAI;QAC5B,iBAAiB,IAAI,CAAC,OAAO,IAAI;QACjC,EAAE;QACF,oFAAoF;QACpF,mFAAmF;QACnF,kFAAkF;QAClF,6CAA6C;QAC7C,EAAE;QACF,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"body.js","sourceRoot":"","sources":["../../../src/roadmap/sync/body.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,15 @@ export interface Collected {
31
31
  root: string;
32
32
  items: readonly ProjectableItem[];
33
33
  unprojectable: readonly UnprojectableRef[];
34
+ /**
35
+ * Every item id → its repo-relative path, across **all five statuses**.
36
+ *
37
+ * Not restricted to the eligible ones. A `backlog` item routinely names the four `hold`
38
+ * items it supersedes, and those references are the most useful links in the body
39
+ * precisely because a reader cannot guess where a parked item went. Restricting this map
40
+ * to projected statuses would drop them silently.
41
+ */
42
+ itemPaths: ReadonlyMap<string, string>;
34
43
  }
35
44
  /**
36
45
  * A title for an item whose frontmatter has none.
@@ -1 +1 @@
1
- {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;IAClC,aAAa,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA2CnD"}
1
+ {"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAaH,OAAO,KAAK,EAAa,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;IAClC,aAAa,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC3C;;;;;;;OAOG;IACH,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAmDnD"}
@@ -25,7 +25,7 @@
25
25
  *
26
26
  * @module
27
27
  */
28
- import { ITEM_FILENAME_RE, ROADMAP_DIR, ROADMAP_STATUSES, listStatus, primaryCheckout, unparseableItems, } from '../paths.js';
28
+ import { ITEM_FILENAME_RE, ROADMAP_DIR, ROADMAP_STATUSES, frontmatter, itemBody, listStatus, primaryCheckout, unparseableItems, } from '../paths.js';
29
29
  /**
30
30
  * A title for an item whose frontmatter has none.
31
31
  *
@@ -43,6 +43,7 @@ export function collectItems(cwd) {
43
43
  const root = primaryCheckout(cwd);
44
44
  const items = [];
45
45
  const unprojectable = [];
46
+ const itemPaths = new Map();
46
47
  // Unparseable first, so its entries keep their own reasons rather than being
47
48
  // overwritten by the weaker "no id" classification below.
48
49
  const unparseableLabels = new Set();
@@ -69,16 +70,60 @@ export function collectItems(cwd) {
69
70
  });
70
71
  continue;
71
72
  }
73
+ const relPath = relPathOf(status, item.filename);
74
+ // First writer wins, matching `findByPromotedTo` and `indexByMarker`: a duplicate id
75
+ // is refused by `planProjection` anyway, so silently preferring one here cannot
76
+ // change an outcome — it only keeps this map from depending on directory order.
77
+ if (!itemPaths.has(item.id))
78
+ itemPaths.set(item.id, relPath);
72
79
  items.push({
73
80
  id: item.id,
74
81
  title: item.title ?? titleFromFilename(item.filename),
75
82
  status,
76
83
  filename: item.filename,
77
- relPath: relPathOf(status, item.filename),
84
+ relPath,
85
+ body: itemBody(item.raw),
86
+ facts: factsOf(item.raw),
78
87
  });
79
88
  }
80
89
  }
81
- return { root, items, unprojectable };
90
+ return { root, items, unprojectable, itemPaths };
91
+ }
92
+ /**
93
+ * The frontmatter facts, from the `raw` `readItem` already returned.
94
+ *
95
+ * No second disk read, and no second parse of the whole file: `readItem` keeps `raw`
96
+ * precisely so a caller can work from it. Every value is validated at this boundary and
97
+ * becomes `null` on anything unexpected — a wrong-typed `author` is a cosmetic gap, not a
98
+ * reason to make the whole item unprojectable, which is the same call the existing
99
+ * missing-`title` fallback already makes.
100
+ */
101
+ function factsOf(raw) {
102
+ const data = frontmatter(raw)?.data ?? {};
103
+ const str = (key) => {
104
+ const value = data[key];
105
+ if (typeof value === 'string' && value.trim().length > 0)
106
+ return value.trim();
107
+ // `created_at: 2026-09-05` parses as a Date under YAML 1.1 timestamp rules, so a
108
+ // string check alone would drop the one fact every item has.
109
+ if (value instanceof Date)
110
+ return value.toISOString().slice(0, 10);
111
+ return null;
112
+ };
113
+ const dependsOn = [];
114
+ if (Array.isArray(data.depends_on)) {
115
+ for (const entry of data.depends_on) {
116
+ if (typeof entry === 'string' && entry.trim().length > 0)
117
+ dependsOn.push(entry.trim());
118
+ }
119
+ }
120
+ return {
121
+ createdAt: str('created_at'),
122
+ author: str('author'),
123
+ source: str('source'),
124
+ promotedTo: str('promoted_to'),
125
+ dependsOn,
126
+ };
82
127
  }
83
128
  /**
84
129
  * Repo-relative path of an item, with forward slashes on every platform.
@@ -1 +1 @@
1
- {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AAUrB;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAElC,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,MAAM,aAAa,GAAuB,EAAE,CAAC;IAE7C,6EAA6E;IAC7E,0DAA0D;IAC1D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjC,aAAa,CAAC,IAAI,CAAC;YACjB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,aAAa;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,IAAI,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC3C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;gBACrB,aAAa,CAAC,IAAI,CAAC;oBACjB,KAAK;oBACL,MAAM;oBACN,GAAG,EAAE,YAAY;oBACjB,MAAM,EAAE,gCAAgC;iBACzC,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACrD,MAAM;gBACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,MAAqB,EAAE,QAAgB;IACxD,OAAO,GAAG,WAAW,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/roadmap/sync/collect.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAW,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,uFAAuF;IACvF,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,YAAY,EAAE,SAAS,QAAQ,EAAE,CAAC;CACnC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,UAAU,CAyBtF;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CA6C1F;AAyCD,6CAA6C;AAC7C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuB3D"}
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAW,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,uFAAuF;IACvF,OAAO,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,YAAY,EAAE,SAAS,QAAQ,EAAE,CAAC;CACnC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,UAAU,CAyBtF;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAqD1F;AAyCD,6CAA6C;AAC7C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuB3D"}
@@ -22,7 +22,6 @@
22
22
  *
23
23
  * @module
24
24
  */
25
- import { renderIssueBody } from './body.js';
26
25
  import { firstLine, repoArgs } from './gh.js';
27
26
  import { colorFor, descriptionFor } from './labels.js';
28
27
  import { isWrite } from './types.js';
@@ -55,6 +54,8 @@ export function invocationFor(plan, line, discoveryLabel) {
55
54
  case 'create': {
56
55
  if (line.item === null)
57
56
  throw new Error('create without an item');
57
+ if (line.newBody === null)
58
+ throw new Error('create without a rendered body');
58
59
  return [
59
60
  'issue',
60
61
  'create',
@@ -62,7 +63,7 @@ export function invocationFor(plan, line, discoveryLabel) {
62
63
  '--title',
63
64
  line.item.title,
64
65
  '--body',
65
- renderIssueBody(line.item),
66
+ line.newBody,
66
67
  '--label',
67
68
  discoveryLabel,
68
69
  ...line.addLabels.flatMap((l) => ['--label', l]),
@@ -88,6 +89,15 @@ export function invocationFor(plan, line, discoveryLabel) {
88
89
  ...line.removeLabels.flatMap((l) => ['--remove-label', l]),
89
90
  ];
90
91
  }
92
+ case 'update-body': {
93
+ if (line.issueNumber === null)
94
+ throw new Error('update-body without an issue');
95
+ if (line.newBody === null)
96
+ throw new Error('update-body without a body');
97
+ // The whole body, not a patch: `gh issue edit --body` replaces it, and the merge that
98
+ // preserved anything a human added already happened in the planner (design DD-6).
99
+ return ['issue', 'edit', String(line.issueNumber), ...repo, '--body', line.newBody];
100
+ }
91
101
  case 'close': {
92
102
  if (line.issueNumber === null)
93
103
  throw new Error('close without an issue');
@@ -1 +1 @@
1
- {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/roadmap/sync/execute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../src/roadmap/sync/execute.ts"],"names":[],"mappings":"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"}
@@ -61,4 +61,14 @@ export declare function ghPreflight(gh: GhRunner): {
61
61
  export declare function firstLine(text: string): string;
62
62
  /** `['--repo', repo]` when a coordinate was resolved, else `[]`. */
63
63
  export declare function repoArgs(repo: string | null): readonly string[];
64
+ /**
65
+ * Ask `gh` which repository the current directory belongs to.
66
+ *
67
+ * Only needed when `roadmap.sync.repo` is unset, and only so bodies can carry permalinks.
68
+ * A failure is **not** fatal: it yields null, and the projection continues with unlinked
69
+ * paths. Refusing to sync because a hyperlink could not be built would trade the feature's
70
+ * whole purpose for one of its conveniences, and the plan header already names the target,
71
+ * so a wrong repository stays visible either way.
72
+ */
73
+ export declare function resolveNameWithOwner(gh: GhRunner): string | null;
64
74
  //# sourceMappingURL=gh.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gh.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/gh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,MAAM,QAAQ,GAChB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAoB,CAAC;AAE/C,kEAAkE;AAClE,wBAAgB,YAAY,IAAI,QAAQ,CAkBvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CASrF;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,MAAM,EAAE,CAE/D"}
1
+ {"version":3,"file":"gh.d.ts","sourceRoot":"","sources":["../../../src/roadmap/sync/gh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,MAAM,QAAQ,GAChB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,QAAoB,CAAC;AAE/C,kEAAkE;AAClE,wBAAgB,YAAY,IAAI,QAAQ,CAkBvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CASrF;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,MAAM,EAAE,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAWhE"}
@@ -83,4 +83,28 @@ export function firstLine(text) {
83
83
  export function repoArgs(repo) {
84
84
  return repo === null ? [] : ['--repo', repo];
85
85
  }
86
+ /**
87
+ * Ask `gh` which repository the current directory belongs to.
88
+ *
89
+ * Only needed when `roadmap.sync.repo` is unset, and only so bodies can carry permalinks.
90
+ * A failure is **not** fatal: it yields null, and the projection continues with unlinked
91
+ * paths. Refusing to sync because a hyperlink could not be built would trade the feature's
92
+ * whole purpose for one of its conveniences, and the plan header already names the target,
93
+ * so a wrong repository stays visible either way.
94
+ */
95
+ export function resolveNameWithOwner(gh) {
96
+ const result = gh.run(['repo', 'view', '--json', 'nameWithOwner']);
97
+ if (!result.ok)
98
+ return null;
99
+ try {
100
+ const parsed = JSON.parse(result.stdout);
101
+ if (typeof parsed !== 'object' || parsed === null)
102
+ return null;
103
+ const value = parsed.nameWithOwner;
104
+ return typeof value === 'string' && value.length > 0 ? value : null;
105
+ }
106
+ catch {
107
+ return null;
108
+ }
109
+ }
86
110
  //# sourceMappingURL=gh.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gh.js","sourceRoot":"","sources":["../../../src/roadmap/sync/gh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAUlD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,kEAAkE;AAClE,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,GAAG,CAAC,IAAuB;YACzB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;oBAC3C,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;oBACjC,SAAS,EAAE,aAAa;iBACzB,CAAC,CAAC;gBACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC9B,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,GAA6E,CAAC;gBACxF,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACpF,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,sBAAsB,CAAC,CAAC,IAAI,EAAE,CAAC;gBACvE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YACnE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,EAAY;IACtC,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACnC,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EACH,4EAA4E;YAC5E,kDAAkD,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;KAC9E,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,QAAQ,CAAC,IAAmB;IAC1C,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"gh.js","sourceRoot":"","sources":["../../../src/roadmap/sync/gh.ts"],"names":[],"mappings":"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"}