@rasensio/aidlc 1.29.2 → 1.31.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.
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +12 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +13 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/compile/question-rendering.d.ts +83 -0
- package/dist/compile/question-rendering.d.ts.map +1 -0
- package/dist/compile/question-rendering.js +177 -0
- package/dist/compile/question-rendering.js.map +1 -0
- package/dist/compile/roadmap-skill.d.ts +7 -1
- package/dist/compile/roadmap-skill.d.ts.map +1 -1
- package/dist/compile/roadmap-skill.js +86 -5
- package/dist/compile/roadmap-skill.js.map +1 -1
- package/dist/doctor/migrations/index.d.ts.map +1 -1
- package/dist/doctor/migrations/index.js +8 -0
- package/dist/doctor/migrations/index.js.map +1 -1
- package/dist/doctor/migrations/roadmap-item-fields.d.ts +81 -0
- package/dist/doctor/migrations/roadmap-item-fields.d.ts.map +1 -0
- package/dist/doctor/migrations/roadmap-item-fields.js +174 -0
- package/dist/doctor/migrations/roadmap-item-fields.js.map +1 -0
- package/dist/doctor/migrations/roadmap-layout.d.ts +8 -1
- package/dist/doctor/migrations/roadmap-layout.d.ts.map +1 -1
- package/dist/doctor/migrations/roadmap-layout.js +15 -3
- package/dist/doctor/migrations/roadmap-layout.js.map +1 -1
- package/dist/roadmap/item-fields.d.ts +157 -0
- package/dist/roadmap/item-fields.d.ts.map +1 -0
- package/dist/roadmap/item-fields.js +259 -0
- package/dist/roadmap/item-fields.js.map +1 -0
- package/dist/roadmap/sync/import.d.ts.map +1 -1
- package/dist/roadmap/sync/import.js +13 -2
- package/dist/roadmap/sync/import.js.map +1 -1
- package/package.json +2 -2
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
38
38
|
import { join } from 'node:path';
|
|
39
|
+
import { itemFieldsOrEmpty, renderFieldDefault, renderFieldLines, } from '../roadmap/item-fields.js';
|
|
40
|
+
import { primaryCheckout } from '../roadmap/paths.js';
|
|
39
41
|
/** Directory name of the skill, shared by source and target. */
|
|
40
42
|
const SKILL_DIR = 'roadmap-item';
|
|
41
43
|
/** Path segments below the content package root. */
|
|
@@ -46,6 +48,73 @@ const TARGET_SEGMENTS = ['.aidlc', 'resources', 'skills', SKILL_DIR, 'SKILL.md']
|
|
|
46
48
|
export const ROADMAP_SKILL_PATH = TARGET_SEGMENTS.join('/');
|
|
47
49
|
/** The token the source carries in place of a version literal. */
|
|
48
50
|
const VERSION_PLACEHOLDER = '{{version}}';
|
|
51
|
+
/**
|
|
52
|
+
* The two project-field placeholders, each occupying a **whole line** of the source.
|
|
53
|
+
*
|
|
54
|
+
* Whole-line, not inline, and that is what makes a project declaring nothing get a
|
|
55
|
+
* byte-identical file to the one before this feature existed
|
|
56
|
+
* (item-extension-fields/AC-10): the line is *deleted*, not substituted with an
|
|
57
|
+
* empty string, so no stray blank line survives. An inline token could not manage
|
|
58
|
+
* that, and byte-identity is the only version of "behaves exactly as today" that
|
|
59
|
+
* can be asserted rather than eyeballed.
|
|
60
|
+
*/
|
|
61
|
+
const FIELDS_PLACEHOLDER = '{{project_item_fields}}';
|
|
62
|
+
const FIELDS_RULE_PLACEHOLDER = '{{project_item_fields_rule}}';
|
|
63
|
+
/**
|
|
64
|
+
* The rule as it reads when the project has declared nothing.
|
|
65
|
+
*
|
|
66
|
+
* Byte-for-byte the wording the source carried before this feature, because AC-10
|
|
67
|
+
* is asserted against the committed emitted file.
|
|
68
|
+
*/
|
|
69
|
+
const ABSOLUTE_RULE = [
|
|
70
|
+
'- Do not add any other field, and do not add a `status` field. Status is recorded by which',
|
|
71
|
+
' folder the file sits in, not inside the file.',
|
|
72
|
+
];
|
|
73
|
+
/**
|
|
74
|
+
* The rule as it reads when the project has declared fields.
|
|
75
|
+
*
|
|
76
|
+
* The absolute "do not add any other field" is what made the framework's own
|
|
77
|
+
* instruction and a project's own gate jointly unsatisfiable, so it becomes a
|
|
78
|
+
* bounded rule rather than being dropped (AC-8). The `status` prohibition stays
|
|
79
|
+
* absolute in both renderings — that one is not a schema choice, it is the layout.
|
|
80
|
+
*
|
|
81
|
+
* Each field states its required-ness and default (AC-9) so an agent that cannot
|
|
82
|
+
* read the project's config still knows what to write. The agent loading this skill
|
|
83
|
+
* usually has no checkout at all, which is the entire reason the skill is portable.
|
|
84
|
+
*/
|
|
85
|
+
function projectRule(fields) {
|
|
86
|
+
const lines = [
|
|
87
|
+
'- Add no field beyond the template above — which already includes the fields this project',
|
|
88
|
+
' has declared — and never add a `status` field. Status is recorded by which folder the',
|
|
89
|
+
' file sits in, not inside the file.',
|
|
90
|
+
"- This project's own declared fields, which the template above already carries:",
|
|
91
|
+
];
|
|
92
|
+
for (const field of fields) {
|
|
93
|
+
lines.push(` - \`${field.name}\` — ${field.required ? 'required, include it even when empty' : 'optional'}; ` +
|
|
94
|
+
`write \`${renderFieldDefault(field.default)}\` if you have nothing better.`);
|
|
95
|
+
}
|
|
96
|
+
lines.push(' The project checks that these are present and of the right shape. What goes *in* them is', " the project's own business — if you do not know, write the default and say so.");
|
|
97
|
+
return lines;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Replace a whole-line placeholder with a block, or delete the line when the block
|
|
101
|
+
* is empty.
|
|
102
|
+
*
|
|
103
|
+
* Operates on lines rather than on the raw string so "delete the line" means
|
|
104
|
+
* exactly that, including its newline.
|
|
105
|
+
*/
|
|
106
|
+
function substituteLine(text, placeholder, block) {
|
|
107
|
+
const lines = text.split('\n');
|
|
108
|
+
const out = [];
|
|
109
|
+
for (const line of lines) {
|
|
110
|
+
if (line.trim() !== placeholder) {
|
|
111
|
+
out.push(line);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
out.push(...block);
|
|
115
|
+
}
|
|
116
|
+
return out.join('\n');
|
|
117
|
+
}
|
|
49
118
|
/**
|
|
50
119
|
* Ownership notice written into the emitted file.
|
|
51
120
|
*
|
|
@@ -63,9 +132,11 @@ const OWNERSHIP_MARKER = '<!-- aidlc:generated — framework-owned. Edits are ov
|
|
|
63
132
|
*
|
|
64
133
|
* @param source - Raw source template contents.
|
|
65
134
|
* @param version - Version to stamp, e.g. `1.12.0`.
|
|
135
|
+
* @param fields - The project's declared item fields; empty for the stock template.
|
|
66
136
|
*/
|
|
67
|
-
export function renderRoadmapSkill(source, version) {
|
|
68
|
-
const
|
|
137
|
+
export function renderRoadmapSkill(source, version, fields = []) {
|
|
138
|
+
const withFields = substituteLine(substituteLine(source, FIELDS_PLACEHOLDER, renderFieldLines(fields)), FIELDS_RULE_PLACEHOLDER, fields.length > 0 ? projectRule(fields) : ABSOLUTE_RULE);
|
|
139
|
+
const stamped = withFields.split(VERSION_PLACEHOLDER).join(version);
|
|
69
140
|
// Insert the marker after the frontmatter's closing fence. A source without
|
|
70
141
|
// frontmatter is not something we produce, but degrading to "prepend nothing"
|
|
71
142
|
// beats emitting a file whose first bytes are a comment.
|
|
@@ -85,6 +156,9 @@ export function renderRoadmapSkill(source, version) {
|
|
|
85
156
|
* rather than read here so tests can pin it and this module needs no opinion
|
|
86
157
|
* about where a package manifest lives.
|
|
87
158
|
* @param opts.dryRun - Compute the report without writing.
|
|
159
|
+
* @param opts.fields - Declared item fields, overriding what the project's config
|
|
160
|
+
* says. A test seam: rendering is the thing worth asserting, and threading a
|
|
161
|
+
* config file through a temp directory to assert it would test the reader twice.
|
|
88
162
|
*/
|
|
89
163
|
export function installRoadmapSkill(projectRoot, contentRoot, version, opts = {}) {
|
|
90
164
|
const source = join(contentRoot, ...SOURCE_SEGMENTS);
|
|
@@ -95,13 +169,20 @@ export function installRoadmapSkill(projectRoot, contentRoot, version, opts = {}
|
|
|
95
169
|
warnings: [`the content package ships no roadmap authoring skill at ${source}`],
|
|
96
170
|
};
|
|
97
171
|
}
|
|
98
|
-
|
|
172
|
+
// Declared fields come from the PRIMARY checkout, never this working tree: items
|
|
173
|
+
// and their schema are one fact, so a feature branch must not be able to change
|
|
174
|
+
// what a colleague's items are validated against (AC-3).
|
|
175
|
+
const declared = opts.fields !== undefined
|
|
176
|
+
? { fields: opts.fields, warning: null }
|
|
177
|
+
: itemFieldsOrEmpty(primaryCheckout(projectRoot));
|
|
178
|
+
const warnings = declared.warning === null ? [] : [declared.warning];
|
|
179
|
+
const rendered = renderRoadmapSkill(readFileSync(source, 'utf8'), version, declared.fields);
|
|
99
180
|
const target = join(projectRoot, ...TARGET_SEGMENTS);
|
|
100
181
|
const existed = existsSync(target);
|
|
101
182
|
// Skipping an identical write keeps output deterministic and stops `update`
|
|
102
183
|
// from producing a diff on every run.
|
|
103
184
|
if (existed && readFileSync(target, 'utf8') === rendered) {
|
|
104
|
-
return { path: null, status: 'already-current', warnings
|
|
185
|
+
return { path: null, status: 'already-current', warnings };
|
|
105
186
|
}
|
|
106
187
|
if (!opts.dryRun) {
|
|
107
188
|
mkdirSync(join(projectRoot, ...TARGET_SEGMENTS.slice(0, -1)), { recursive: true });
|
|
@@ -110,7 +191,7 @@ export function installRoadmapSkill(projectRoot, contentRoot, version, opts = {}
|
|
|
110
191
|
return {
|
|
111
192
|
path: ROADMAP_SKILL_PATH,
|
|
112
193
|
status: existed ? 'updated' : 'installed',
|
|
113
|
-
warnings
|
|
194
|
+
warnings,
|
|
114
195
|
};
|
|
115
196
|
}
|
|
116
197
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roadmap-skill.js","sourceRoot":"","sources":["../../src/compile/roadmap-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,gEAAgE;AAChE,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC,oDAAoD;AACpD,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAEhF,4CAA4C;AAC5C,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAE1F,mDAAmD;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE5D,kEAAkE;AAClE,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,gBAAgB,GACpB,sFAAsF,CAAC;AAUzF
|
|
1
|
+
{"version":3,"file":"roadmap-skill.js","sourceRoot":"","sources":["../../src/compile/roadmap-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,gEAAgE;AAChE,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC,oDAAoD;AACpD,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAEhF,4CAA4C;AAC5C,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAE1F,mDAAmD;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE5D,kEAAkE;AAClE,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AACrD,MAAM,uBAAuB,GAAG,8BAA8B,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,aAAa,GAAG;IACpB,4FAA4F;IAC5F,iDAAiD;CAClD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,SAAS,WAAW,CAAC,MAAgC;IACnD,MAAM,KAAK,GAAG;QACZ,2FAA2F;QAC3F,yFAAyF;QACzF,sCAAsC;QACtC,iFAAiF;KAClF,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CACR,SAAS,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,UAAU,IAAI;YACjG,WAAW,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,gCAAgC,CAC/E,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CACR,4FAA4F,EAC5F,kFAAkF,CACnF,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,WAAmB,EAAE,KAAwB;IACjF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,WAAW,EAAE,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,gBAAgB,GACpB,sFAAsF,CAAC;AAUzF;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,OAAe,EACf,SAAmC,EAAE;IAErC,MAAM,UAAU,GAAG,cAAc,CAC/B,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,EACpE,uBAAuB,EACvB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CACxD,CAAC;IACF,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEpE,4EAA4E;IAC5E,8EAA8E;IAC9E,yDAAyD;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;IACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,gBAAgB,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAAmB,EACnB,WAAmB,EACnB,OAAe,EACf,OAAgE,EAAE;IAElE,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,eAAe,CAAC,CAAC;IAErD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,gBAAgB;YACxB,QAAQ,EAAE,CAAC,2DAA2D,MAAM,EAAE,CAAC;SAChF,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,gFAAgF;IAChF,yDAAyD;IACzD,MAAM,QAAQ,GACZ,IAAI,CAAC,MAAM,KAAK,SAAS;QACvB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QACxC,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAErE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,eAAe,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnC,4EAA4E;IAC5E,sCAAsC;IACtC,IAAI,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QACzD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;QACzC,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA0B;IAC9D,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,WAAW;YACd,OAAO,yCAAyC,kBAAkB,EAAE,CAAC;QACvE,KAAK,SAAS;YACZ,OAAO,uCAAuC,kBAAkB,EAAE,CAAC;QACrE;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAkC7C,eAAO,MAAM,UAAU,EAAE,SAAS,EA6FjC,CAAC"}
|
|
@@ -23,6 +23,7 @@ import { trustRunActions } from './trust-run-actions.js';
|
|
|
23
23
|
import { staleIdeaSkill } from './stale-idea-skill.js';
|
|
24
24
|
import { roadmapLayout } from './roadmap-layout.js';
|
|
25
25
|
import { roadmapItemTitles } from './roadmap-item-titles.js';
|
|
26
|
+
import { roadmapItemFields } from './roadmap-item-fields.js';
|
|
26
27
|
import { instanceCompletion } from './instance-completion.js';
|
|
27
28
|
import { findingsFilenameMigration } from './findings-filename.js';
|
|
28
29
|
import { roadmapSyncGhMissing } from './roadmap-sync-gh-missing.js';
|
|
@@ -47,6 +48,13 @@ export const MIGRATIONS = [
|
|
|
47
48
|
// an item that will not parse. Repairing titles between the two means one
|
|
48
49
|
// doctor run both creates the item and can see it.
|
|
49
50
|
roadmapItemTitles,
|
|
51
|
+
// Ordered after roadmap-item-titles, load-bearing: an item whose frontmatter will
|
|
52
|
+
// not parse cannot be checked for a declared field, and this migration skips those
|
|
53
|
+
// in silence rather than reporting the same file twice. Quoting titles first means
|
|
54
|
+
// one doctor run both makes an item readable and backfills its declared fields.
|
|
55
|
+
// After roadmap-layout for the same reason — the legacy rewrite creates the items
|
|
56
|
+
// this then validates (item-extension-fields/AC-15).
|
|
57
|
+
roadmapItemFields,
|
|
50
58
|
// Ordered after roadmap-layout: that migration creates the status directories
|
|
51
59
|
// and can itself place an item in `in-progress/` for an instance that has
|
|
52
60
|
// since completed, which is exactly what this one then moves to `done/`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,CAAC,MAAM,UAAU,GAAgB;IACrC,aAAa;IACb,kBAAkB;IAClB,aAAa;IACb,cAAc;IACd,eAAe;IACf,4EAA4E;IAC5E,2EAA2E;IAC3E,8EAA8E;IAC9E,cAAc;IACd,aAAa;IACb,0EAA0E;IAC1E,qEAAqE;IACrE,+EAA+E;IAC/E,0EAA0E;IAC1E,mDAAmD;IACnD,iBAAiB;IACjB,8EAA8E;IAC9E,0EAA0E;IAC1E,yEAAyE;IACzE,kBAAkB;IAClB,8EAA8E;IAC9E,iFAAiF;IACjF,kFAAkF;IAClF,+EAA+E;IAC/E,gFAAgF;IAChF,oBAAoB;IACpB,yBAAyB;IACzB,qFAAqF;IACrF,uFAAuF;IACvF,8EAA8E;IAC9E,oBAAoB;IACpB,mBAAmB;IACnB,iBAAiB;IACjB,cAAc;IACd,wBAAwB;IACxB,aAAa;IACb,kBAAkB;IAClB,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,eAAe;IACf,eAAe;IACf,gFAAgF;IAChF,iEAAiE;IACjE,iBAAiB;IACjB,yEAAyE;IACzE,0EAA0E;IAC1E,eAAe;IACf,sFAAsF;IACtF,sFAAsF;IACtF,qFAAqF;IACrF,uDAAuD;IACvD,EAAE;IACF,iFAAiF;IACjF,qFAAqF;IACrF,wFAAwF;IACxF,gDAAgD;IAChD,wFAAwF;IACxF,mFAAmF;IACnF,iFAAiF;IACjF,wBAAwB;IACxB,0BAA0B;IAC1B,0BAA0B;IAC1B,sBAAsB;IACtB,iFAAiF;IACjF,qDAAqD;IACrD,uBAAuB;IACvB,sFAAsF;IACtF,oFAAoF;IACpF,uFAAuF;IACvF,uFAAuF;IACvF,oEAAoE;IACpE,qBAAqB;IACrB,gFAAgF;IAChF,kFAAkF;IAClF,+EAA+E;IAC/E,6CAA6C;IAC7C,8CAA8C;IAC9C,EAAE;IACF,6EAA6E;IAC7E,6EAA6E;IAC7E,iFAAiF;IACjF,sBAAsB;IACtB,mBAAmB;IACnB,eAAe;CAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/migrations/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* roadmap-item-fields migration (confirm tier): backfill a project-declared item
|
|
3
|
+
* field that an item is missing, and report one whose value is the wrong shape.
|
|
4
|
+
*
|
|
5
|
+
* Requirements: item-extension-fields/AC-15, AC-16, AC-18, AC-19, AC-20
|
|
6
|
+
*
|
|
7
|
+
* Declaring a field is cheap; retrofitting it across a roadmap that already holds
|
|
8
|
+
* fifty items is not. Without a backfill, `roadmap.item_fields` would report fifty
|
|
9
|
+
* problems on the day it was added and offer no way to act on any of them — the
|
|
10
|
+
* shape of gate this project has learned to distrust.
|
|
11
|
+
*
|
|
12
|
+
* The line between what this repairs and what it only reports is the same line the
|
|
13
|
+
* feature draws everywhere: **presence, never contents.**
|
|
14
|
+
*
|
|
15
|
+
* - A *missing* required field is repaired by writing the value the project itself
|
|
16
|
+
* declared as the default. That is presence repair with the project's own answer,
|
|
17
|
+
* not a semantic judgment, so it stays inside the boundary AC-17 sets.
|
|
18
|
+
* - A *wrong-shaped* value is reported and never rewritten. Wrapping a scalar in a
|
|
19
|
+
* list to make it fit would be the confident-wrong-fix `roadmap-item-titles`
|
|
20
|
+
* already refuses, and only the person who wrote the value knows what they meant.
|
|
21
|
+
*
|
|
22
|
+
* Wrong shapes and an invalid declaration are both reported as NOT APPLICABLE
|
|
23
|
+
* rather than pending, following `roadmap-item-titles` exactly: `aidlc doctor`
|
|
24
|
+
* exits 1 on pending confirm work, so calling a condition `apply` will never fix
|
|
25
|
+
* "pending" fails doctor forever on a repo holding one such item, which trains
|
|
26
|
+
* people to ignore doctor output. `not-applicable` still prints the detail, which
|
|
27
|
+
* is the entire point.
|
|
28
|
+
*
|
|
29
|
+
* Items whose frontmatter will not parse are skipped in silence. They are
|
|
30
|
+
* `roadmap-item-titles`' condition, that migration is registered ahead of this one,
|
|
31
|
+
* and reporting the same file from two migrations would double every line without
|
|
32
|
+
* adding a fact.
|
|
33
|
+
*
|
|
34
|
+
* Confirm tier, because this edits the user's own content — the reason
|
|
35
|
+
* `roadmap-layout` and `roadmap-item-titles` are confirm tier too. `check` and
|
|
36
|
+
* `apply` both derive everything from `planItemFields` and nothing else computes
|
|
37
|
+
* pending-ness, the rule `../types.ts` states, so a dry run and a real run cannot
|
|
38
|
+
* disagree.
|
|
39
|
+
*/
|
|
40
|
+
import type { DoctorContext, Migration } from '../types.js';
|
|
41
|
+
import { type ItemFieldDecl, type ShapeMismatch } from '../../roadmap/item-fields.js';
|
|
42
|
+
/** One item with fields to add, and the rewritten contents that add them. */
|
|
43
|
+
export interface FieldBackfill {
|
|
44
|
+
/** `<status>/<filename>` — the form used in doctor output. */
|
|
45
|
+
label: string;
|
|
46
|
+
file: string;
|
|
47
|
+
fields: ItemFieldDecl[];
|
|
48
|
+
contents: string;
|
|
49
|
+
}
|
|
50
|
+
/** One item carrying a declared field of the wrong shape. */
|
|
51
|
+
export interface FieldShapeReport {
|
|
52
|
+
label: string;
|
|
53
|
+
mismatches: ShapeMismatch[];
|
|
54
|
+
}
|
|
55
|
+
export interface ItemFieldsPlan {
|
|
56
|
+
/** Null when the project declares nothing; a message when its declaration is wrong. */
|
|
57
|
+
notApplicable: string | null;
|
|
58
|
+
backfills: FieldBackfill[];
|
|
59
|
+
shapes: FieldShapeReport[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Insert `name: <default>` lines at the **end** of an item's frontmatter block.
|
|
63
|
+
*
|
|
64
|
+
* End-of-block rather than "after `history`", deliberately. `history` is a block
|
|
65
|
+
* list whose extent has to be walked, and `writeHistoryEntry` appends to it — a key
|
|
66
|
+
* inserted between the `history:` line and its last entry would be swallowed into
|
|
67
|
+
* the list on the next move. End-of-block is unambiguous, needs no walk, and is
|
|
68
|
+
* where `writeHistoryEntry` itself puts a `history` key when none exists.
|
|
69
|
+
*
|
|
70
|
+
* @returns The rewritten contents, or null when there is no frontmatter to edit.
|
|
71
|
+
*/
|
|
72
|
+
export declare function insertFields(raw: string, fields: readonly ItemFieldDecl[]): string | null;
|
|
73
|
+
/**
|
|
74
|
+
* Everything the migration would do, computed without writing.
|
|
75
|
+
*
|
|
76
|
+
* The single source of pending-ness. Items are walked in status order and then
|
|
77
|
+
* filename order, so the plan never depends on directory read order.
|
|
78
|
+
*/
|
|
79
|
+
export declare function planItemFields(ctx: DoctorContext): ItemFieldsPlan;
|
|
80
|
+
export declare const roadmapItemFields: Migration;
|
|
81
|
+
//# sourceMappingURL=roadmap-item-fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap-item-fields.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-item-fields.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAIH,OAAO,KAAK,EAAe,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQzE,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,uFAAuF;IACvF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,GAAG,IAAI,CAUzF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAwCjE;AA8BD,eAAO,MAAM,iBAAiB,EAAE,SAkD/B,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* roadmap-item-fields migration (confirm tier): backfill a project-declared item
|
|
3
|
+
* field that an item is missing, and report one whose value is the wrong shape.
|
|
4
|
+
*
|
|
5
|
+
* Requirements: item-extension-fields/AC-15, AC-16, AC-18, AC-19, AC-20
|
|
6
|
+
*
|
|
7
|
+
* Declaring a field is cheap; retrofitting it across a roadmap that already holds
|
|
8
|
+
* fifty items is not. Without a backfill, `roadmap.item_fields` would report fifty
|
|
9
|
+
* problems on the day it was added and offer no way to act on any of them — the
|
|
10
|
+
* shape of gate this project has learned to distrust.
|
|
11
|
+
*
|
|
12
|
+
* The line between what this repairs and what it only reports is the same line the
|
|
13
|
+
* feature draws everywhere: **presence, never contents.**
|
|
14
|
+
*
|
|
15
|
+
* - A *missing* required field is repaired by writing the value the project itself
|
|
16
|
+
* declared as the default. That is presence repair with the project's own answer,
|
|
17
|
+
* not a semantic judgment, so it stays inside the boundary AC-17 sets.
|
|
18
|
+
* - A *wrong-shaped* value is reported and never rewritten. Wrapping a scalar in a
|
|
19
|
+
* list to make it fit would be the confident-wrong-fix `roadmap-item-titles`
|
|
20
|
+
* already refuses, and only the person who wrote the value knows what they meant.
|
|
21
|
+
*
|
|
22
|
+
* Wrong shapes and an invalid declaration are both reported as NOT APPLICABLE
|
|
23
|
+
* rather than pending, following `roadmap-item-titles` exactly: `aidlc doctor`
|
|
24
|
+
* exits 1 on pending confirm work, so calling a condition `apply` will never fix
|
|
25
|
+
* "pending" fails doctor forever on a repo holding one such item, which trains
|
|
26
|
+
* people to ignore doctor output. `not-applicable` still prints the detail, which
|
|
27
|
+
* is the entire point.
|
|
28
|
+
*
|
|
29
|
+
* Items whose frontmatter will not parse are skipped in silence. They are
|
|
30
|
+
* `roadmap-item-titles`' condition, that migration is registered ahead of this one,
|
|
31
|
+
* and reporting the same file from two migrations would double every line without
|
|
32
|
+
* adding a fact.
|
|
33
|
+
*
|
|
34
|
+
* Confirm tier, because this edits the user's own content — the reason
|
|
35
|
+
* `roadmap-layout` and `roadmap-item-titles` are confirm tier too. `check` and
|
|
36
|
+
* `apply` both derive everything from `planItemFields` and nothing else computes
|
|
37
|
+
* pending-ness, the rule `../types.ts` states, so a dry run and a real run cannot
|
|
38
|
+
* disagree.
|
|
39
|
+
*/
|
|
40
|
+
import { writeFileSync } from 'node:fs';
|
|
41
|
+
import { relative } from 'node:path';
|
|
42
|
+
import { ROADMAP_STATUSES, frontmatter, listStatus, primaryCheckout, } from '../../roadmap/paths.js';
|
|
43
|
+
import { checkItemFrontmatter, readItemFields, renderFieldDefault, } from '../../roadmap/item-fields.js';
|
|
44
|
+
/**
|
|
45
|
+
* Insert `name: <default>` lines at the **end** of an item's frontmatter block.
|
|
46
|
+
*
|
|
47
|
+
* End-of-block rather than "after `history`", deliberately. `history` is a block
|
|
48
|
+
* list whose extent has to be walked, and `writeHistoryEntry` appends to it — a key
|
|
49
|
+
* inserted between the `history:` line and its last entry would be swallowed into
|
|
50
|
+
* the list on the next move. End-of-block is unambiguous, needs no walk, and is
|
|
51
|
+
* where `writeHistoryEntry` itself puts a `history` key when none exists.
|
|
52
|
+
*
|
|
53
|
+
* @returns The rewritten contents, or null when there is no frontmatter to edit.
|
|
54
|
+
*/
|
|
55
|
+
export function insertFields(raw, fields) {
|
|
56
|
+
const fm = frontmatter(raw);
|
|
57
|
+
if (fm === null)
|
|
58
|
+
return null;
|
|
59
|
+
if (fields.length === 0)
|
|
60
|
+
return raw;
|
|
61
|
+
const lines = fm.text.split('\n');
|
|
62
|
+
// `fm.text` ends with the newline before the closing `---`, so splitting leaves a
|
|
63
|
+
// trailing empty element; the insert goes immediately before it.
|
|
64
|
+
lines.splice(lines.length - 1, 0, ...fields.map((f) => `${f.name}: ${renderFieldDefault(f.default)}`));
|
|
65
|
+
return `${raw.slice(0, fm.start)}${lines.join('\n')}${raw.slice(fm.end)}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Everything the migration would do, computed without writing.
|
|
69
|
+
*
|
|
70
|
+
* The single source of pending-ness. Items are walked in status order and then
|
|
71
|
+
* filename order, so the plan never depends on directory read order.
|
|
72
|
+
*/
|
|
73
|
+
export function planItemFields(ctx) {
|
|
74
|
+
const empty = { notApplicable: null, backfills: [], shapes: [] };
|
|
75
|
+
// The schema is the primary checkout's: items and the rules they are checked
|
|
76
|
+
// against are one fact, so a feature branch must not change what a colleague's
|
|
77
|
+
// items are validated against (AC-3).
|
|
78
|
+
const declared = readItemFields(primaryCheckout(ctx.projectRoot));
|
|
79
|
+
if (declared.kind === 'not-configured')
|
|
80
|
+
return empty;
|
|
81
|
+
if (declared.kind === 'invalid') {
|
|
82
|
+
return { ...empty, notApplicable: `roadmap.item_fields is not usable: ${declared.error}` };
|
|
83
|
+
}
|
|
84
|
+
const fields = declared.fields;
|
|
85
|
+
if (fields.length === 0)
|
|
86
|
+
return empty;
|
|
87
|
+
const backfills = [];
|
|
88
|
+
const shapes = [];
|
|
89
|
+
for (const status of ROADMAP_STATUSES) {
|
|
90
|
+
for (const item of listStatus(ctx.projectRoot, status)) {
|
|
91
|
+
const fm = frontmatter(item.raw);
|
|
92
|
+
// Unparseable frontmatter is roadmap-item-titles' condition, and `listStatus`
|
|
93
|
+
// has already dropped those; this is the belt for the braces.
|
|
94
|
+
if (fm === null)
|
|
95
|
+
continue;
|
|
96
|
+
const { missing, mismatched } = checkItemFrontmatter(fm.data, fields);
|
|
97
|
+
const label = itemLabel(item);
|
|
98
|
+
if (missing.length > 0) {
|
|
99
|
+
const contents = insertFields(item.raw, missing);
|
|
100
|
+
if (contents !== null) {
|
|
101
|
+
backfills.push({ label, file: item.file, fields: missing, contents });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (mismatched.length > 0) {
|
|
105
|
+
shapes.push({ label, mismatches: mismatched });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { notApplicable: null, backfills, shapes };
|
|
110
|
+
}
|
|
111
|
+
function itemLabel(item) {
|
|
112
|
+
return `${item.status}/${item.filename}`;
|
|
113
|
+
}
|
|
114
|
+
/** One-line summary shared by `check` and `apply`. */
|
|
115
|
+
function describe(plan, verb) {
|
|
116
|
+
const named = plan.backfills
|
|
117
|
+
.map((b) => `${b.label} (${b.fields.map((f) => f.name).join(', ')})`)
|
|
118
|
+
.join('; ');
|
|
119
|
+
const count = plan.backfills.reduce((n, b) => n + b.fields.length, 0);
|
|
120
|
+
const suffix = plan.shapes.length > 0
|
|
121
|
+
? `; ${plan.shapes.length} item(s) carry a declared field of the wrong shape and need a human: ${describeShapes(plan)}`
|
|
122
|
+
: '';
|
|
123
|
+
return `${verb} ${count} declared field value(s) to ${plan.backfills.length} roadmap item(s): ${named}${suffix}`;
|
|
124
|
+
}
|
|
125
|
+
function describeShapes(plan) {
|
|
126
|
+
return plan.shapes
|
|
127
|
+
.map((s) => `${s.label} — ${s.mismatches
|
|
128
|
+
.map((m) => `${m.field.name} is ${m.found}, declared as ${m.expected}`)
|
|
129
|
+
.join(', ')}`)
|
|
130
|
+
.join('; ');
|
|
131
|
+
}
|
|
132
|
+
export const roadmapItemFields = {
|
|
133
|
+
id: 'roadmap-item-fields',
|
|
134
|
+
tier: 'confirm',
|
|
135
|
+
check(ctx) {
|
|
136
|
+
const plan = planItemFields(ctx);
|
|
137
|
+
if (plan.notApplicable !== null) {
|
|
138
|
+
return { applicable: false, reason: plan.notApplicable };
|
|
139
|
+
}
|
|
140
|
+
if (plan.backfills.length === 0) {
|
|
141
|
+
if (plan.shapes.length > 0) {
|
|
142
|
+
return {
|
|
143
|
+
applicable: false,
|
|
144
|
+
reason: `${plan.shapes.length} roadmap item(s) carry a project-declared field of the wrong ` +
|
|
145
|
+
'shape. The framework checks presence and shape only, so it will not rewrite a value ' +
|
|
146
|
+
`somebody chose — a human must: ${describeShapes(plan)}`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return { applicable: true, pending: false };
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
applicable: true,
|
|
153
|
+
pending: true,
|
|
154
|
+
description: describe(plan, 'would add'),
|
|
155
|
+
// No shell equivalent: this is an in-place insert into a frontmatter block,
|
|
156
|
+
// not a move. Listing the files and fields is the honest version of "the
|
|
157
|
+
// exact commands".
|
|
158
|
+
commands: plan.backfills.map((b) => `edit ${relative(ctx.projectRoot, b.file)} — add ${b.fields
|
|
159
|
+
.map((f) => `${f.name}: ${renderFieldDefault(f.default)}`)
|
|
160
|
+
.join(', ')}`),
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
apply(ctx) {
|
|
164
|
+
const plan = planItemFields(ctx);
|
|
165
|
+
for (const backfill of plan.backfills) {
|
|
166
|
+
writeFileSync(backfill.file, backfill.contents, 'utf8');
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
changed: plan.backfills.length > 0,
|
|
170
|
+
summary: plan.backfills.length > 0 ? describe(plan, 'added') : 'no declared fields to add',
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=roadmap-item-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadmap-item-fields.js","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-item-fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { Migration } from '../types.js';
|
|
26
26
|
import type { DoctorContext } from '../types.js';
|
|
27
|
+
import { type ItemFieldDecl } from '../../roadmap/item-fields.js';
|
|
27
28
|
import { type RoadmapStatus } from '../../roadmap/paths.js';
|
|
28
29
|
/** One planned relocation, with everything `apply` needs to carry it out. */
|
|
29
30
|
export interface RoadmapMove {
|
|
@@ -57,8 +58,14 @@ export interface RoadmapPlan {
|
|
|
57
58
|
* `author` is deliberately omitted rather than guessed. The legacy format never
|
|
58
59
|
* recorded one, and `created_by` from an unrelated instance is not the author of
|
|
59
60
|
* an idea.
|
|
61
|
+
*
|
|
62
|
+
* Project-declared fields (item-extension-fields/AC-14) are appended with their
|
|
63
|
+
* declared defaults. Legacy ideas predate extension fields by definition, so
|
|
64
|
+
* without this a project that has declared a field and then migrates its old inbox
|
|
65
|
+
* ends up with a directory of items its own check rejects — the migration
|
|
66
|
+
* manufacturing the very failure the feature exists to remove.
|
|
60
67
|
*/
|
|
61
|
-
export declare function rewriteFrontmatter(raw: string, filename: string, status: RoadmapStatus): {
|
|
68
|
+
export declare function rewriteFrontmatter(raw: string, filename: string, status: RoadmapStatus, fields?: readonly ItemFieldDecl[]): {
|
|
62
69
|
contents: string;
|
|
63
70
|
id: string;
|
|
64
71
|
} | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roadmap-layout.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,
|
|
1
|
+
{"version":3,"file":"roadmap-layout.d.ts","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAuC,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AACvG,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAEhC,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,yEAAyE;IACzE,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAsBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE,SAAS,aAAa,EAAO,GACpC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqDzC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,CAuEhE;AASD,eAAO,MAAM,aAAa,EAAE,SA8G3B,CAAC"}
|
|
@@ -28,7 +28,8 @@ import { basename, dirname, join } from 'node:path';
|
|
|
28
28
|
import { parse as parseYaml } from 'yaml';
|
|
29
29
|
import { trackedFiles } from '../git.js';
|
|
30
30
|
import { completionInfo, loadAllTemplates, loadInstance } from '../../metrics/report.js';
|
|
31
|
-
import {
|
|
31
|
+
import { itemFieldsOrEmpty, renderFieldLines } from '../../roadmap/item-fields.js';
|
|
32
|
+
import { ITEM_FILENAME_RE, LEGACY_IDEAS_DIR, ROADMAP_DIR, primaryCheckout, } from '../../roadmap/paths.js';
|
|
32
33
|
/** Map a legacy `status:` value onto a roadmap directory. */
|
|
33
34
|
function targetStatus(legacy, promotedTo, ctx, templates) {
|
|
34
35
|
if (legacy === 'raw')
|
|
@@ -57,8 +58,14 @@ function targetStatus(legacy, promotedTo, ctx, templates) {
|
|
|
57
58
|
* `author` is deliberately omitted rather than guessed. The legacy format never
|
|
58
59
|
* recorded one, and `created_by` from an unrelated instance is not the author of
|
|
59
60
|
* an idea.
|
|
61
|
+
*
|
|
62
|
+
* Project-declared fields (item-extension-fields/AC-14) are appended with their
|
|
63
|
+
* declared defaults. Legacy ideas predate extension fields by definition, so
|
|
64
|
+
* without this a project that has declared a field and then migrates its old inbox
|
|
65
|
+
* ends up with a directory of items its own check rejects — the migration
|
|
66
|
+
* manufacturing the very failure the feature exists to remove.
|
|
60
67
|
*/
|
|
61
|
-
export function rewriteFrontmatter(raw, filename, status) {
|
|
68
|
+
export function rewriteFrontmatter(raw, filename, status, fields = []) {
|
|
62
69
|
const nameMatch = ITEM_FILENAME_RE.exec(filename);
|
|
63
70
|
if (!nameMatch)
|
|
64
71
|
return null;
|
|
@@ -105,6 +112,7 @@ export function rewriteFrontmatter(raw, filename, status) {
|
|
|
105
112
|
`depends_on: [${deps.join(', ')}]`,
|
|
106
113
|
'history:',
|
|
107
114
|
` - { status: ${status}, at: ${createdAt} }`,
|
|
115
|
+
...renderFieldLines(fields),
|
|
108
116
|
'---',
|
|
109
117
|
];
|
|
110
118
|
return { contents: `${lines.join('\n')}\n${body}`, id };
|
|
@@ -121,6 +129,10 @@ export function planRoadmapMoves(ctx) {
|
|
|
121
129
|
return { moves: [], unclassified: [] };
|
|
122
130
|
const templates = loadAllTemplates(ctx.projectRoot);
|
|
123
131
|
const tracked = new Set(trackedFiles(ctx.projectRoot, [LEGACY_IDEAS_DIR]));
|
|
132
|
+
// Legacy ideas live in `.aidlc/ideas/` of this checkout, but the schema is the
|
|
133
|
+
// primary checkout's — `primaryCheckout` of a primary checkout is itself, so the
|
|
134
|
+
// ordinary case is unaffected.
|
|
135
|
+
const declaredFields = itemFieldsOrEmpty(primaryCheckout(ctx.projectRoot)).fields;
|
|
124
136
|
const moves = [];
|
|
125
137
|
const unclassified = [];
|
|
126
138
|
for (const name of readdirSync(legacyDir).sort()) {
|
|
@@ -155,7 +167,7 @@ export function planRoadmapMoves(ctx) {
|
|
|
155
167
|
unclassified.push(fromRel);
|
|
156
168
|
continue;
|
|
157
169
|
}
|
|
158
|
-
const rewritten = rewriteFrontmatter(raw, name, status);
|
|
170
|
+
const rewritten = rewriteFrontmatter(raw, name, status, declaredFields);
|
|
159
171
|
if (rewritten === null) {
|
|
160
172
|
unclassified.push(fromRel);
|
|
161
173
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roadmap-layout.js","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,
|
|
1
|
+
{"version":3,"file":"roadmap-layout.js","sourceRoot":"","sources":["../../../src/doctor/migrations/roadmap-layout.ts"],"names":[],"mappings":"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"}
|