@lumenflow/core 1.3.2 → 1.3.3
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 +1 -1
- package/dist/arg-parser.js +3 -13
- package/dist/core/tool.schemas.d.ts +1 -1
- package/dist/coverage-gate.d.ts +3 -0
- package/dist/coverage-gate.js +7 -4
- package/dist/force-bypass-audit.d.ts +63 -0
- package/dist/force-bypass-audit.js +140 -0
- package/dist/gates-config.d.ts +132 -0
- package/dist/gates-config.js +229 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -2
- package/dist/lumenflow-config-schema.d.ts +97 -0
- package/dist/lumenflow-config-schema.js +9 -0
- package/dist/lumenflow-home.js +14 -11
- package/dist/manual-test-validator.d.ts +3 -0
- package/dist/manual-test-validator.js +6 -3
- package/dist/prompt-linter.js +2 -1
- package/dist/prompt-monitor.js +3 -1
- package/dist/spec-branch-helpers.d.ts +8 -8
- package/dist/spec-branch-helpers.js +18 -11
- package/dist/user-normalizer.d.ts +5 -1
- package/dist/user-normalizer.js +6 -1
- package/dist/validators/phi-scanner.js +6 -0
- package/dist/worktree-symlink.d.ts +4 -0
- package/dist/worktree-symlink.js +14 -20
- package/dist/wu-constants.d.ts +116 -0
- package/dist/wu-constants.js +120 -4
- package/dist/wu-create-validators.d.ts +17 -0
- package/dist/wu-create-validators.js +37 -2
- package/dist/wu-spawn.js +1 -1
- package/dist/wu-yaml-fixer.js +6 -3
- package/package.json +11 -11
|
@@ -67,6 +67,7 @@ export declare const WuConfigSchema: z.ZodObject<{
|
|
|
67
67
|
}, z.core.$strip>;
|
|
68
68
|
/**
|
|
69
69
|
* Gates configuration
|
|
70
|
+
* Note: GatesExecutionConfigSchema is imported from gates-config.ts
|
|
70
71
|
*/
|
|
71
72
|
export declare const GatesConfigSchema: z.ZodObject<{
|
|
72
73
|
maxEslintWarnings: z.ZodDefault<z.ZodNumber>;
|
|
@@ -74,6 +75,38 @@ export declare const GatesConfigSchema: z.ZodObject<{
|
|
|
74
75
|
minCoverage: z.ZodDefault<z.ZodNumber>;
|
|
75
76
|
enableSafetyCriticalTests: z.ZodDefault<z.ZodBoolean>;
|
|
76
77
|
enableInvariants: z.ZodDefault<z.ZodBoolean>;
|
|
78
|
+
execution: z.ZodOptional<z.ZodObject<{
|
|
79
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
80
|
+
setup: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
81
|
+
command: z.ZodString;
|
|
82
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
84
|
+
}, z.core.$strip>]>>;
|
|
85
|
+
format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
86
|
+
command: z.ZodString;
|
|
87
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
89
|
+
}, z.core.$strip>]>>;
|
|
90
|
+
lint: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
91
|
+
command: z.ZodString;
|
|
92
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
93
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
94
|
+
}, z.core.$strip>]>>;
|
|
95
|
+
typecheck: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
96
|
+
command: z.ZodString;
|
|
97
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
98
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
99
|
+
}, z.core.$strip>]>>;
|
|
100
|
+
test: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
101
|
+
command: z.ZodString;
|
|
102
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
103
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
104
|
+
}, z.core.$strip>]>>;
|
|
105
|
+
coverage: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
106
|
+
command: z.ZodString;
|
|
107
|
+
threshold: z.ZodOptional<z.ZodNumber>;
|
|
108
|
+
}, z.core.$strip>]>>;
|
|
109
|
+
}, z.core.$strip>>;
|
|
77
110
|
}, z.core.$strip>;
|
|
78
111
|
/**
|
|
79
112
|
* Memory layer configuration
|
|
@@ -227,6 +260,38 @@ export declare const LumenFlowConfigSchema: z.ZodObject<{
|
|
|
227
260
|
minCoverage: z.ZodDefault<z.ZodNumber>;
|
|
228
261
|
enableSafetyCriticalTests: z.ZodDefault<z.ZodBoolean>;
|
|
229
262
|
enableInvariants: z.ZodDefault<z.ZodBoolean>;
|
|
263
|
+
execution: z.ZodOptional<z.ZodObject<{
|
|
264
|
+
preset: z.ZodOptional<z.ZodString>;
|
|
265
|
+
setup: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
266
|
+
command: z.ZodString;
|
|
267
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
268
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
269
|
+
}, z.core.$strip>]>>;
|
|
270
|
+
format: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
271
|
+
command: z.ZodString;
|
|
272
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
273
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
274
|
+
}, z.core.$strip>]>>;
|
|
275
|
+
lint: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
276
|
+
command: z.ZodString;
|
|
277
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
278
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
279
|
+
}, z.core.$strip>]>>;
|
|
280
|
+
typecheck: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
281
|
+
command: z.ZodString;
|
|
282
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
283
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
284
|
+
}, z.core.$strip>]>>;
|
|
285
|
+
test: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
286
|
+
command: z.ZodString;
|
|
287
|
+
continueOnError: z.ZodOptional<z.ZodBoolean>;
|
|
288
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
289
|
+
}, z.core.$strip>]>>;
|
|
290
|
+
coverage: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
291
|
+
command: z.ZodString;
|
|
292
|
+
threshold: z.ZodOptional<z.ZodNumber>;
|
|
293
|
+
}, z.core.$strip>]>>;
|
|
294
|
+
}, z.core.$strip>>;
|
|
230
295
|
}, z.core.$strip>>;
|
|
231
296
|
memory: z.ZodDefault<z.ZodObject<{
|
|
232
297
|
directory: z.ZodDefault<z.ZodString>;
|
|
@@ -344,6 +409,38 @@ export declare function validateConfig(data: unknown): z.ZodSafeParseResult<{
|
|
|
344
409
|
minCoverage: number;
|
|
345
410
|
enableSafetyCriticalTests: boolean;
|
|
346
411
|
enableInvariants: boolean;
|
|
412
|
+
execution?: {
|
|
413
|
+
preset?: string;
|
|
414
|
+
setup?: string | {
|
|
415
|
+
command: string;
|
|
416
|
+
continueOnError?: boolean;
|
|
417
|
+
timeout?: number;
|
|
418
|
+
};
|
|
419
|
+
format?: string | {
|
|
420
|
+
command: string;
|
|
421
|
+
continueOnError?: boolean;
|
|
422
|
+
timeout?: number;
|
|
423
|
+
};
|
|
424
|
+
lint?: string | {
|
|
425
|
+
command: string;
|
|
426
|
+
continueOnError?: boolean;
|
|
427
|
+
timeout?: number;
|
|
428
|
+
};
|
|
429
|
+
typecheck?: string | {
|
|
430
|
+
command: string;
|
|
431
|
+
continueOnError?: boolean;
|
|
432
|
+
timeout?: number;
|
|
433
|
+
};
|
|
434
|
+
test?: string | {
|
|
435
|
+
command: string;
|
|
436
|
+
continueOnError?: boolean;
|
|
437
|
+
timeout?: number;
|
|
438
|
+
};
|
|
439
|
+
coverage?: string | {
|
|
440
|
+
command: string;
|
|
441
|
+
threshold?: number;
|
|
442
|
+
};
|
|
443
|
+
};
|
|
347
444
|
};
|
|
348
445
|
memory: {
|
|
349
446
|
directory: string;
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* @module lumenflow-config-schema
|
|
8
8
|
*/
|
|
9
9
|
import { z } from 'zod';
|
|
10
|
+
// WU-1067: Import gates execution schema from canonical source
|
|
11
|
+
import { GatesExecutionConfigSchema } from './gates-config.js';
|
|
10
12
|
/**
|
|
11
13
|
* Directory paths configuration
|
|
12
14
|
*/
|
|
@@ -110,6 +112,7 @@ export const WuConfigSchema = z.object({
|
|
|
110
112
|
});
|
|
111
113
|
/**
|
|
112
114
|
* Gates configuration
|
|
115
|
+
* Note: GatesExecutionConfigSchema is imported from gates-config.ts
|
|
113
116
|
*/
|
|
114
117
|
export const GatesConfigSchema = z.object({
|
|
115
118
|
/** Maximum ESLint warnings allowed (default: 100) */
|
|
@@ -122,6 +125,12 @@ export const GatesConfigSchema = z.object({
|
|
|
122
125
|
enableSafetyCriticalTests: z.boolean().default(true),
|
|
123
126
|
/** Enable invariants check (default: true) */
|
|
124
127
|
enableInvariants: z.boolean().default(true),
|
|
128
|
+
/**
|
|
129
|
+
* WU-1067: Config-driven gates execution
|
|
130
|
+
* Custom commands for each gate, with optional preset expansion.
|
|
131
|
+
* When set, gates runner uses these instead of hardcoded commands.
|
|
132
|
+
*/
|
|
133
|
+
execution: GatesExecutionConfigSchema.optional(),
|
|
125
134
|
});
|
|
126
135
|
/**
|
|
127
136
|
* Memory layer configuration
|
package/dist/lumenflow-home.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { homedir } from 'node:os';
|
|
15
15
|
import { join } from 'node:path';
|
|
16
|
+
import { PATH_LITERALS, PATH_SLICE_LENGTHS, STRING_LITERALS } from './wu-constants.js';
|
|
16
17
|
/**
|
|
17
18
|
* Environment variable name for LumenFlow home directory
|
|
18
19
|
*/
|
|
@@ -40,10 +41,10 @@ export const LUMENFLOW_HOME_VAR_PREFIX = '$LUMENFLOW_HOME';
|
|
|
40
41
|
* @returns {string} Expanded path
|
|
41
42
|
*/
|
|
42
43
|
function expandTilde(path) {
|
|
43
|
-
if (path.startsWith(
|
|
44
|
-
return join(homedir(), path.slice(
|
|
44
|
+
if (path.startsWith(PATH_LITERALS.TILDE_PREFIX)) {
|
|
45
|
+
return join(homedir(), path.slice(PATH_SLICE_LENGTHS.TILDE_PREFIX_LENGTH));
|
|
45
46
|
}
|
|
46
|
-
if (path ===
|
|
47
|
+
if (path === PATH_LITERALS.TILDE) {
|
|
47
48
|
return homedir();
|
|
48
49
|
}
|
|
49
50
|
return path;
|
|
@@ -55,7 +56,7 @@ function expandTilde(path) {
|
|
|
55
56
|
* @returns {string} Path without trailing slashes
|
|
56
57
|
*/
|
|
57
58
|
function removeTrailingSlash(path) {
|
|
58
|
-
return path.replace(
|
|
59
|
+
return path.replace(PATH_LITERALS.TRAILING_SLASH_REGEX, STRING_LITERALS.EMPTY);
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
61
62
|
* Get the LumenFlow home directory path
|
|
@@ -120,7 +121,7 @@ export function getPlansDir() {
|
|
|
120
121
|
*/
|
|
121
122
|
export function isExternalPath(path) {
|
|
122
123
|
// Check for tilde-prefixed paths
|
|
123
|
-
if (path.startsWith(
|
|
124
|
+
if (path.startsWith(PATH_LITERALS.TILDE_PREFIX)) {
|
|
124
125
|
return true;
|
|
125
126
|
}
|
|
126
127
|
// Check for environment variable reference
|
|
@@ -132,7 +133,7 @@ export function isExternalPath(path) {
|
|
|
132
133
|
return true;
|
|
133
134
|
}
|
|
134
135
|
// Check for absolute paths (starting with /)
|
|
135
|
-
if (path.startsWith(
|
|
136
|
+
if (path.startsWith(STRING_LITERALS.SLASH)) {
|
|
136
137
|
return true;
|
|
137
138
|
}
|
|
138
139
|
return false;
|
|
@@ -168,11 +169,13 @@ export function normalizeSpecRef(specRef) {
|
|
|
168
169
|
if (specRef.startsWith(LUMENFLOW_HOME_VAR_PREFIX)) {
|
|
169
170
|
const relativePath = specRef.slice(LUMENFLOW_HOME_VAR_PREFIX.length);
|
|
170
171
|
// Remove leading slash if present
|
|
171
|
-
const cleanPath = relativePath.startsWith(
|
|
172
|
+
const cleanPath = relativePath.startsWith(STRING_LITERALS.SLASH)
|
|
173
|
+
? relativePath.slice(PATH_SLICE_LENGTHS.LEADING_SLASH_LENGTH)
|
|
174
|
+
: relativePath;
|
|
172
175
|
return join(getLumenflowHome(), cleanPath);
|
|
173
176
|
}
|
|
174
177
|
// Handle tilde expansion
|
|
175
|
-
if (specRef.startsWith(
|
|
178
|
+
if (specRef.startsWith(PATH_LITERALS.TILDE_PREFIX)) {
|
|
176
179
|
return expandTilde(specRef);
|
|
177
180
|
}
|
|
178
181
|
// Return relative paths unchanged
|
|
@@ -189,7 +192,7 @@ export function normalizeSpecRef(specRef) {
|
|
|
189
192
|
* // '/home/user/.lumenflow/plans/WU-1062-plan.md'
|
|
190
193
|
*/
|
|
191
194
|
export function getPlanPath(wuId) {
|
|
192
|
-
const filename = `${wuId}
|
|
195
|
+
const filename = `${wuId}${PATH_LITERALS.PLAN_FILE_SUFFIX}`;
|
|
193
196
|
return join(getPlansDir(), filename);
|
|
194
197
|
}
|
|
195
198
|
/**
|
|
@@ -203,6 +206,6 @@ export function getPlanPath(wuId) {
|
|
|
203
206
|
* // 'lumenflow://plans/WU-1062-plan.md'
|
|
204
207
|
*/
|
|
205
208
|
export function getPlanProtocolRef(wuId) {
|
|
206
|
-
const filename = `${wuId}
|
|
207
|
-
return `${LUMENFLOW_PROTOCOL}${PLANS_SUBDIR}
|
|
209
|
+
const filename = `${wuId}${PATH_LITERALS.PLAN_FILE_SUFFIX}`;
|
|
210
|
+
return `${LUMENFLOW_PROTOCOL}${PLANS_SUBDIR}${STRING_LITERALS.SLASH}${filename}`;
|
|
208
211
|
}
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
* Path prefixes for hex core code requiring automated tests.
|
|
19
19
|
* These are the critical application layer paths.
|
|
20
20
|
*
|
|
21
|
+
* WU-1068: Changed from @patientpath to @lumenflow for framework reusability.
|
|
22
|
+
* Project-specific patterns should be configured in .lumenflow.config.yaml.
|
|
23
|
+
*
|
|
21
24
|
* @constant {string[]}
|
|
22
25
|
*/
|
|
23
26
|
export declare const HEX_CORE_CODE_PATTERNS: readonly string[];
|
|
@@ -40,12 +40,15 @@ const CONFIG_PATTERNS = Object.freeze([
|
|
|
40
40
|
* Path prefixes for hex core code requiring automated tests.
|
|
41
41
|
* These are the critical application layer paths.
|
|
42
42
|
*
|
|
43
|
+
* WU-1068: Changed from @patientpath to @lumenflow for framework reusability.
|
|
44
|
+
* Project-specific patterns should be configured in .lumenflow.config.yaml.
|
|
45
|
+
*
|
|
43
46
|
* @constant {string[]}
|
|
44
47
|
*/
|
|
45
48
|
export const HEX_CORE_CODE_PATTERNS = Object.freeze([
|
|
46
|
-
'packages/@
|
|
47
|
-
'packages/@
|
|
48
|
-
'packages/@
|
|
49
|
+
'packages/@lumenflow/core/',
|
|
50
|
+
'packages/@lumenflow/cli/',
|
|
51
|
+
'packages/@lumenflow/agent/',
|
|
49
52
|
]);
|
|
50
53
|
/**
|
|
51
54
|
* @deprecated Lane-based exemptions removed in WU-2332.
|
package/dist/prompt-linter.js
CHANGED
|
@@ -249,7 +249,8 @@ export async function lintPrompts(filePaths = [], mode = 'local', configPath = u
|
|
|
249
249
|
const output = { quiet: options.quiet === true, verbose: options.verbose === true };
|
|
250
250
|
// If no files provided, find all orchestrator prompt files (WU-676 scope only)
|
|
251
251
|
if (filePaths.length === 0) {
|
|
252
|
-
|
|
252
|
+
// WU-1068: Changed from @patientpath to generic ai/prompts for framework reusability
|
|
253
|
+
const pattern = 'ai/prompts/orchestrator-*/**/*.yaml';
|
|
253
254
|
filePaths = await glob(pattern, { cwd: ROOT_DIR, absolute: true });
|
|
254
255
|
}
|
|
255
256
|
// Load previous metrics for delta calculation
|
package/dist/prompt-monitor.js
CHANGED
|
@@ -96,7 +96,9 @@ async function log(event, data) {
|
|
|
96
96
|
async function monitor() {
|
|
97
97
|
console.log('\n🌙 Nightly Prompt Monitor Starting...\n');
|
|
98
98
|
// Find all prompt files
|
|
99
|
-
|
|
99
|
+
// WU-1068: Changed from @patientpath to generic ai/prompts for framework reusability
|
|
100
|
+
// Projects should configure prompt paths in .lumenflow.config.yaml
|
|
101
|
+
const pattern = 'ai/prompts/**/*.yaml';
|
|
100
102
|
const promptFiles = await glob(pattern, { cwd: ROOT_DIR, absolute: true });
|
|
101
103
|
console.log(`Found ${promptFiles.length} prompt files to analyze\n`);
|
|
102
104
|
// Load yesterday's metrics for delta calculation
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
|
-
import type {
|
|
11
|
+
import type { GitAdapter } from './git-adapter.js';
|
|
12
12
|
/**
|
|
13
13
|
* Spec branch prefix
|
|
14
14
|
*/
|
|
@@ -54,7 +54,7 @@ export declare function getOriginSpecBranch(wuId: string): string;
|
|
|
54
54
|
* @example
|
|
55
55
|
* const exists = await specBranchExists('WU-1062', git);
|
|
56
56
|
*/
|
|
57
|
-
export declare function specBranchExists(wuId: string, git:
|
|
57
|
+
export declare function specBranchExists(wuId: string, git: GitAdapter): Promise<boolean>;
|
|
58
58
|
/**
|
|
59
59
|
* Check if a WU exists on main branch
|
|
60
60
|
*
|
|
@@ -62,7 +62,7 @@ export declare function specBranchExists(wuId: string, git: SimpleGit): Promise<
|
|
|
62
62
|
* @param {SimpleGit} git - Git adapter instance
|
|
63
63
|
* @returns {Promise<boolean>} True if WU YAML exists on main
|
|
64
64
|
*/
|
|
65
|
-
export declare function isWUOnMain(wuId: string, git:
|
|
65
|
+
export declare function isWUOnMain(wuId: string, git: GitAdapter): Promise<boolean>;
|
|
66
66
|
/**
|
|
67
67
|
* Merge spec branch to main branch (fast-forward only)
|
|
68
68
|
*
|
|
@@ -76,14 +76,14 @@ export declare function isWUOnMain(wuId: string, git: SimpleGit): Promise<boolea
|
|
|
76
76
|
* @example
|
|
77
77
|
* await mergeSpecBranchToMain('WU-1062', git);
|
|
78
78
|
*/
|
|
79
|
-
export declare function mergeSpecBranchToMain(wuId: string, git:
|
|
79
|
+
export declare function mergeSpecBranchToMain(wuId: string, git: GitAdapter): Promise<void>;
|
|
80
80
|
/**
|
|
81
81
|
* Delete spec branch after merge
|
|
82
82
|
*
|
|
83
83
|
* @param {string} wuId - Work Unit ID
|
|
84
84
|
* @param {SimpleGit} git - Git adapter instance
|
|
85
85
|
*/
|
|
86
|
-
export declare function deleteSpecBranch(wuId: string, git:
|
|
86
|
+
export declare function deleteSpecBranch(wuId: string, git: GitAdapter): Promise<void>;
|
|
87
87
|
/**
|
|
88
88
|
* Determine the source of a WU (main, spec branch, both, or not found)
|
|
89
89
|
*
|
|
@@ -99,7 +99,7 @@ export declare function deleteSpecBranch(wuId: string, git: SimpleGit): Promise<
|
|
|
99
99
|
* await mergeSpecBranchToMain('WU-1062', git);
|
|
100
100
|
* }
|
|
101
101
|
*/
|
|
102
|
-
export declare function getWUSource(wuId: string, git:
|
|
102
|
+
export declare function getWUSource(wuId: string, git: GitAdapter): Promise<WUSourceType>;
|
|
103
103
|
/**
|
|
104
104
|
* Create a spec branch from current HEAD
|
|
105
105
|
*
|
|
@@ -108,11 +108,11 @@ export declare function getWUSource(wuId: string, git: SimpleGit): Promise<WUSou
|
|
|
108
108
|
* @param {string} wuId - Work Unit ID
|
|
109
109
|
* @param {SimpleGit} git - Git adapter instance
|
|
110
110
|
*/
|
|
111
|
-
export declare function createSpecBranch(wuId: string, git:
|
|
111
|
+
export declare function createSpecBranch(wuId: string, git: GitAdapter): Promise<void>;
|
|
112
112
|
/**
|
|
113
113
|
* Push spec branch to origin
|
|
114
114
|
*
|
|
115
115
|
* @param {string} wuId - Work Unit ID
|
|
116
116
|
* @param {SimpleGit} git - Git adapter instance
|
|
117
117
|
*/
|
|
118
|
-
export declare function pushSpecBranch(wuId: string, git:
|
|
118
|
+
export declare function pushSpecBranch(wuId: string, git: GitAdapter): Promise<void>;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { WU_PATHS } from './wu-paths.js';
|
|
12
|
+
import { REMOTES, GIT_REFS, GIT_COMMANDS, GIT_FLAGS } from './wu-constants.js';
|
|
12
13
|
/**
|
|
13
14
|
* Spec branch prefix
|
|
14
15
|
*/
|
|
@@ -45,7 +46,7 @@ export function getSpecBranchName(wuId) {
|
|
|
45
46
|
* @returns {string} Origin-qualified branch name (e.g., 'origin/spec/wu-1062')
|
|
46
47
|
*/
|
|
47
48
|
export function getOriginSpecBranch(wuId) {
|
|
48
|
-
return
|
|
49
|
+
return GIT_REFS.remote(REMOTES.ORIGIN, getSpecBranchName(wuId));
|
|
49
50
|
}
|
|
50
51
|
/**
|
|
51
52
|
* Check if a spec branch exists on origin
|
|
@@ -65,7 +66,12 @@ export async function specBranchExists(wuId, git) {
|
|
|
65
66
|
return await git.branchExists(originBranch);
|
|
66
67
|
}
|
|
67
68
|
// Fallback: use ls-remote to check if branch exists
|
|
68
|
-
const result = await git.raw([
|
|
69
|
+
const result = await git.raw([
|
|
70
|
+
GIT_COMMANDS.LS_REMOTE,
|
|
71
|
+
GIT_FLAGS.HEADS,
|
|
72
|
+
REMOTES.ORIGIN,
|
|
73
|
+
getSpecBranchName(wuId),
|
|
74
|
+
]);
|
|
69
75
|
return result.trim().length > 0;
|
|
70
76
|
}
|
|
71
77
|
catch {
|
|
@@ -83,8 +89,9 @@ export async function isWUOnMain(wuId, git) {
|
|
|
83
89
|
try {
|
|
84
90
|
const wuPath = WU_PATHS.WU(wuId);
|
|
85
91
|
// Check if file exists on origin/main
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
// git ls-tree returns exit 0 with empty output if file doesn't exist
|
|
93
|
+
const result = await git.raw([GIT_COMMANDS.LS_TREE, GIT_REFS.ORIGIN_MAIN, GIT_FLAGS.PATH_SEPARATOR, wuPath]);
|
|
94
|
+
return result.trim().length > 0;
|
|
88
95
|
}
|
|
89
96
|
catch {
|
|
90
97
|
return false;
|
|
@@ -107,9 +114,9 @@ export async function mergeSpecBranchToMain(wuId, git) {
|
|
|
107
114
|
const specBranch = getSpecBranchName(wuId);
|
|
108
115
|
const originSpecBranch = getOriginSpecBranch(wuId);
|
|
109
116
|
// Fetch the spec branch
|
|
110
|
-
await git.fetch(
|
|
117
|
+
await git.fetch(REMOTES.ORIGIN, specBranch);
|
|
111
118
|
// Merge with fast-forward only (safe merge)
|
|
112
|
-
await git.merge(
|
|
119
|
+
await git.merge(originSpecBranch, { ffOnly: true });
|
|
113
120
|
}
|
|
114
121
|
/**
|
|
115
122
|
* Delete spec branch after merge
|
|
@@ -121,14 +128,14 @@ export async function deleteSpecBranch(wuId, git) {
|
|
|
121
128
|
const specBranch = getSpecBranchName(wuId);
|
|
122
129
|
try {
|
|
123
130
|
// Delete local branch if exists
|
|
124
|
-
await git.
|
|
131
|
+
await git.deleteBranch(specBranch);
|
|
125
132
|
}
|
|
126
133
|
catch {
|
|
127
134
|
// Ignore if local branch doesn't exist
|
|
128
135
|
}
|
|
129
136
|
try {
|
|
130
137
|
// Delete remote branch
|
|
131
|
-
await git.
|
|
138
|
+
await git.raw([GIT_COMMANDS.PUSH, REMOTES.ORIGIN, GIT_FLAGS.DELETE_REMOTE, specBranch]);
|
|
132
139
|
}
|
|
133
140
|
catch {
|
|
134
141
|
// Ignore if remote branch doesn't exist
|
|
@@ -176,8 +183,8 @@ export async function getWUSource(wuId, git) {
|
|
|
176
183
|
*/
|
|
177
184
|
export async function createSpecBranch(wuId, git) {
|
|
178
185
|
const specBranch = getSpecBranchName(wuId);
|
|
179
|
-
// Create local branch
|
|
180
|
-
await git.
|
|
186
|
+
// Create local branch and checkout
|
|
187
|
+
await git.createBranch(specBranch);
|
|
181
188
|
}
|
|
182
189
|
/**
|
|
183
190
|
* Push spec branch to origin
|
|
@@ -188,5 +195,5 @@ export async function createSpecBranch(wuId, git) {
|
|
|
188
195
|
export async function pushSpecBranch(wuId, git) {
|
|
189
196
|
const specBranch = getSpecBranchName(wuId);
|
|
190
197
|
// Push to origin
|
|
191
|
-
await git.push(
|
|
198
|
+
await git.push(REMOTES.ORIGIN, specBranch);
|
|
192
199
|
}
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* Provides email normalization and domain inference for WU ownership.
|
|
5
5
|
* Converts plain usernames (e.g., "tom") to email format (e.g., "tom@hellm.ai")
|
|
6
6
|
* using domain from git config or .lumenflow.config.yaml.
|
|
7
|
+
*
|
|
8
|
+
* WU-1068: Removed hardcoded patientpath.co.uk domain. Domain is now inferred
|
|
9
|
+
* from git config user.email or .lumenflow.config.yaml OWNER_EMAIL.
|
|
7
10
|
*/
|
|
8
11
|
/**
|
|
9
12
|
* Default domain fallback when git config and lumenflow config unavailable
|
|
13
|
+
* WU-1068: Changed from hardcoded 'patientpath.co.uk' to generic default
|
|
10
14
|
*/
|
|
11
|
-
export declare const DEFAULT_DOMAIN
|
|
15
|
+
export declare const DEFAULT_DOMAIN: string;
|
|
12
16
|
/**
|
|
13
17
|
* Check if a value is a valid email address (simple check)
|
|
14
18
|
*
|
package/dist/user-normalizer.js
CHANGED
|
@@ -4,14 +4,19 @@
|
|
|
4
4
|
* Provides email normalization and domain inference for WU ownership.
|
|
5
5
|
* Converts plain usernames (e.g., "tom") to email format (e.g., "tom@hellm.ai")
|
|
6
6
|
* using domain from git config or .lumenflow.config.yaml.
|
|
7
|
+
*
|
|
8
|
+
* WU-1068: Removed hardcoded patientpath.co.uk domain. Domain is now inferred
|
|
9
|
+
* from git config user.email or .lumenflow.config.yaml OWNER_EMAIL.
|
|
7
10
|
*/
|
|
8
11
|
import { readFile, access } from 'node:fs/promises';
|
|
9
12
|
import { join } from 'node:path';
|
|
10
13
|
import { getGitForCwd } from './git-adapter.js';
|
|
14
|
+
import { DEFAULTS } from './wu-constants.js';
|
|
11
15
|
/**
|
|
12
16
|
* Default domain fallback when git config and lumenflow config unavailable
|
|
17
|
+
* WU-1068: Changed from hardcoded 'patientpath.co.uk' to generic default
|
|
13
18
|
*/
|
|
14
|
-
export const DEFAULT_DOMAIN =
|
|
19
|
+
export const DEFAULT_DOMAIN = DEFAULTS.EMAIL_DOMAIN;
|
|
15
20
|
/**
|
|
16
21
|
* Minimum length for a valid email local part
|
|
17
22
|
*/
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import nhsValidator from 'nhs-number-validator';
|
|
14
14
|
import { isValid as isValidPostcode, parse as parsePostcode } from 'postcode';
|
|
15
15
|
import { PHI_TYPES, MEDICAL_CONTEXT_KEYWORDS, MEDICAL_CONTEXT_WINDOW_SIZE, TEST_NHS_NUMBERS, NHS_TEST_PREFIX, TEST_POSTCODES, TEST_DATA_MARKERS, EXCLUDED_PATH_PATTERNS, NHS_CANDIDATE_PATTERN, } from './phi-constants.js';
|
|
16
|
+
import { PHI_CONFIG } from '../wu-constants.js';
|
|
16
17
|
/**
|
|
17
18
|
* Check if a file path should be excluded from PHI scanning
|
|
18
19
|
*
|
|
@@ -137,6 +138,11 @@ export function scanForPHI(content, options = {}) {
|
|
|
137
138
|
matches: [],
|
|
138
139
|
warnings: [],
|
|
139
140
|
};
|
|
141
|
+
// WU-1068: PHI scanning is gated behind config flag
|
|
142
|
+
// Projects must explicitly opt-in via LUMENFLOW_PHI_ENABLED=1 or config
|
|
143
|
+
if (!PHI_CONFIG.ENABLED) {
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
140
146
|
// Handle null/undefined/empty content
|
|
141
147
|
if (!content || typeof content !== 'string' || content.trim() === '') {
|
|
142
148
|
return result;
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
* pnpm monorepos create node_modules in each package with symlinks
|
|
19
19
|
* to the .pnpm store. turbo typecheck and tests need these to resolve imports.
|
|
20
20
|
*
|
|
21
|
+
* WU-1068: Removed @patientpath references. Only @lumenflow packages are
|
|
22
|
+
* relevant to the LumenFlow framework. Project-specific paths should be
|
|
23
|
+
* configured in .lumenflow.config.yaml.
|
|
24
|
+
*
|
|
21
25
|
* @type {string[]}
|
|
22
26
|
*/
|
|
23
27
|
export declare const NESTED_PACKAGE_PATHS: string[];
|
package/dist/worktree-symlink.js
CHANGED
|
@@ -43,30 +43,24 @@ const PNPM_DIR = '.pnpm';
|
|
|
43
43
|
* pnpm monorepos create node_modules in each package with symlinks
|
|
44
44
|
* to the .pnpm store. turbo typecheck and tests need these to resolve imports.
|
|
45
45
|
*
|
|
46
|
+
* WU-1068: Removed @patientpath references. Only @lumenflow packages are
|
|
47
|
+
* relevant to the LumenFlow framework. Project-specific paths should be
|
|
48
|
+
* configured in .lumenflow.config.yaml.
|
|
49
|
+
*
|
|
46
50
|
* @type {string[]}
|
|
47
51
|
*/
|
|
48
52
|
export const NESTED_PACKAGE_PATHS = [
|
|
49
|
-
// Packages -
|
|
50
|
-
'packages/
|
|
51
|
-
|
|
52
|
-
'packages/@
|
|
53
|
-
'packages/@
|
|
54
|
-
'packages/@
|
|
55
|
-
'packages/@
|
|
56
|
-
'packages/@
|
|
57
|
-
//
|
|
58
|
-
'packages/@lumenflow/api',
|
|
59
|
-
'packages/@lumenflow/application',
|
|
60
|
-
'packages/@lumenflow/infrastructure',
|
|
61
|
-
// Packages - lumenflow-*
|
|
62
|
-
'packages/lumenflow-cli',
|
|
63
|
-
'packages/lumenflow-tools',
|
|
64
|
-
// Packages - beacon-explainer (WU-2427: added for typecheck resolution)
|
|
65
|
-
'packages/beacon-explainer',
|
|
66
|
-
// Apps
|
|
53
|
+
// Packages - @lumenflow/*
|
|
54
|
+
'packages/@lumenflow/core',
|
|
55
|
+
'packages/@lumenflow/cli',
|
|
56
|
+
'packages/@lumenflow/memory',
|
|
57
|
+
'packages/@lumenflow/agent',
|
|
58
|
+
'packages/@lumenflow/metrics',
|
|
59
|
+
'packages/@lumenflow/initiatives',
|
|
60
|
+
'packages/@lumenflow/shims',
|
|
61
|
+
// Apps (generic placeholders)
|
|
67
62
|
'apps/web',
|
|
68
|
-
'apps/
|
|
69
|
-
'apps/hellm-ai', // WU-2427: added for typecheck resolution
|
|
63
|
+
'apps/docs',
|
|
70
64
|
];
|
|
71
65
|
/**
|
|
72
66
|
* Check if a symlink target points into a worktrees directory
|