@lumenflow/cli 3.11.1 → 3.12.1
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/README.md +30 -30
- package/dist/init-templates.js +0 -282
- package/dist/init-templates.js.map +1 -1
- package/dist/init.js +1 -1
- package/dist/initiative-create.js +2 -4
- package/dist/initiative-create.js.map +1 -1
- package/dist/lane-lifecycle-process.js +36 -81
- package/dist/lane-lifecycle-process.js.map +1 -1
- package/dist/lane-setup.js +3 -9
- package/dist/lane-setup.js.map +1 -1
- package/dist/lane-suggest.js +27 -31
- package/dist/lane-suggest.js.map +1 -1
- package/dist/lane-validate.js +1 -1
- package/dist/onboarding-smoke-test.js +25 -90
- package/dist/onboarding-smoke-test.js.map +1 -1
- package/dist/onboarding-template-paths.js +0 -1
- package/dist/onboarding-template-paths.js.map +1 -1
- package/dist/public-manifest.js +2 -2
- package/dist/public-manifest.js.map +1 -1
- package/package.json +8 -8
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +23 -22
- package/templates/core/ai/onboarding/starting-prompt.md.template +7 -6
- package/dist/init-lane-validation.js +0 -233
- package/dist/init-lane-validation.js.map +0 -1
- package/templates/core/ai/onboarding/lane-inference.md.template +0 -64
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
-
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
-
/**
|
|
4
|
-
* @file init-lane-validation.ts
|
|
5
|
-
* Lane config drift detection against inference taxonomy.
|
|
6
|
-
*
|
|
7
|
-
* WU-1745: Validate lane config against inference hierarchy at init time.
|
|
8
|
-
* WU-2326: Inference taxonomy is derived metadata and never blocks
|
|
9
|
-
* workspace-defined lane validation.
|
|
10
|
-
*
|
|
11
|
-
* Cross-checks lane definitions in workspace.yaml software_delivery against
|
|
12
|
-
* .lumenflow.lane-inference.yaml parents and emits non-blocking guidance
|
|
13
|
-
* when taxonomy drifts from workspace definitions.
|
|
14
|
-
*/
|
|
15
|
-
import * as fs from 'node:fs';
|
|
16
|
-
import * as path from 'node:path';
|
|
17
|
-
import * as yaml from 'yaml';
|
|
18
|
-
import { WORKSPACE_CONFIG_FILE_NAME } from '@lumenflow/core/config';
|
|
19
|
-
import { WORKSPACE_V2_KEYS } from '@lumenflow/core/config-schema';
|
|
20
|
-
import { CONFIG_FILES } from '@lumenflow/core/wu-constants';
|
|
21
|
-
/** Separator between parent and sublane in lane names */
|
|
22
|
-
const LANE_NAME_SEPARATOR = ': ';
|
|
23
|
-
const SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
|
|
24
|
-
/**
|
|
25
|
-
* Extract the parent name from a "Parent: Sublane" lane name.
|
|
26
|
-
*
|
|
27
|
-
* @param laneName - Lane name in "Parent: Sublane" format
|
|
28
|
-
* @returns The parent portion, or null if no separator found
|
|
29
|
-
*/
|
|
30
|
-
function extractParentName(laneName) {
|
|
31
|
-
const separatorIndex = laneName.indexOf(LANE_NAME_SEPARATOR);
|
|
32
|
-
if (separatorIndex === -1) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
return laneName.substring(0, separatorIndex);
|
|
36
|
-
}
|
|
37
|
-
function extractSubLaneName(laneName) {
|
|
38
|
-
const separatorIndex = laneName.indexOf(LANE_NAME_SEPARATOR);
|
|
39
|
-
if (separatorIndex === -1) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
const subLane = laneName.substring(separatorIndex + LANE_NAME_SEPARATOR.length).trim();
|
|
43
|
-
return subLane.length > 0 ? subLane : null;
|
|
44
|
-
}
|
|
45
|
-
function sortMapValues(map) {
|
|
46
|
-
const sorted = {};
|
|
47
|
-
for (const [parent, subLanes] of Object.entries(map)) {
|
|
48
|
-
sorted[parent] = [...subLanes].sort((left, right) => left.localeCompare(right));
|
|
49
|
-
}
|
|
50
|
-
return sorted;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Detect parent drift between workspace lane definitions and inference taxonomy.
|
|
54
|
-
*
|
|
55
|
-
* Workspace definitions are the source of truth. Inference taxonomy drift is
|
|
56
|
-
* reported as warnings only and does not populate invalidLanes.
|
|
57
|
-
*
|
|
58
|
-
* @param configLanes - Lane definitions from workspace.yaml software_delivery
|
|
59
|
-
* @param inferenceParents - Valid parent names from .lumenflow.lane-inference.yaml
|
|
60
|
-
* @returns Validation result with warnings and invalid lane names
|
|
61
|
-
*/
|
|
62
|
-
export function validateLaneConfigAgainstInference(configLanes, inferenceParents) {
|
|
63
|
-
const warnings = [];
|
|
64
|
-
const invalidLanes = [];
|
|
65
|
-
if (configLanes.length === 0 || inferenceParents.length === 0) {
|
|
66
|
-
return { warnings, invalidLanes };
|
|
67
|
-
}
|
|
68
|
-
const validParentSet = new Set(inferenceParents);
|
|
69
|
-
for (const lane of configLanes) {
|
|
70
|
-
const parent = extractParentName(lane.name);
|
|
71
|
-
if (parent === null) {
|
|
72
|
-
// Parent-only lanes are allowed and validated from workspace.yaml elsewhere.
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (!validParentSet.has(parent)) {
|
|
76
|
-
warnings.push(`Lane "${lane.name}" uses parent "${parent}" which is missing from ${CONFIG_FILES.LANE_INFERENCE}. ` +
|
|
77
|
-
`workspace.yaml is authoritative for lane validation. ` +
|
|
78
|
-
`Regenerate inference taxonomy with: pnpm lane:suggest --output ${CONFIG_FILES.LANE_INFERENCE}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return { warnings, invalidLanes };
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Extract top-level parent names from a lane inference YAML file.
|
|
85
|
-
*
|
|
86
|
-
* The lane inference file uses hierarchical format:
|
|
87
|
-
* Parent:
|
|
88
|
-
* Sublane:
|
|
89
|
-
* code_paths: [...]
|
|
90
|
-
*
|
|
91
|
-
* This function returns the top-level keys (parent names).
|
|
92
|
-
*
|
|
93
|
-
* @param laneInferencePath - Path to .lumenflow.lane-inference.yaml
|
|
94
|
-
* @returns Array of parent names, or empty array if file doesn't exist/is invalid
|
|
95
|
-
*/
|
|
96
|
-
export function extractInferenceParents(laneInferencePath) {
|
|
97
|
-
if (!fs.existsSync(laneInferencePath)) {
|
|
98
|
-
return [];
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
const content = fs.readFileSync(laneInferencePath, 'utf-8');
|
|
102
|
-
const parsed = yaml.parse(content);
|
|
103
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
104
|
-
return [];
|
|
105
|
-
}
|
|
106
|
-
// Top-level keys are parent names
|
|
107
|
-
return Object.keys(parsed);
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
export function extractInferenceTaxonomy(laneInferencePath) {
|
|
114
|
-
if (!fs.existsSync(laneInferencePath)) {
|
|
115
|
-
return {};
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
const content = fs.readFileSync(laneInferencePath, 'utf-8');
|
|
119
|
-
const parsed = yaml.parse(content);
|
|
120
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
121
|
-
return {};
|
|
122
|
-
}
|
|
123
|
-
const taxonomy = {};
|
|
124
|
-
for (const [parent, subLanesRaw] of Object.entries(parsed)) {
|
|
125
|
-
if (!subLanesRaw || typeof subLanesRaw !== 'object' || Array.isArray(subLanesRaw)) {
|
|
126
|
-
taxonomy[parent] = [];
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
taxonomy[parent] = Object.keys(subLanesRaw);
|
|
130
|
-
}
|
|
131
|
-
return sortMapValues(taxonomy);
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
return {};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
export function extractConfigTaxonomy(configLanes) {
|
|
138
|
-
if (configLanes.length === 0) {
|
|
139
|
-
return {};
|
|
140
|
-
}
|
|
141
|
-
const byParent = new Map();
|
|
142
|
-
for (const lane of configLanes) {
|
|
143
|
-
const parent = extractParentName(lane.name);
|
|
144
|
-
const subLane = extractSubLaneName(lane.name);
|
|
145
|
-
if (!parent || !subLane) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
const existing = byParent.get(parent) ?? new Set();
|
|
149
|
-
existing.add(subLane);
|
|
150
|
-
byParent.set(parent, existing);
|
|
151
|
-
}
|
|
152
|
-
const taxonomy = {};
|
|
153
|
-
for (const [parent, subLanes] of byParent.entries()) {
|
|
154
|
-
taxonomy[parent] = [...subLanes].sort((left, right) => left.localeCompare(right));
|
|
155
|
-
}
|
|
156
|
-
return taxonomy;
|
|
157
|
-
}
|
|
158
|
-
export function detectLaneTaxonomyDrift(configLanes, inferenceTaxonomy) {
|
|
159
|
-
const configTaxonomy = extractConfigTaxonomy(configLanes);
|
|
160
|
-
const allParents = new Set([...Object.keys(configTaxonomy), ...Object.keys(inferenceTaxonomy)]);
|
|
161
|
-
const missingInInference = {};
|
|
162
|
-
const extraInInference = {};
|
|
163
|
-
for (const parent of allParents) {
|
|
164
|
-
const configSubLanes = new Set(configTaxonomy[parent] ?? []);
|
|
165
|
-
const inferenceSubLanes = new Set(inferenceTaxonomy[parent] ?? []);
|
|
166
|
-
const missing = [...configSubLanes]
|
|
167
|
-
.filter((subLane) => !inferenceSubLanes.has(subLane))
|
|
168
|
-
.sort((left, right) => left.localeCompare(right));
|
|
169
|
-
const extra = [...inferenceSubLanes]
|
|
170
|
-
.filter((subLane) => !configSubLanes.has(subLane))
|
|
171
|
-
.sort((left, right) => left.localeCompare(right));
|
|
172
|
-
if (missing.length > 0) {
|
|
173
|
-
missingInInference[parent] = missing;
|
|
174
|
-
}
|
|
175
|
-
if (extra.length > 0) {
|
|
176
|
-
extraInInference[parent] = extra;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return {
|
|
180
|
-
hasDrift: Object.keys(missingInInference).length > 0 || Object.keys(extraInInference).length > 0,
|
|
181
|
-
missingInInference,
|
|
182
|
-
extraInInference,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Extract lane definitions from a workspace YAML file.
|
|
187
|
-
*
|
|
188
|
-
* @param configPath - Path to workspace.yaml
|
|
189
|
-
* @returns Array of lane definitions, or empty array if not found
|
|
190
|
-
*/
|
|
191
|
-
export function extractConfigLanes(configPath) {
|
|
192
|
-
if (!fs.existsSync(configPath)) {
|
|
193
|
-
return [];
|
|
194
|
-
}
|
|
195
|
-
try {
|
|
196
|
-
const content = fs.readFileSync(configPath, 'utf-8');
|
|
197
|
-
const parsed = yaml.parse(content);
|
|
198
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
199
|
-
return [];
|
|
200
|
-
}
|
|
201
|
-
const softwareDelivery = parsed[SOFTWARE_DELIVERY_KEY];
|
|
202
|
-
const lanes = softwareDelivery?.lanes;
|
|
203
|
-
const definitions = lanes?.definitions;
|
|
204
|
-
if (!Array.isArray(definitions)) {
|
|
205
|
-
return [];
|
|
206
|
-
}
|
|
207
|
-
return definitions;
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
return [];
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Run lane validation for a project directory.
|
|
215
|
-
*
|
|
216
|
-
* Reads both workspace.yaml and .lumenflow.lane-inference.yaml,
|
|
217
|
-
* then validates that all lane parents exist in the inference hierarchy.
|
|
218
|
-
*
|
|
219
|
-
* @param targetDir - Project root directory
|
|
220
|
-
* @returns Validation result with warnings and invalid lane names
|
|
221
|
-
*/
|
|
222
|
-
export function validateLanesForProject(targetDir) {
|
|
223
|
-
const configPath = path.join(targetDir, WORKSPACE_CONFIG_FILE_NAME);
|
|
224
|
-
const inferencePath = path.join(targetDir, CONFIG_FILES.LANE_INFERENCE);
|
|
225
|
-
const configLanes = extractConfigLanes(configPath);
|
|
226
|
-
const inferenceParents = extractInferenceParents(inferencePath);
|
|
227
|
-
// Without config lanes or inference parents there is no drift check to run.
|
|
228
|
-
if (configLanes.length === 0 || inferenceParents.length === 0) {
|
|
229
|
-
return { warnings: [], invalidLanes: [] };
|
|
230
|
-
}
|
|
231
|
-
return validateLaneConfigAgainstInference(configLanes, inferenceParents);
|
|
232
|
-
}
|
|
233
|
-
//# sourceMappingURL=init-lane-validation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init-lane-validation.js","sourceRoot":"","sources":["../src/init-lane-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# Lane Inference
|
|
2
|
-
|
|
3
|
-
**Last updated:** {{DATE}}
|
|
4
|
-
|
|
5
|
-
Lanes define which area of the system a WU belongs to. Use the lane tools before creating or reshaping work.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## The Two Inputs
|
|
10
|
-
|
|
11
|
-
Lane fit is driven by:
|
|
12
|
-
|
|
13
|
-
1. The WU `code_paths`
|
|
14
|
-
2. The implementation description or acceptance criteria
|
|
15
|
-
|
|
16
|
-
If those disagree with the assigned lane, fix the lane or split the WU.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Runtime Checks
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
pnpm wu:infer-lane --id WU-XXX
|
|
24
|
-
pnpm lane:status
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Use `wu:infer-lane` for a WU-level recommendation and `lane:status` for current lifecycle state.
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Taxonomy Source
|
|
32
|
-
|
|
33
|
-
Lane metadata is stored in `.lumenflow.lane-inference.yaml`.
|
|
34
|
-
|
|
35
|
-
Regenerate it when taxonomy drifts from `workspace.yaml`:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
pnpm lane:suggest --output .lumenflow.lane-inference.yaml
|
|
39
|
-
pnpm lane:validate
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Before Delivery WUs
|
|
45
|
-
|
|
46
|
-
Lane lifecycle must be complete before the first delivery WU:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
pnpm lane:setup
|
|
50
|
-
pnpm lane:validate
|
|
51
|
-
pnpm lane:lock
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
`locked` means delivery WUs can be created safely.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Common Failure Mode
|
|
59
|
-
|
|
60
|
-
If a WU touches files outside the assigned lane's code paths, do not just keep coding.
|
|
61
|
-
|
|
62
|
-
- Propose a lane change if the WU is genuinely in the wrong lane.
|
|
63
|
-
- Split the WU if the work spans multiple lanes.
|
|
64
|
-
- Update the taxonomy only when the lane model itself is outdated.
|