@lumenflow/core 2.3.1 → 2.4.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/arg-parser.d.ts +14 -2
- package/dist/arg-parser.js +63 -0
- package/dist/context/wu-state-reader.js +3 -2
- package/dist/lane-inference.js +8 -2
- package/dist/lumenflow-config-schema.d.ts +6 -0
- package/dist/lumenflow-config-schema.js +21 -0
- package/dist/lumenflow-config.d.ts +2 -0
- package/dist/lumenflow-config.js +3 -0
- package/dist/wu-paths.d.ts +10 -0
- package/dist/wu-paths.js +5 -0
- package/package.json +2 -2
package/dist/arg-parser.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OptionValues } from 'commander';
|
|
1
2
|
/**
|
|
2
3
|
* Predefined option configurations for WU management scripts.
|
|
3
4
|
* Each option has: name, flags, description, and optional default.
|
|
@@ -19,6 +20,10 @@ interface WUOption {
|
|
|
19
20
|
default?: string | boolean | string[];
|
|
20
21
|
isNegated?: boolean;
|
|
21
22
|
isRepeatable?: boolean;
|
|
23
|
+
/** Type hint for option parsing (e.g., 'boolean' for flags, 'string' for values) */
|
|
24
|
+
type?: 'boolean' | 'string';
|
|
25
|
+
/** Whether this option is required (used for validation hints) */
|
|
26
|
+
required?: boolean;
|
|
22
27
|
}
|
|
23
28
|
export declare const WU_OPTIONS: Record<string, WUOption>;
|
|
24
29
|
/**
|
|
@@ -49,7 +54,14 @@ export declare const WU_CREATE_OPTIONS: Record<string, WUOption>;
|
|
|
49
54
|
* console.log(opts.id); // 'WU-123'
|
|
50
55
|
* console.log(opts.branchOnly); // true
|
|
51
56
|
*/
|
|
52
|
-
export declare function createWUParser(config:
|
|
57
|
+
export declare function createWUParser(config: {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
options?: WUOption[];
|
|
61
|
+
required?: string[];
|
|
62
|
+
allowPositionalId?: boolean;
|
|
63
|
+
version?: string;
|
|
64
|
+
}): OptionValues;
|
|
53
65
|
/**
|
|
54
66
|
* Backward-compatible unified argument parser for WU management scripts.
|
|
55
67
|
* Uses commander internally but maintains the same return format.
|
|
@@ -65,5 +77,5 @@ export declare function createWUParser(config: any): import("commander").OptionV
|
|
|
65
77
|
* console.log(args.id); // 'WU-123'
|
|
66
78
|
* console.log(args.branchOnly); // true
|
|
67
79
|
*/
|
|
68
|
-
export declare function parseWUArgs(argv:
|
|
80
|
+
export declare function parseWUArgs(argv: string[]): OptionValues;
|
|
69
81
|
export {};
|
package/dist/arg-parser.js
CHANGED
|
@@ -323,12 +323,26 @@ export const WU_OPTIONS = {
|
|
|
323
323
|
description: 'Code paths (repeatable)',
|
|
324
324
|
isRepeatable: true,
|
|
325
325
|
},
|
|
326
|
+
// WU-1300: Alias for --code-paths (singular form for convenience)
|
|
327
|
+
codePath: {
|
|
328
|
+
name: 'codePath',
|
|
329
|
+
flags: '--code-path <path>',
|
|
330
|
+
description: 'Alias for --code-paths (repeatable)',
|
|
331
|
+
isRepeatable: true,
|
|
332
|
+
},
|
|
326
333
|
testPathsManual: {
|
|
327
334
|
name: 'testPathsManual',
|
|
328
335
|
flags: '--test-paths-manual <tests>',
|
|
329
336
|
description: 'Manual test descriptions (repeatable)',
|
|
330
337
|
isRepeatable: true,
|
|
331
338
|
},
|
|
339
|
+
// WU-1300: Alias for --test-paths-manual (shorter form for convenience)
|
|
340
|
+
manualTest: {
|
|
341
|
+
name: 'manualTest',
|
|
342
|
+
flags: '--manual-test <test>',
|
|
343
|
+
description: 'Alias for --test-paths-manual (repeatable)',
|
|
344
|
+
isRepeatable: true,
|
|
345
|
+
},
|
|
332
346
|
testPathsUnit: {
|
|
333
347
|
name: 'testPathsUnit',
|
|
334
348
|
flags: '--test-paths-unit <paths>',
|
|
@@ -562,8 +576,57 @@ export function createWUParser(config) {
|
|
|
562
576
|
if (allowPositionalId && program.args.length > 0 && !opts.id) {
|
|
563
577
|
opts.id = program.args[0];
|
|
564
578
|
}
|
|
579
|
+
// WU-1300: Merge CLI aliases into their canonical options
|
|
580
|
+
opts = mergeAliasOptions(opts);
|
|
565
581
|
return opts;
|
|
566
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* WU-1300: Option alias mappings (alias -> canonical)
|
|
585
|
+
* These allow users to use shorter/alternative flag names.
|
|
586
|
+
*/
|
|
587
|
+
const OPTION_ALIASES = {
|
|
588
|
+
codePath: 'codePaths',
|
|
589
|
+
manualTest: 'testPathsManual',
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* WU-1300: Merge alias options into their canonical counterparts.
|
|
593
|
+
* Supports both singular aliases (--code-path -> --code-paths)
|
|
594
|
+
* and alternative names (--manual-test -> --test-paths-manual).
|
|
595
|
+
*
|
|
596
|
+
* For repeatable options, values are concatenated.
|
|
597
|
+
* For single-value options, alias value is used if canonical is not set.
|
|
598
|
+
*
|
|
599
|
+
* @param {object} opts - Parsed options from Commander
|
|
600
|
+
* @returns {object} Options with aliases merged into canonical names
|
|
601
|
+
*/
|
|
602
|
+
function mergeAliasOptions(opts) {
|
|
603
|
+
const result = { ...opts };
|
|
604
|
+
for (const [alias, canonical] of Object.entries(OPTION_ALIASES)) {
|
|
605
|
+
const aliasValue = result[alias];
|
|
606
|
+
const canonicalValue = result[canonical];
|
|
607
|
+
if (aliasValue !== undefined && aliasValue !== null) {
|
|
608
|
+
// For arrays (repeatable options), concatenate
|
|
609
|
+
if (Array.isArray(aliasValue)) {
|
|
610
|
+
const existingArray = Array.isArray(canonicalValue) ? canonicalValue : [];
|
|
611
|
+
result[canonical] = [...existingArray, ...aliasValue];
|
|
612
|
+
}
|
|
613
|
+
else if (canonicalValue === undefined || canonicalValue === null) {
|
|
614
|
+
// For single values, only use alias if canonical not set
|
|
615
|
+
result[canonical] = aliasValue;
|
|
616
|
+
}
|
|
617
|
+
// Remove the alias from results (clean output)
|
|
618
|
+
// Build new result without the alias key to avoid dynamic delete
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
// Remove alias keys from final result
|
|
622
|
+
const finalResult = {};
|
|
623
|
+
for (const [key, value] of Object.entries(result)) {
|
|
624
|
+
if (!(key in OPTION_ALIASES)) {
|
|
625
|
+
finalResult[key] = value;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return finalResult;
|
|
629
|
+
}
|
|
567
630
|
/**
|
|
568
631
|
* Backward-compatible unified argument parser for WU management scripts.
|
|
569
632
|
* Uses commander internally but maintains the same return format.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { existsSync, readFileSync } from 'node:fs';
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
import { parse as parseYaml } from 'yaml';
|
|
14
|
-
import {
|
|
14
|
+
import { WU_PATHS } from '../wu-paths.js';
|
|
15
15
|
/**
|
|
16
16
|
* Normalize WU ID to uppercase format.
|
|
17
17
|
*/
|
|
@@ -24,10 +24,11 @@ function normalizeWuId(id) {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Build the path to WU YAML file.
|
|
27
|
+
* WU-1301: Uses config-based paths instead of hardcoded DIRECTORIES.
|
|
27
28
|
*/
|
|
28
29
|
function getWuYamlPath(wuId, repoRoot) {
|
|
29
30
|
const normalizedId = normalizeWuId(wuId);
|
|
30
|
-
return join(repoRoot,
|
|
31
|
+
return join(repoRoot, WU_PATHS.WU(normalizedId));
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* Read WU state from YAML and detect inconsistencies.
|
package/dist/lane-inference.js
CHANGED
|
@@ -31,7 +31,13 @@ function loadConfig(configPath = null) {
|
|
|
31
31
|
configPath = path.join(projectRoot, '.lumenflow.lane-inference.yaml');
|
|
32
32
|
}
|
|
33
33
|
if (!existsSync(configPath)) {
|
|
34
|
-
throw createError(ErrorCodes.FILE_NOT_FOUND, `Lane inference config not found: ${configPath}\n\
|
|
34
|
+
throw createError(ErrorCodes.FILE_NOT_FOUND, `Lane inference config not found: ${configPath}\n\n` +
|
|
35
|
+
`This file defines the lane taxonomy for sub-lane validation.\n\n` +
|
|
36
|
+
`To fix this:\n` +
|
|
37
|
+
` 1. Generate a lane taxonomy from your codebase:\n` +
|
|
38
|
+
` pnpm lane:suggest --output .lumenflow.lane-inference.yaml\n\n` +
|
|
39
|
+
` 2. Or copy from an example project and customize.\n\n` +
|
|
40
|
+
`See: LUMENFLOW.md "Setup Notes" section for details.`, { path: configPath });
|
|
35
41
|
}
|
|
36
42
|
try {
|
|
37
43
|
const configContent = readFileSync(configPath, { encoding: 'utf-8' });
|
|
@@ -167,7 +173,7 @@ export function getAllSubLanes(configPath = null) {
|
|
|
167
173
|
subLanes.push(`${parentLane}: ${subLane}`);
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
|
-
return subLanes.sort();
|
|
176
|
+
return subLanes.sort((a, b) => a.localeCompare(b));
|
|
171
177
|
}
|
|
172
178
|
/**
|
|
173
179
|
* Get valid sub-lanes for a specific parent lane
|
|
@@ -35,6 +35,7 @@ export declare const DirectoriesSchema: z.ZodObject<{
|
|
|
35
35
|
statusPath: z.ZodDefault<z.ZodString>;
|
|
36
36
|
skillsDir: z.ZodDefault<z.ZodString>;
|
|
37
37
|
agentsDir: z.ZodDefault<z.ZodString>;
|
|
38
|
+
plansDir: z.ZodDefault<z.ZodString>;
|
|
38
39
|
}, z.core.$strip>;
|
|
39
40
|
/**
|
|
40
41
|
* Beacon paths configuration (.lumenflow directory structure)
|
|
@@ -67,6 +68,7 @@ export declare const GitConfigSchema: z.ZodObject<{
|
|
|
67
68
|
maxBranchDrift: z.ZodDefault<z.ZodNumber>;
|
|
68
69
|
branchDriftWarning: z.ZodDefault<z.ZodNumber>;
|
|
69
70
|
branchDriftInfo: z.ZodDefault<z.ZodNumber>;
|
|
71
|
+
requireRemote: z.ZodDefault<z.ZodBoolean>;
|
|
70
72
|
agentBranchPatterns: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
71
73
|
agentBranchPatternsOverride: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
72
74
|
disableAgentPatternRegistry: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -329,6 +331,7 @@ export declare const LumenFlowConfigSchema: z.ZodObject<{
|
|
|
329
331
|
statusPath: z.ZodDefault<z.ZodString>;
|
|
330
332
|
skillsDir: z.ZodDefault<z.ZodString>;
|
|
331
333
|
agentsDir: z.ZodDefault<z.ZodString>;
|
|
334
|
+
plansDir: z.ZodDefault<z.ZodString>;
|
|
332
335
|
}, z.core.$strip>>;
|
|
333
336
|
beacon: z.ZodDefault<z.ZodObject<{
|
|
334
337
|
base: z.ZodDefault<z.ZodString>;
|
|
@@ -355,6 +358,7 @@ export declare const LumenFlowConfigSchema: z.ZodObject<{
|
|
|
355
358
|
maxBranchDrift: z.ZodDefault<z.ZodNumber>;
|
|
356
359
|
branchDriftWarning: z.ZodDefault<z.ZodNumber>;
|
|
357
360
|
branchDriftInfo: z.ZodDefault<z.ZodNumber>;
|
|
361
|
+
requireRemote: z.ZodDefault<z.ZodBoolean>;
|
|
358
362
|
agentBranchPatterns: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
359
363
|
agentBranchPatternsOverride: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
360
364
|
disableAgentPatternRegistry: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -544,6 +548,7 @@ export declare function validateConfig(data: unknown): z.ZodSafeParseResult<{
|
|
|
544
548
|
statusPath: string;
|
|
545
549
|
skillsDir: string;
|
|
546
550
|
agentsDir: string;
|
|
551
|
+
plansDir: string;
|
|
547
552
|
};
|
|
548
553
|
beacon: {
|
|
549
554
|
base: string;
|
|
@@ -570,6 +575,7 @@ export declare function validateConfig(data: unknown): z.ZodSafeParseResult<{
|
|
|
570
575
|
maxBranchDrift: number;
|
|
571
576
|
branchDriftWarning: number;
|
|
572
577
|
branchDriftInfo: number;
|
|
578
|
+
requireRemote: boolean;
|
|
573
579
|
agentBranchPatterns: string[];
|
|
574
580
|
disableAgentPatternRegistry: boolean;
|
|
575
581
|
agentBranchPatternsOverride?: string[];
|
|
@@ -67,6 +67,8 @@ export const DirectoriesSchema = z.object({
|
|
|
67
67
|
skillsDir: z.string().default('.claude/skills'),
|
|
68
68
|
/** Agents directory (default: '.claude/agents') */
|
|
69
69
|
agentsDir: z.string().default('.claude/agents'),
|
|
70
|
+
/** Plans directory (default: 'docs/04-operations/plans') - WU-1301 */
|
|
71
|
+
plansDir: z.string().default('docs/04-operations/plans'),
|
|
70
72
|
});
|
|
71
73
|
/**
|
|
72
74
|
* Beacon paths configuration (.lumenflow directory structure)
|
|
@@ -118,6 +120,25 @@ export const GitConfigSchema = z.object({
|
|
|
118
120
|
branchDriftWarning: z.number().int().positive().default(15),
|
|
119
121
|
/** Info threshold for branch drift */
|
|
120
122
|
branchDriftInfo: z.number().int().positive().default(10),
|
|
123
|
+
/**
|
|
124
|
+
* WU-1302: Require a remote repository for wu:create and wu:claim.
|
|
125
|
+
* When true (default), operations fail if no remote 'origin' exists.
|
|
126
|
+
* When false, operations can proceed locally without pushing.
|
|
127
|
+
*
|
|
128
|
+
* Use `git.requireRemote: false` for:
|
|
129
|
+
* - Local-only development before remote is set up
|
|
130
|
+
* - Air-gapped environments
|
|
131
|
+
* - Testing/evaluation of LumenFlow
|
|
132
|
+
*
|
|
133
|
+
* @default true
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```yaml
|
|
137
|
+
* git:
|
|
138
|
+
* requireRemote: false # Allow offline/local mode
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
requireRemote: z.boolean().default(true),
|
|
121
142
|
/**
|
|
122
143
|
* Agent branch patterns to MERGE with the registry patterns.
|
|
123
144
|
* These patterns are merged with patterns from lumenflow.dev/registry/agent-patterns.json.
|
|
@@ -71,6 +71,7 @@ export declare function getResolvedPaths(options?: {
|
|
|
71
71
|
skillsDir: string;
|
|
72
72
|
agentsDir: string;
|
|
73
73
|
memoryBank: string;
|
|
74
|
+
plansDir: string;
|
|
74
75
|
};
|
|
75
76
|
/**
|
|
76
77
|
* Validate a config file
|
|
@@ -93,3 +94,4 @@ export declare function createSampleConfig(outputPath: string, options?: {
|
|
|
93
94
|
includeComments?: boolean;
|
|
94
95
|
}): void;
|
|
95
96
|
export type { LumenFlowConfig, Directories, BeaconPaths, GitConfig, WuConfig, GatesConfig, MemoryConfig, UiConfig, YamlConfig, } from './lumenflow-config-schema.js';
|
|
97
|
+
export { getDefaultConfig } from './lumenflow-config-schema.js';
|
package/dist/lumenflow-config.js
CHANGED
|
@@ -144,6 +144,7 @@ export function getResolvedPaths(options = {}) {
|
|
|
144
144
|
skillsDir: path.join(projectRoot, config.directories.skillsDir),
|
|
145
145
|
agentsDir: path.join(projectRoot, config.directories.agentsDir),
|
|
146
146
|
memoryBank: path.join(projectRoot, config.directories.memoryBank),
|
|
147
|
+
plansDir: path.join(projectRoot, config.directories.plansDir),
|
|
147
148
|
};
|
|
148
149
|
}
|
|
149
150
|
/**
|
|
@@ -234,3 +235,5 @@ gates:
|
|
|
234
235
|
: yaml.stringify(defaultConfig);
|
|
235
236
|
fs.writeFileSync(outputPath, configContent, 'utf8');
|
|
236
237
|
}
|
|
238
|
+
// Re-export getDefaultConfig for consumers
|
|
239
|
+
export { getDefaultConfig } from './lumenflow-config-schema.js';
|
package/dist/wu-paths.d.ts
CHANGED
|
@@ -77,6 +77,11 @@ export declare function createWuPaths(options?: {
|
|
|
77
77
|
* @returns Path to worktrees directory
|
|
78
78
|
*/
|
|
79
79
|
WORKTREES_DIR: () => string;
|
|
80
|
+
/**
|
|
81
|
+
* Get path to plans directory
|
|
82
|
+
* @returns Path to plans directory (WU-1301)
|
|
83
|
+
*/
|
|
84
|
+
PLANS_DIR: () => string;
|
|
80
85
|
};
|
|
81
86
|
/**
|
|
82
87
|
* Default WU paths using default config
|
|
@@ -130,6 +135,11 @@ export declare const WU_PATHS: {
|
|
|
130
135
|
* @returns Path to worktrees directory
|
|
131
136
|
*/
|
|
132
137
|
WORKTREES_DIR: () => string;
|
|
138
|
+
/**
|
|
139
|
+
* Get path to plans directory
|
|
140
|
+
* @returns Path to plans directory (WU-1301)
|
|
141
|
+
*/
|
|
142
|
+
PLANS_DIR: () => string;
|
|
133
143
|
};
|
|
134
144
|
/**
|
|
135
145
|
* Generate default worktree path from WU document
|
package/dist/wu-paths.js
CHANGED
|
@@ -104,6 +104,11 @@ export function createWuPaths(options = {}) {
|
|
|
104
104
|
* @returns Path to worktrees directory
|
|
105
105
|
*/
|
|
106
106
|
WORKTREES_DIR: () => config.directories.worktrees,
|
|
107
|
+
/**
|
|
108
|
+
* Get path to plans directory
|
|
109
|
+
* @returns Path to plans directory (WU-1301)
|
|
110
|
+
*/
|
|
111
|
+
PLANS_DIR: () => config.directories.plansDir,
|
|
107
112
|
};
|
|
108
113
|
}
|
|
109
114
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumenflow/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Core WU lifecycle tools for LumenFlow workflow framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lumenflow",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"vitest": "^4.0.17"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
|
-
"@lumenflow/memory": "2.
|
|
101
|
+
"@lumenflow/memory": "2.4.0"
|
|
102
102
|
},
|
|
103
103
|
"peerDependenciesMeta": {
|
|
104
104
|
"@lumenflow/memory": {
|