@lumenflow/core 1.3.3 → 1.3.5
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/adapters/filesystem-metrics.adapter.d.ts +1 -1
- package/dist/adapters/filesystem-metrics.adapter.js +1 -1
- package/dist/beacon-migration.d.ts +56 -0
- package/dist/beacon-migration.js +101 -0
- package/dist/cleanup-lock.js +3 -3
- package/dist/commands-logger.d.ts +2 -2
- package/dist/commands-logger.js +5 -5
- package/dist/core/tool-runner.d.ts +1 -1
- package/dist/core/tool-runner.js +2 -2
- package/dist/docs-path-validator.d.ts +2 -2
- package/dist/docs-path-validator.js +4 -4
- package/dist/domain/orchestration.constants.js +3 -3
- package/dist/force-bypass-audit.d.ts +2 -2
- package/dist/force-bypass-audit.js +8 -7
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/lane-lock.d.ts +1 -1
- package/dist/lane-lock.js +3 -4
- package/dist/logs-lib.d.ts +2 -2
- package/dist/logs-lib.js +5 -4
- package/dist/lumenflow-config-schema.d.ts +1 -1
- package/dist/lumenflow-config-schema.js +19 -19
- package/dist/lumenflow-config.js +1 -1
- package/dist/merge-lock.js +7 -7
- package/dist/prompt-linter.js +3 -3
- package/dist/prompt-monitor.d.ts +1 -1
- package/dist/prompt-monitor.js +5 -5
- package/dist/rebase-artifact-cleanup.d.ts +1 -1
- package/dist/rebase-artifact-cleanup.js +1 -1
- package/dist/spawn-recovery.d.ts +2 -2
- package/dist/spawn-recovery.js +6 -6
- package/dist/spawn-registry-store.d.ts +2 -2
- package/dist/spawn-registry-store.js +2 -2
- package/dist/spawn-tree.d.ts +2 -2
- package/dist/spawn-tree.js +2 -2
- package/dist/stamp-utils.d.ts +1 -1
- package/dist/stamp-utils.js +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.js +1 -1
- package/dist/wu-checkpoint.js +4 -4
- package/dist/wu-constants.d.ts +67 -4
- package/dist/wu-constants.js +41 -15
- package/dist/wu-done-branch-only.js +2 -2
- package/dist/wu-done-inputs.js +1 -1
- package/dist/wu-done-validation.js +2 -2
- package/dist/wu-done-worktree.js +4 -4
- package/dist/wu-paths.js +1 -1
- package/dist/wu-recovery.d.ts +4 -4
- package/dist/wu-recovery.js +8 -8
- package/dist/wu-repair-core.js +4 -4
- package/dist/wu-spawn-helpers.d.ts +1 -1
- package/dist/wu-spawn-helpers.js +3 -2
- package/dist/wu-spawn.js +7 -7
- package/dist/wu-state-store.d.ts +2 -2
- package/dist/wu-state-store.js +2 -2
- package/package.json +11 -11
- package/dist/spec-branch-helpers.d.ts +0 -118
- package/dist/spec-branch-helpers.js +0 -199
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Implements MetricsCollector port by reading from filesystem:
|
|
6
6
|
* - WU YAML files (docs/04-operations/tasks/wu/)
|
|
7
7
|
* - status.md (active/blocked WUs)
|
|
8
|
-
* - telemetry files (.
|
|
8
|
+
* - telemetry files (.lumenflow/telemetry/)
|
|
9
9
|
*
|
|
10
10
|
* Library-First Approach:
|
|
11
11
|
* - fast-glob: File discovery
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Implements MetricsCollector port by reading from filesystem:
|
|
6
6
|
* - WU YAML files (docs/04-operations/tasks/wu/)
|
|
7
7
|
* - status.md (active/blocked WUs)
|
|
8
|
-
* - telemetry files (.
|
|
8
|
+
* - telemetry files (.lumenflow/telemetry/)
|
|
9
9
|
*
|
|
10
10
|
* Library-First Approach:
|
|
11
11
|
* - fast-glob: File discovery
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file beacon-migration.ts
|
|
3
|
+
* @description Migration utility for renaming .beacon directories to .lumenflow (WU-1075)
|
|
4
|
+
*
|
|
5
|
+
* This module provides a one-time migration function that renames the legacy
|
|
6
|
+
* .beacon directory to .lumenflow. It's safe to run multiple times - it will
|
|
7
|
+
* only migrate if .beacon exists and .lumenflow does not.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { migrateBeaconToLumenflow } from '@lumenflow/core';
|
|
12
|
+
*
|
|
13
|
+
* // Run migration in project root
|
|
14
|
+
* const result = migrateBeaconToLumenflow();
|
|
15
|
+
* if (result.migrated) {
|
|
16
|
+
* console.log('Successfully migrated .beacon/ → .lumenflow/');
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Result of a migration attempt
|
|
22
|
+
*/
|
|
23
|
+
export interface MigrationResult {
|
|
24
|
+
/** Whether migration was performed */
|
|
25
|
+
migrated: boolean;
|
|
26
|
+
/** Reason for the result */
|
|
27
|
+
reason: 'migrated' | 'already_migrated' | 'no_legacy_dir' | 'both_exist';
|
|
28
|
+
/** Path that was migrated from (if migrated) */
|
|
29
|
+
fromPath?: string;
|
|
30
|
+
/** Path that was migrated to (if migrated) */
|
|
31
|
+
toPath?: string;
|
|
32
|
+
/** Error message if migration failed */
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Migrate .beacon directory to .lumenflow
|
|
37
|
+
*
|
|
38
|
+
* This function safely renames the legacy .beacon directory to .lumenflow.
|
|
39
|
+
* It handles the following scenarios:
|
|
40
|
+
*
|
|
41
|
+
* - .beacon exists, .lumenflow does not → Migrate (rename)
|
|
42
|
+
* - .beacon does not exist, .lumenflow exists → Already migrated (no-op)
|
|
43
|
+
* - Neither exists → No legacy directory (no-op)
|
|
44
|
+
* - Both exist → Conflict, manual resolution needed
|
|
45
|
+
*
|
|
46
|
+
* @param {string} [baseDir=process.cwd()] - Base directory to check for migration
|
|
47
|
+
* @returns {MigrationResult} Result of the migration attempt
|
|
48
|
+
*/
|
|
49
|
+
export declare function migrateBeaconToLumenflow(baseDir?: string): MigrationResult;
|
|
50
|
+
/**
|
|
51
|
+
* Check if migration is needed without performing it
|
|
52
|
+
*
|
|
53
|
+
* @param {string} [baseDir=process.cwd()] - Base directory to check
|
|
54
|
+
* @returns {boolean} True if .beacon exists and .lumenflow does not
|
|
55
|
+
*/
|
|
56
|
+
export declare function needsMigration(baseDir?: string): boolean;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file beacon-migration.ts
|
|
3
|
+
* @description Migration utility for renaming .beacon directories to .lumenflow (WU-1075)
|
|
4
|
+
*
|
|
5
|
+
* This module provides a one-time migration function that renames the legacy
|
|
6
|
+
* .beacon directory to .lumenflow. It's safe to run multiple times - it will
|
|
7
|
+
* only migrate if .beacon exists and .lumenflow does not.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { migrateBeaconToLumenflow } from '@lumenflow/core';
|
|
12
|
+
*
|
|
13
|
+
* // Run migration in project root
|
|
14
|
+
* const result = migrateBeaconToLumenflow();
|
|
15
|
+
* if (result.migrated) {
|
|
16
|
+
* console.log('Successfully migrated .beacon/ → .lumenflow/');
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import * as fs from 'fs';
|
|
21
|
+
import * as path from 'path';
|
|
22
|
+
import { LUMENFLOW_PATHS } from './wu-constants.js';
|
|
23
|
+
/** Legacy directory name that was used before v1.5.0 */
|
|
24
|
+
const LEGACY_BEACON_DIR = '.beacon';
|
|
25
|
+
/**
|
|
26
|
+
* Migrate .beacon directory to .lumenflow
|
|
27
|
+
*
|
|
28
|
+
* This function safely renames the legacy .beacon directory to .lumenflow.
|
|
29
|
+
* It handles the following scenarios:
|
|
30
|
+
*
|
|
31
|
+
* - .beacon exists, .lumenflow does not → Migrate (rename)
|
|
32
|
+
* - .beacon does not exist, .lumenflow exists → Already migrated (no-op)
|
|
33
|
+
* - Neither exists → No legacy directory (no-op)
|
|
34
|
+
* - Both exist → Conflict, manual resolution needed
|
|
35
|
+
*
|
|
36
|
+
* @param {string} [baseDir=process.cwd()] - Base directory to check for migration
|
|
37
|
+
* @returns {MigrationResult} Result of the migration attempt
|
|
38
|
+
*/
|
|
39
|
+
export function migrateBeaconToLumenflow(baseDir = process.cwd()) {
|
|
40
|
+
const legacyPath = path.join(baseDir, LEGACY_BEACON_DIR);
|
|
41
|
+
const newPath = path.join(baseDir, LUMENFLOW_PATHS.BASE);
|
|
42
|
+
const legacyExists = fs.existsSync(legacyPath);
|
|
43
|
+
const newExists = fs.existsSync(newPath);
|
|
44
|
+
// Both exist - conflict
|
|
45
|
+
if (legacyExists && newExists) {
|
|
46
|
+
return {
|
|
47
|
+
migrated: false,
|
|
48
|
+
reason: 'both_exist',
|
|
49
|
+
fromPath: legacyPath,
|
|
50
|
+
toPath: newPath,
|
|
51
|
+
error: 'Both .beacon and .lumenflow directories exist. ' +
|
|
52
|
+
'Please manually resolve by removing or merging .beacon into .lumenflow.',
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Already migrated
|
|
56
|
+
if (!legacyExists && newExists) {
|
|
57
|
+
return {
|
|
58
|
+
migrated: false,
|
|
59
|
+
reason: 'already_migrated',
|
|
60
|
+
toPath: newPath,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// No legacy directory
|
|
64
|
+
if (!legacyExists && !newExists) {
|
|
65
|
+
return {
|
|
66
|
+
migrated: false,
|
|
67
|
+
reason: 'no_legacy_dir',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Migrate: rename .beacon → .lumenflow
|
|
71
|
+
try {
|
|
72
|
+
fs.renameSync(legacyPath, newPath);
|
|
73
|
+
return {
|
|
74
|
+
migrated: true,
|
|
75
|
+
reason: 'migrated',
|
|
76
|
+
fromPath: legacyPath,
|
|
77
|
+
toPath: newPath,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
82
|
+
return {
|
|
83
|
+
migrated: false,
|
|
84
|
+
reason: 'migrated',
|
|
85
|
+
fromPath: legacyPath,
|
|
86
|
+
toPath: newPath,
|
|
87
|
+
error: `Failed to rename: ${error}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if migration is needed without performing it
|
|
93
|
+
*
|
|
94
|
+
* @param {string} [baseDir=process.cwd()] - Base directory to check
|
|
95
|
+
* @returns {boolean} True if .beacon exists and .lumenflow does not
|
|
96
|
+
*/
|
|
97
|
+
export function needsMigration(baseDir = process.cwd()) {
|
|
98
|
+
const legacyPath = path.join(baseDir, LEGACY_BEACON_DIR);
|
|
99
|
+
const newPath = path.join(baseDir, LUMENFLOW_PATHS.BASE);
|
|
100
|
+
return fs.existsSync(legacyPath) && !fs.existsSync(newPath);
|
|
101
|
+
}
|
package/dist/cleanup-lock.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, openSync, closeSync, } from 'node:fs';
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import crypto from 'node:crypto';
|
|
25
|
-
import { LOG_PREFIX, EMOJI } from './wu-constants.js';
|
|
25
|
+
import { LOG_PREFIX, EMOJI, LUMENFLOW_PATHS } from './wu-constants.js';
|
|
26
26
|
import { createError, ErrorCodes } from './error-handler.js';
|
|
27
27
|
/**
|
|
28
28
|
* Default timeout for waiting to acquire lock (ms)
|
|
@@ -35,7 +35,7 @@ export const CLEANUP_LOCK_TIMEOUT_MS = 30000; // 30 seconds
|
|
|
35
35
|
* Cleanup is slower than merge, so longer timeout
|
|
36
36
|
*/
|
|
37
37
|
export const CLEANUP_LOCK_STALE_MS = 5 * 60 * 1000; // 5 minutes
|
|
38
|
-
/** Lock file name within .
|
|
38
|
+
/** Lock file name within .lumenflow directory */
|
|
39
39
|
const LOCK_FILE_NAME = 'cleanup.lock';
|
|
40
40
|
/**
|
|
41
41
|
* Polling interval for lock acquisition retries
|
|
@@ -49,7 +49,7 @@ const LOCK_POLL_INTERVAL_MS = 500;
|
|
|
49
49
|
*/
|
|
50
50
|
function getLockPath(options = {}) {
|
|
51
51
|
const baseDir = options.baseDir || process.cwd();
|
|
52
|
-
return path.join(baseDir,
|
|
52
|
+
return path.join(baseDir, LUMENFLOW_PATHS.BASE, LOCK_FILE_NAME);
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Read lock file contents
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Part of WU-630: Detective layer (Layer 3 of 4-layer defense)
|
|
4
4
|
* Part of WU-1552: Complete logging integration with user/outcome tracking
|
|
5
5
|
*
|
|
6
|
-
* Logs all git commands to .
|
|
6
|
+
* Logs all git commands to .lumenflow/commands.log for post-execution analysis.
|
|
7
7
|
* Provides defense-in-depth even if git shim is bypassed.
|
|
8
8
|
*
|
|
9
9
|
* Log format (v2): timestamp | command | branch | worktree | user | outcome
|
|
@@ -43,7 +43,7 @@ export interface LogGitCommandOptions {
|
|
|
43
43
|
/**
|
|
44
44
|
* Log a git command to the commands log
|
|
45
45
|
* @param {string[]} args - Git command arguments (e.g., ['status'], ['add', '.'])
|
|
46
|
-
* @param {string} logPath - Path to log file (defaults to .
|
|
46
|
+
* @param {string} logPath - Path to log file (defaults to .lumenflow/commands.log)
|
|
47
47
|
* @param {LogGitCommandOptions} options - Additional logging options (WU-1552)
|
|
48
48
|
*/
|
|
49
49
|
export declare function logGitCommand(args: any, logPath?: string, options?: LogGitCommandOptions): void;
|
package/dist/commands-logger.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Part of WU-630: Detective layer (Layer 3 of 4-layer defense)
|
|
4
4
|
* Part of WU-1552: Complete logging integration with user/outcome tracking
|
|
5
5
|
*
|
|
6
|
-
* Logs all git commands to .
|
|
6
|
+
* Logs all git commands to .lumenflow/commands.log for post-execution analysis.
|
|
7
7
|
* Provides defense-in-depth even if git shim is bypassed.
|
|
8
8
|
*
|
|
9
9
|
* Log format (v2): timestamp | command | branch | worktree | user | outcome
|
|
@@ -17,11 +17,11 @@ import fs from 'node:fs';
|
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
import { getCurrentBranch, isMainWorktree } from './wu-helpers.js';
|
|
20
|
-
import {
|
|
20
|
+
import { GIT_FLAGS, STRING_LITERALS, LUMENFLOW_PATHS } from './wu-constants.js';
|
|
21
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
22
22
|
const __dirname = path.dirname(__filename);
|
|
23
23
|
// Default log path (can be overridden for testing)
|
|
24
|
-
const DEFAULT_LOG_PATH = path.resolve(__dirname, '../..',
|
|
24
|
+
const DEFAULT_LOG_PATH = path.resolve(__dirname, '../..', LUMENFLOW_PATHS.COMMANDS_LOG);
|
|
25
25
|
// Banned patterns (same as git shim)
|
|
26
26
|
const BANNED_PATTERNS = [
|
|
27
27
|
{ command: 'reset', flags: [GIT_FLAGS.HARD] },
|
|
@@ -53,7 +53,7 @@ export const COMMAND_LOG = {
|
|
|
53
53
|
/**
|
|
54
54
|
* Log a git command to the commands log
|
|
55
55
|
* @param {string[]} args - Git command arguments (e.g., ['status'], ['add', '.'])
|
|
56
|
-
* @param {string} logPath - Path to log file (defaults to .
|
|
56
|
+
* @param {string} logPath - Path to log file (defaults to .lumenflow/commands.log)
|
|
57
57
|
* @param {LogGitCommandOptions} options - Additional logging options (WU-1552)
|
|
58
58
|
*/
|
|
59
59
|
export function logGitCommand(args, logPath = DEFAULT_LOG_PATH, options = {}) {
|
|
@@ -75,7 +75,7 @@ export function logGitCommand(args, logPath = DEFAULT_LOG_PATH, options = {}) {
|
|
|
75
75
|
const outcome = options.outcome || COMMAND_LOG.OUTCOME.ALLOWED;
|
|
76
76
|
// New format (v2): timestamp | command | branch | worktree | user | outcome
|
|
77
77
|
const logEntry = `${timestamp} | ${command} | ${branch} | ${worktree} | ${user} | ${outcome}\n`;
|
|
78
|
-
// Ensure .
|
|
78
|
+
// Ensure .lumenflow directory exists
|
|
79
79
|
const logDir = path.dirname(logPath);
|
|
80
80
|
if (!fs.existsSync(logDir)) {
|
|
81
81
|
fs.mkdirSync(logDir, { recursive: true });
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Input validation via Zod schemas (tool.schemas.ts)
|
|
7
7
|
* - Worktree context detection (worktree-guard.mjs)
|
|
8
8
|
* - Scope validation against code_paths (scope-checker.mjs)
|
|
9
|
-
* - Audit logging for telemetry (.
|
|
9
|
+
* - Audit logging for telemetry (.lumenflow/telemetry/tools.ndjson)
|
|
10
10
|
* - Consistent error handling with agent-friendly messages
|
|
11
11
|
*
|
|
12
12
|
* Usage:
|
package/dist/core/tool-runner.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Input validation via Zod schemas (tool.schemas.ts)
|
|
7
7
|
* - Worktree context detection (worktree-guard.mjs)
|
|
8
8
|
* - Scope validation against code_paths (scope-checker.mjs)
|
|
9
|
-
* - Audit logging for telemetry (.
|
|
9
|
+
* - Audit logging for telemetry (.lumenflow/telemetry/tools.ndjson)
|
|
10
10
|
* - Consistent error handling with agent-friendly messages
|
|
11
11
|
*
|
|
12
12
|
* Usage:
|
|
@@ -97,7 +97,7 @@ function createAuditLogger() {
|
|
|
97
97
|
return (entry) => {
|
|
98
98
|
// Write to NDJSON telemetry file
|
|
99
99
|
// Implementation deferred - currently no-op for testing
|
|
100
|
-
// Will integrate with .
|
|
100
|
+
// Will integrate with .lumenflow/telemetry/tools.ndjson in future WU
|
|
101
101
|
void entry;
|
|
102
102
|
};
|
|
103
103
|
}
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* - ai/**
|
|
12
12
|
* - .claude/**
|
|
13
13
|
* - *.md (markdown files anywhere)
|
|
14
|
-
* - .
|
|
15
|
-
* - .
|
|
14
|
+
* - .lumenflow/stamps/**
|
|
15
|
+
* - .lumenflow/state/wu-events.jsonl (tooling-managed metadata)
|
|
16
16
|
*
|
|
17
17
|
* Forbidden paths:
|
|
18
18
|
* - apps/**
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
* - ai/**
|
|
12
12
|
* - .claude/**
|
|
13
13
|
* - *.md (markdown files anywhere)
|
|
14
|
-
* - .
|
|
15
|
-
* - .
|
|
14
|
+
* - .lumenflow/stamps/**
|
|
15
|
+
* - .lumenflow/state/wu-events.jsonl (tooling-managed metadata)
|
|
16
16
|
*
|
|
17
17
|
* Forbidden paths:
|
|
18
18
|
* - apps/**
|
|
@@ -88,8 +88,8 @@ export function getAllowedPathsDescription() {
|
|
|
88
88
|
- .claude/** (agent configuration and skills)
|
|
89
89
|
- docs/** (technical documentation)
|
|
90
90
|
- *.md (markdown files)
|
|
91
|
-
- .
|
|
92
|
-
- .
|
|
91
|
+
- .lumenflow/stamps/** (completion stamps)
|
|
92
|
+
- .lumenflow/state/${WU_EVENTS_FILE_NAME} (WU lifecycle event log)
|
|
93
93
|
- tools/__tests__/** (test files only)
|
|
94
94
|
- packages/**/__tests__/** (test files only)`;
|
|
95
95
|
}
|
|
@@ -91,7 +91,7 @@ export const FILESYSTEM_PATHS = {
|
|
|
91
91
|
WU_DIR: 'docs/04-operations/tasks/wu',
|
|
92
92
|
STATUS_FILE: 'docs/04-operations/tasks/status.md',
|
|
93
93
|
BACKLOG_FILE: 'docs/04-operations/tasks/backlog.md',
|
|
94
|
-
TELEMETRY_DIR: '.
|
|
95
|
-
STAMPS_DIR: '.
|
|
96
|
-
SESSION_FILE: '.
|
|
94
|
+
TELEMETRY_DIR: '.lumenflow/telemetry',
|
|
95
|
+
STAMPS_DIR: '.lumenflow/stamps',
|
|
96
|
+
SESSION_FILE: '.lumenflow/sessions/current.json',
|
|
97
97
|
};
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* WU-1070: Force Bypass Audit Logging
|
|
3
3
|
*
|
|
4
4
|
* Provides audit logging for LUMENFLOW_FORCE bypass usage.
|
|
5
|
-
* All hooks log bypass events to .
|
|
5
|
+
* All hooks log bypass events to .lumenflow/force-bypasses.log for accountability.
|
|
6
6
|
*
|
|
7
7
|
* Key principles:
|
|
8
8
|
* - FAIL-OPEN: Audit logging must never block the bypass itself
|
|
9
9
|
* - WARN ON MISSING REASON: stderr warning if LUMENFLOW_FORCE_REASON not set
|
|
10
|
-
* - GIT-TRACKED: .
|
|
10
|
+
* - GIT-TRACKED: .lumenflow/force-bypasses.log is version controlled
|
|
11
11
|
*
|
|
12
12
|
* Log format:
|
|
13
13
|
* ISO_TIMESTAMP | HOOK_NAME | GIT_USER | BRANCH | REASON | CWD
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* WU-1070: Force Bypass Audit Logging
|
|
3
3
|
*
|
|
4
4
|
* Provides audit logging for LUMENFLOW_FORCE bypass usage.
|
|
5
|
-
* All hooks log bypass events to .
|
|
5
|
+
* All hooks log bypass events to .lumenflow/force-bypasses.log for accountability.
|
|
6
6
|
*
|
|
7
7
|
* Key principles:
|
|
8
8
|
* - FAIL-OPEN: Audit logging must never block the bypass itself
|
|
9
9
|
* - WARN ON MISSING REASON: stderr warning if LUMENFLOW_FORCE_REASON not set
|
|
10
|
-
* - GIT-TRACKED: .
|
|
10
|
+
* - GIT-TRACKED: .lumenflow/force-bypasses.log is version controlled
|
|
11
11
|
*
|
|
12
12
|
* Log format:
|
|
13
13
|
* ISO_TIMESTAMP | HOOK_NAME | GIT_USER | BRANCH | REASON | CWD
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { appendFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
19
19
|
import { execSync } from 'node:child_process';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
|
+
import { LUMENFLOW_PATHS } from './wu-constants.js';
|
|
21
22
|
/**
|
|
22
23
|
* Environment variable names for force bypass
|
|
23
24
|
*/
|
|
@@ -26,7 +27,7 @@ export const FORCE_REASON_ENV_VAR = 'LUMENFLOW_FORCE_REASON';
|
|
|
26
27
|
/**
|
|
27
28
|
* Log file path relative to project root
|
|
28
29
|
*/
|
|
29
|
-
const LOG_FILE_NAME =
|
|
30
|
+
const LOG_FILE_NAME = LUMENFLOW_PATHS.FORCE_BYPASSES;
|
|
30
31
|
/**
|
|
31
32
|
* Check if LUMENFLOW_FORCE bypass is active
|
|
32
33
|
*
|
|
@@ -102,10 +103,10 @@ export function logForceBypass(hookName, projectRoot) {
|
|
|
102
103
|
// Write to log file (fail-open)
|
|
103
104
|
try {
|
|
104
105
|
const logPath = getAuditLogPath(projectRoot);
|
|
105
|
-
const
|
|
106
|
-
// Ensure .
|
|
107
|
-
if (!existsSync(
|
|
108
|
-
mkdirSync(
|
|
106
|
+
const lumenflowDir = join(projectRoot, LUMENFLOW_PATHS.BASE);
|
|
107
|
+
// Ensure .lumenflow directory exists
|
|
108
|
+
if (!existsSync(lumenflowDir)) {
|
|
109
|
+
mkdirSync(lumenflowDir, { recursive: true });
|
|
109
110
|
}
|
|
110
111
|
appendFileSync(logPath, logLine);
|
|
111
112
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './arg-parser.js';
|
|
|
7
7
|
export * from './date-utils.js';
|
|
8
8
|
export * from './error-handler.js';
|
|
9
9
|
export * from './retry-strategy.js';
|
|
10
|
+
export * from './beacon-migration.js';
|
|
10
11
|
export { DEFAULT_DOMAIN, inferDefaultDomain, normalizeToEmail, isValidEmail, } from './user-normalizer.js';
|
|
11
12
|
export * from './git-adapter.js';
|
|
12
13
|
export * from './state-machine.js';
|
|
@@ -44,3 +45,4 @@ export * from './gates-config.js';
|
|
|
44
45
|
export * from './branch-check.js';
|
|
45
46
|
export * from './lumenflow-home.js';
|
|
46
47
|
export * from './force-bypass-audit.js';
|
|
48
|
+
export { LUMENFLOW_PATHS, BEACON_PATHS } from './wu-constants.js';
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ export * from './arg-parser.js';
|
|
|
9
9
|
export * from './date-utils.js';
|
|
10
10
|
export * from './error-handler.js';
|
|
11
11
|
export * from './retry-strategy.js';
|
|
12
|
+
// Migration utilities (WU-1075)
|
|
13
|
+
export * from './beacon-migration.js';
|
|
12
14
|
// User normalizer (explicit exports to avoid conflicts)
|
|
13
15
|
export { DEFAULT_DOMAIN, inferDefaultDomain, normalizeToEmail, isValidEmail, } from './user-normalizer.js';
|
|
14
16
|
// Git operations
|
|
@@ -67,3 +69,5 @@ export * from './branch-check.js';
|
|
|
67
69
|
export * from './lumenflow-home.js';
|
|
68
70
|
// WU-1070: Force bypass audit logging
|
|
69
71
|
export * from './force-bypass-audit.js';
|
|
72
|
+
// WU-1075: LumenFlow directory paths (exported from wu-constants)
|
|
73
|
+
export { LUMENFLOW_PATHS, BEACON_PATHS } from './wu-constants.js';
|
package/dist/lane-lock.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* which fails if the file already exists. This prevents the race condition where
|
|
10
10
|
* parallel agents could both read status.md before either updates it.
|
|
11
11
|
*
|
|
12
|
-
* Lock file location: .
|
|
12
|
+
* Lock file location: .lumenflow/locks/<lane-kebab>.lock
|
|
13
13
|
* Lock file format: JSON with wuId, timestamp, agentSession, pid
|
|
14
14
|
*
|
|
15
15
|
* @see WU-1603 - Race condition fix for wu:claim
|
package/dist/lane-lock.js
CHANGED
|
@@ -9,19 +9,18 @@
|
|
|
9
9
|
* which fails if the file already exists. This prevents the race condition where
|
|
10
10
|
* parallel agents could both read status.md before either updates it.
|
|
11
11
|
*
|
|
12
|
-
* Lock file location: .
|
|
12
|
+
* Lock file location: .lumenflow/locks/<lane-kebab>.lock
|
|
13
13
|
* Lock file format: JSON with wuId, timestamp, agentSession, pid
|
|
14
14
|
*
|
|
15
15
|
* @see WU-1603 - Race condition fix for wu:claim
|
|
16
16
|
*/
|
|
17
17
|
import { openSync, closeSync, writeFileSync, readFileSync, unlinkSync, existsSync, mkdirSync, } from 'node:fs';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
-
import { toKebab } from './wu-constants.js';
|
|
20
|
-
import { getProjectRoot } from './wu-constants.js';
|
|
19
|
+
import { toKebab, LUMENFLOW_PATHS, getProjectRoot } from './wu-constants.js';
|
|
21
20
|
/** Log prefix for lane-lock messages */
|
|
22
21
|
const LOG_PREFIX = '[lane-lock]';
|
|
23
22
|
/** Directory for lock files relative to project root */
|
|
24
|
-
const LOCKS_DIR =
|
|
23
|
+
const LOCKS_DIR = LUMENFLOW_PATHS.LOCKS_DIR;
|
|
25
24
|
/** Default stale lock threshold in hours (WU-1949: reduced from 24h to 2h) */
|
|
26
25
|
const DEFAULT_STALE_LOCK_THRESHOLD_HOURS = 2;
|
|
27
26
|
/**
|
package/dist/logs-lib.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Core library for unified log aggregation following Anthropic's agent logging patterns.
|
|
5
5
|
* Aggregates logs from multiple sources:
|
|
6
6
|
* - .logs/web.log (structured JSON from Next.js)
|
|
7
|
-
* - .
|
|
8
|
-
* - .
|
|
7
|
+
* - .lumenflow/commands.log (git command audit trail)
|
|
8
|
+
* - .lumenflow/flow.log (WU flow events)
|
|
9
9
|
* - .logs/tool-audit.ndjson (Claude Code tool usage audit)
|
|
10
10
|
*
|
|
11
11
|
* LIBRARY-FIRST: No general-purpose library exists for project-specific log
|
package/dist/logs-lib.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Core library for unified log aggregation following Anthropic's agent logging patterns.
|
|
5
5
|
* Aggregates logs from multiple sources:
|
|
6
6
|
* - .logs/web.log (structured JSON from Next.js)
|
|
7
|
-
* - .
|
|
8
|
-
* - .
|
|
7
|
+
* - .lumenflow/commands.log (git command audit trail)
|
|
8
|
+
* - .lumenflow/flow.log (WU flow events)
|
|
9
9
|
* - .logs/tool-audit.ndjson (Claude Code tool usage audit)
|
|
10
10
|
*
|
|
11
11
|
* LIBRARY-FIRST: No general-purpose library exists for project-specific log
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { existsSync, readFileSync } from 'node:fs';
|
|
18
18
|
import path from 'node:path';
|
|
19
|
+
import { LUMENFLOW_PATHS } from './wu-constants.js';
|
|
19
20
|
export const LOG_SOURCES = [
|
|
20
21
|
{ path: '.logs/web.log', source: 'web.log' },
|
|
21
|
-
{ path:
|
|
22
|
-
{ path:
|
|
22
|
+
{ path: LUMENFLOW_PATHS.COMMANDS_LOG, source: 'commands.log' },
|
|
23
|
+
{ path: LUMENFLOW_PATHS.FLOW_LOG, source: 'flow.log' },
|
|
23
24
|
{ path: '.logs/tool-audit.ndjson', source: 'tool-audit.ndjson' },
|
|
24
25
|
];
|
|
25
26
|
/**
|
|
@@ -27,7 +27,7 @@ export declare const DirectoriesSchema: z.ZodObject<{
|
|
|
27
27
|
agentsDir: z.ZodDefault<z.ZodString>;
|
|
28
28
|
}, z.core.$strip>;
|
|
29
29
|
/**
|
|
30
|
-
* Beacon paths configuration (.
|
|
30
|
+
* Beacon paths configuration (.lumenflow directory structure)
|
|
31
31
|
*/
|
|
32
32
|
export declare const BeaconPathsSchema: z.ZodObject<{
|
|
33
33
|
base: z.ZodDefault<z.ZodString>;
|
|
@@ -43,27 +43,27 @@ export const DirectoriesSchema = z.object({
|
|
|
43
43
|
agentsDir: z.string().default('.claude/agents'),
|
|
44
44
|
});
|
|
45
45
|
/**
|
|
46
|
-
* Beacon paths configuration (.
|
|
46
|
+
* Beacon paths configuration (.lumenflow directory structure)
|
|
47
47
|
*/
|
|
48
48
|
export const BeaconPathsSchema = z.object({
|
|
49
|
-
/** Base beacon directory (default: '.
|
|
50
|
-
base: z.string().default('.
|
|
51
|
-
/** State directory (default: '.
|
|
52
|
-
stateDir: z.string().default('.
|
|
53
|
-
/** Stamps directory (default: '.
|
|
54
|
-
stampsDir: z.string().default('.
|
|
55
|
-
/** Merge lock file (default: '.
|
|
56
|
-
mergeLock: z.string().default('.
|
|
57
|
-
/** Telemetry directory (default: '.
|
|
58
|
-
telemetry: z.string().default('.
|
|
59
|
-
/** Flow log file (default: '.
|
|
60
|
-
flowLog: z.string().default('.
|
|
61
|
-
/** Sessions directory (default: '.
|
|
62
|
-
sessions: z.string().default('.
|
|
63
|
-
/** Incidents directory (default: '.
|
|
64
|
-
incidents: z.string().default('.
|
|
65
|
-
/** Commands log file (default: '.
|
|
66
|
-
commandsLog: z.string().default('.
|
|
49
|
+
/** Base beacon directory (default: '.lumenflow') */
|
|
50
|
+
base: z.string().default('.lumenflow'),
|
|
51
|
+
/** State directory (default: '.lumenflow/state') */
|
|
52
|
+
stateDir: z.string().default('.lumenflow/state'),
|
|
53
|
+
/** Stamps directory (default: '.lumenflow/stamps') */
|
|
54
|
+
stampsDir: z.string().default('.lumenflow/stamps'),
|
|
55
|
+
/** Merge lock file (default: '.lumenflow/merge.lock') */
|
|
56
|
+
mergeLock: z.string().default('.lumenflow/merge.lock'),
|
|
57
|
+
/** Telemetry directory (default: '.lumenflow/telemetry') */
|
|
58
|
+
telemetry: z.string().default('.lumenflow/telemetry'),
|
|
59
|
+
/** Flow log file (default: '.lumenflow/flow.log') */
|
|
60
|
+
flowLog: z.string().default('.lumenflow/flow.log'),
|
|
61
|
+
/** Sessions directory (default: '.lumenflow/sessions') */
|
|
62
|
+
sessions: z.string().default('.lumenflow/sessions'),
|
|
63
|
+
/** Incidents directory (default: '.lumenflow/incidents') */
|
|
64
|
+
incidents: z.string().default('.lumenflow/incidents'),
|
|
65
|
+
/** Commands log file (default: '.lumenflow/commands.log') */
|
|
66
|
+
commandsLog: z.string().default('.lumenflow/commands.log'),
|
|
67
67
|
});
|
|
68
68
|
/**
|
|
69
69
|
* Git configuration
|
package/dist/lumenflow-config.js
CHANGED
|
@@ -206,7 +206,7 @@ directories:
|
|
|
206
206
|
# Agents directory
|
|
207
207
|
agentsDir: "${defaultConfig.directories.agentsDir}"
|
|
208
208
|
|
|
209
|
-
# Beacon paths (.
|
|
209
|
+
# Beacon paths (.lumenflow directory structure)
|
|
210
210
|
beacon:
|
|
211
211
|
base: "${defaultConfig.beacon.base}"
|
|
212
212
|
stampsDir: "${defaultConfig.beacon.stampsDir}"
|
package/dist/merge-lock.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
|
|
16
16
|
import path from 'node:path';
|
|
17
17
|
import crypto from 'node:crypto';
|
|
18
|
-
import { LOG_PREFIX, EMOJI } from './wu-constants.js';
|
|
18
|
+
import { LOG_PREFIX, EMOJI, LUMENFLOW_PATHS } from './wu-constants.js';
|
|
19
19
|
import { createError, ErrorCodes } from './error-handler.js';
|
|
20
20
|
/**
|
|
21
21
|
* Default timeout for waiting to acquire lock (ms)
|
|
@@ -27,7 +27,7 @@ export const MERGE_LOCK_TIMEOUT_MS = 30000; // 30 seconds
|
|
|
27
27
|
* Should be greater than expected merge operation duration
|
|
28
28
|
*/
|
|
29
29
|
export const MERGE_LOCK_STALE_MS = 60000; // 60 seconds
|
|
30
|
-
/** Lock file name within .
|
|
30
|
+
/** Lock file name within .lumenflow directory */
|
|
31
31
|
const LOCK_FILE_NAME = 'merge.lock';
|
|
32
32
|
/**
|
|
33
33
|
* Polling interval for lock acquisition retries
|
|
@@ -41,7 +41,7 @@ const LOCK_POLL_INTERVAL_MS = 500;
|
|
|
41
41
|
*/
|
|
42
42
|
function getLockPath(options = {}) {
|
|
43
43
|
const baseDir = options.baseDir || process.cwd();
|
|
44
|
-
return path.join(baseDir,
|
|
44
|
+
return path.join(baseDir, LUMENFLOW_PATHS.BASE, LOCK_FILE_NAME);
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Read lock file contents
|
|
@@ -71,10 +71,10 @@ function readLockFile(options = {}) {
|
|
|
71
71
|
*/
|
|
72
72
|
function writeLockFile(lockInfo, options = {}) {
|
|
73
73
|
const lockPath = getLockPath(options);
|
|
74
|
-
const
|
|
75
|
-
// Ensure .
|
|
76
|
-
if (!existsSync(
|
|
77
|
-
mkdirSync(
|
|
74
|
+
const lumenflowDir = path.dirname(lockPath);
|
|
75
|
+
// Ensure .lumenflow directory exists
|
|
76
|
+
if (!existsSync(lumenflowDir)) {
|
|
77
|
+
mkdirSync(lumenflowDir, { recursive: true });
|
|
78
78
|
}
|
|
79
79
|
writeFileSync(lockPath, JSON.stringify(lockInfo, null, 2));
|
|
80
80
|
}
|
package/dist/prompt-linter.js
CHANGED
|
@@ -24,7 +24,7 @@ const ROOT_DIR = resolve(__dirname, '../..');
|
|
|
24
24
|
// Default config path
|
|
25
25
|
const DEFAULT_CONFIG_PATH = resolve(ROOT_DIR, 'config/prompts/linter.yml');
|
|
26
26
|
// Telemetry cache path (for storing previous metrics)
|
|
27
|
-
const METRICS_CACHE_PATH = resolve(ROOT_DIR, '.
|
|
27
|
+
const METRICS_CACHE_PATH = resolve(ROOT_DIR, '.lumenflow/telemetry/prompt-metrics.json');
|
|
28
28
|
/**
|
|
29
29
|
* Load config from YAML file with fallback to defaults
|
|
30
30
|
* @param {string} configPath - Path to config file (optional)
|
|
@@ -139,8 +139,8 @@ async function log(level, event, data, output = {}) {
|
|
|
139
139
|
event,
|
|
140
140
|
...data,
|
|
141
141
|
};
|
|
142
|
-
// For CLI, write to .
|
|
143
|
-
const ndjsonPath = resolve(ROOT_DIR, '.
|
|
142
|
+
// For CLI, write to .lumenflow/telemetry/prompt-lint.ndjson
|
|
143
|
+
const ndjsonPath = resolve(ROOT_DIR, '.lumenflow/telemetry/prompt-lint.ndjson');
|
|
144
144
|
const line = `${JSON.stringify(entry)}${STRING_LITERALS.NEWLINE}`;
|
|
145
145
|
try {
|
|
146
146
|
const dir = dirname(ndjsonPath);
|
package/dist/prompt-monitor.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Monitors all prompts for token budget drift and hash changes.
|
|
5
5
|
* Designed to run as a GitHub Actions cron job (nightly at 2 AM).
|
|
6
6
|
*
|
|
7
|
-
* Logs to .
|
|
7
|
+
* Logs to .lumenflow/telemetry/prompt-nightly.ndjson and Axiom.
|
|
8
8
|
* Alerts if:
|
|
9
9
|
* - Any prompt ≥400 tokens (approaching cap)
|
|
10
10
|
* - Any delta >50 tokens since yesterday
|