@lumenflow/initiatives 2.5.0 → 2.5.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/dist/index.d.ts CHANGED
@@ -9,3 +9,4 @@ export * from './initiative-schema.js';
9
9
  export * from './initiative-validation.js';
10
10
  export * from './initiative-validator.js';
11
11
  export * from './initiative-yaml.js';
12
+ export * from './lane-config-resolver.js';
package/dist/index.js CHANGED
@@ -9,3 +9,4 @@ export * from './initiative-schema.js';
9
9
  export * from './initiative-validation.js';
10
10
  export * from './initiative-validator.js';
11
11
  export * from './initiative-yaml.js';
12
+ export * from './lane-config-resolver.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Lane config resolver helpers.
3
+ *
4
+ * Extracts lane definitions from LumenFlow config while keeping the dependency surface small.
5
+ */
6
+ import type { LaneConfig } from './initiative-orchestrator.js';
7
+ /**
8
+ * WU-1340: Resolve laneConfigs from LumenFlow config for policy-aware scheduling.
9
+ */
10
+ export declare function resolveLaneConfigsFromConfig(config?: unknown): Record<string, LaneConfig>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Lane config resolver helpers.
3
+ *
4
+ * Extracts lane definitions from LumenFlow config while keeping the dependency surface small.
5
+ */
6
+ const LANE_SECTION_KEYS = ['definitions', 'engineering', 'business'];
7
+ function isRecord(value) {
8
+ return typeof value === 'object' && value !== null;
9
+ }
10
+ function isLaneConfigContainer(config) {
11
+ return isRecord(config);
12
+ }
13
+ function isLaneDefinition(value) {
14
+ return isRecord(value);
15
+ }
16
+ function collectLaneDefinitions(value, target) {
17
+ if (!Array.isArray(value)) {
18
+ return;
19
+ }
20
+ for (const entry of value) {
21
+ if (isLaneDefinition(entry)) {
22
+ target.push(entry);
23
+ }
24
+ }
25
+ }
26
+ function extractLaneDefinitions(config) {
27
+ if (!isLaneConfigContainer(config)) {
28
+ return [];
29
+ }
30
+ const lanes = config.lanes;
31
+ if (!lanes) {
32
+ return [];
33
+ }
34
+ if (Array.isArray(lanes)) {
35
+ const flat = [];
36
+ collectLaneDefinitions(lanes, flat);
37
+ return flat;
38
+ }
39
+ if (!isRecord(lanes)) {
40
+ return [];
41
+ }
42
+ const grouped = [];
43
+ for (const key of LANE_SECTION_KEYS) {
44
+ collectLaneDefinitions(lanes[key], grouped);
45
+ }
46
+ return grouped;
47
+ }
48
+ function isLockPolicy(value) {
49
+ return value === 'all' || value === 'active' || value === 'none';
50
+ }
51
+ /**
52
+ * WU-1340: Resolve laneConfigs from LumenFlow config for policy-aware scheduling.
53
+ */
54
+ export function resolveLaneConfigsFromConfig(config) {
55
+ const result = {};
56
+ const laneDefinitions = extractLaneDefinitions(config);
57
+ for (const lane of laneDefinitions) {
58
+ if (!lane.name || typeof lane.name !== 'string') {
59
+ continue;
60
+ }
61
+ const entry = {};
62
+ if (isLockPolicy(lane.lock_policy)) {
63
+ entry.lock_policy = lane.lock_policy;
64
+ }
65
+ if (typeof lane.wip_limit === 'number') {
66
+ entry.wip_limit = lane.wip_limit;
67
+ }
68
+ result[lane.name] = entry;
69
+ }
70
+ return result;
71
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumenflow/initiatives",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Initiative tracking for LumenFlow workflow framework - multi-phase project coordination",
5
5
  "keywords": [
6
6
  "lumenflow",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "yaml": "^2.8.2",
43
43
  "zod": "^4.3.5",
44
- "@lumenflow/core": "2.5.0"
44
+ "@lumenflow/core": "2.5.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@vitest/coverage-v8": "^4.0.17",