@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.
@@ -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
@@ -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(2));
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('/') ? relativePath.slice(1) : relativePath;
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}-plan.md`;
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}-plan.md`;
207
- return `${LUMENFLOW_PROTOCOL}${PLANS_SUBDIR}/${filename}`;
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/@patientpath/application/',
47
- 'packages/@patientpath/prompts/',
48
- 'packages/@patientpath/ports/',
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.
@@ -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
- const pattern = 'packages/@patientpath/prompts/orchestrator-*/**/*.yaml';
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
@@ -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
- const pattern = 'packages/@patientpath/prompts/**/*.yaml';
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 { SimpleGit } from 'simple-git';
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: SimpleGit): Promise<boolean>;
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: SimpleGit): Promise<boolean>;
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: SimpleGit): Promise<void>;
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: SimpleGit): Promise<void>;
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: SimpleGit): Promise<WUSourceType>;
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: SimpleGit): Promise<void>;
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: SimpleGit): Promise<void>;
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 `origin/${getSpecBranchName(wuId)}`;
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(['ls-remote', '--heads', 'origin', getSpecBranchName(wuId)]);
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
- await git.raw(['ls-tree', 'origin/main', '--', wuPath]);
87
- return true;
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('origin', specBranch);
117
+ await git.fetch(REMOTES.ORIGIN, specBranch);
111
118
  // Merge with fast-forward only (safe merge)
112
- await git.merge([originSpecBranch, '--ff-only']);
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.branch(['-d', specBranch]);
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.push(['origin', '--delete', specBranch]);
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.checkoutLocalBranch(specBranch);
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(['origin', specBranch]);
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 = "patientpath.co.uk";
15
+ export declare const DEFAULT_DOMAIN: string;
12
16
  /**
13
17
  * Check if a value is a valid email address (simple check)
14
18
  *
@@ -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 = 'patientpath.co.uk';
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[];
@@ -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 - supabase
50
- 'packages/supabase',
51
- // Packages - @patientpath/*
52
- 'packages/@patientpath/prompts',
53
- 'packages/@patientpath/shared',
54
- 'packages/@patientpath/application',
55
- 'packages/@patientpath/ports',
56
- 'packages/@patientpath/infrastructure',
57
- // Packages - @lumenflow/* (WU-2427: added for typecheck resolution)
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/mobile',
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