@lumenflow/core 1.0.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/LICENSE +190 -0
- package/README.md +119 -0
- package/dist/active-wu-detector.d.ts +33 -0
- package/dist/active-wu-detector.js +106 -0
- package/dist/adapters/filesystem-metrics.adapter.d.ts +108 -0
- package/dist/adapters/filesystem-metrics.adapter.js +519 -0
- package/dist/adapters/terminal-renderer.adapter.d.ts +106 -0
- package/dist/adapters/terminal-renderer.adapter.js +337 -0
- package/dist/arg-parser.d.ts +63 -0
- package/dist/arg-parser.js +560 -0
- package/dist/backlog-editor.d.ts +98 -0
- package/dist/backlog-editor.js +179 -0
- package/dist/backlog-generator.d.ts +111 -0
- package/dist/backlog-generator.js +381 -0
- package/dist/backlog-parser.d.ts +45 -0
- package/dist/backlog-parser.js +102 -0
- package/dist/backlog-sync-validator.d.ts +78 -0
- package/dist/backlog-sync-validator.js +294 -0
- package/dist/branch-drift.d.ts +34 -0
- package/dist/branch-drift.js +51 -0
- package/dist/cleanup-install-config.d.ts +33 -0
- package/dist/cleanup-install-config.js +37 -0
- package/dist/cleanup-lock.d.ts +139 -0
- package/dist/cleanup-lock.js +313 -0
- package/dist/code-path-validator.d.ts +146 -0
- package/dist/code-path-validator.js +537 -0
- package/dist/code-paths-overlap.d.ts +55 -0
- package/dist/code-paths-overlap.js +245 -0
- package/dist/commands-logger.d.ts +77 -0
- package/dist/commands-logger.js +254 -0
- package/dist/commit-message-utils.d.ts +25 -0
- package/dist/commit-message-utils.js +41 -0
- package/dist/compliance-parser.d.ts +150 -0
- package/dist/compliance-parser.js +507 -0
- package/dist/constants/backlog-patterns.d.ts +20 -0
- package/dist/constants/backlog-patterns.js +23 -0
- package/dist/constants/dora-constants.d.ts +49 -0
- package/dist/constants/dora-constants.js +53 -0
- package/dist/constants/gate-constants.d.ts +15 -0
- package/dist/constants/gate-constants.js +15 -0
- package/dist/constants/linter-constants.d.ts +16 -0
- package/dist/constants/linter-constants.js +16 -0
- package/dist/constants/tokenizer-constants.d.ts +15 -0
- package/dist/constants/tokenizer-constants.js +15 -0
- package/dist/core/scope-checker.d.ts +97 -0
- package/dist/core/scope-checker.js +163 -0
- package/dist/core/tool-runner.d.ts +161 -0
- package/dist/core/tool-runner.js +393 -0
- package/dist/core/tool.constants.d.ts +105 -0
- package/dist/core/tool.constants.js +101 -0
- package/dist/core/tool.schemas.d.ts +226 -0
- package/dist/core/tool.schemas.js +226 -0
- package/dist/core/worktree-guard.d.ts +130 -0
- package/dist/core/worktree-guard.js +242 -0
- package/dist/coverage-gate.d.ts +108 -0
- package/dist/coverage-gate.js +196 -0
- package/dist/date-utils.d.ts +75 -0
- package/dist/date-utils.js +140 -0
- package/dist/dependency-graph.d.ts +142 -0
- package/dist/dependency-graph.js +550 -0
- package/dist/dependency-guard.d.ts +54 -0
- package/dist/dependency-guard.js +142 -0
- package/dist/dependency-validator.d.ts +105 -0
- package/dist/dependency-validator.js +154 -0
- package/dist/docs-path-validator.d.ts +36 -0
- package/dist/docs-path-validator.js +95 -0
- package/dist/domain/orchestration.constants.d.ts +99 -0
- package/dist/domain/orchestration.constants.js +97 -0
- package/dist/domain/orchestration.schemas.d.ts +280 -0
- package/dist/domain/orchestration.schemas.js +211 -0
- package/dist/domain/orchestration.types.d.ts +133 -0
- package/dist/domain/orchestration.types.js +12 -0
- package/dist/error-handler.d.ts +116 -0
- package/dist/error-handler.js +136 -0
- package/dist/file-classifiers.d.ts +62 -0
- package/dist/file-classifiers.js +108 -0
- package/dist/gates-agent-mode.d.ts +81 -0
- package/dist/gates-agent-mode.js +94 -0
- package/dist/generate-traceability.d.ts +107 -0
- package/dist/generate-traceability.js +411 -0
- package/dist/git-adapter.d.ts +395 -0
- package/dist/git-adapter.js +649 -0
- package/dist/git-staged-validator.d.ts +32 -0
- package/dist/git-staged-validator.js +48 -0
- package/dist/hardcoded-strings.d.ts +61 -0
- package/dist/hardcoded-strings.js +270 -0
- package/dist/incremental-lint.d.ts +78 -0
- package/dist/incremental-lint.js +129 -0
- package/dist/incremental-test.d.ts +39 -0
- package/dist/incremental-test.js +61 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +61 -0
- package/dist/invariants/check-automated-tests.d.ts +50 -0
- package/dist/invariants/check-automated-tests.js +166 -0
- package/dist/invariants-runner.d.ts +103 -0
- package/dist/invariants-runner.js +527 -0
- package/dist/lane-checker.d.ts +50 -0
- package/dist/lane-checker.js +319 -0
- package/dist/lane-inference.d.ts +39 -0
- package/dist/lane-inference.js +195 -0
- package/dist/lane-lock.d.ts +211 -0
- package/dist/lane-lock.js +474 -0
- package/dist/lane-validator.d.ts +48 -0
- package/dist/lane-validator.js +114 -0
- package/dist/logs-lib.d.ts +104 -0
- package/dist/logs-lib.js +207 -0
- package/dist/lumenflow-config-schema.d.ts +272 -0
- package/dist/lumenflow-config-schema.js +207 -0
- package/dist/lumenflow-config.d.ts +95 -0
- package/dist/lumenflow-config.js +236 -0
- package/dist/manual-test-validator.d.ts +80 -0
- package/dist/manual-test-validator.js +200 -0
- package/dist/merge-lock.d.ts +115 -0
- package/dist/merge-lock.js +251 -0
- package/dist/micro-worktree.d.ts +159 -0
- package/dist/micro-worktree.js +427 -0
- package/dist/migration-deployer.d.ts +69 -0
- package/dist/migration-deployer.js +151 -0
- package/dist/orchestration-advisory-loader.d.ts +28 -0
- package/dist/orchestration-advisory-loader.js +87 -0
- package/dist/orchestration-advisory.d.ts +58 -0
- package/dist/orchestration-advisory.js +94 -0
- package/dist/orchestration-di.d.ts +48 -0
- package/dist/orchestration-di.js +57 -0
- package/dist/orchestration-rules.d.ts +57 -0
- package/dist/orchestration-rules.js +201 -0
- package/dist/orphan-detector.d.ts +131 -0
- package/dist/orphan-detector.js +226 -0
- package/dist/path-classifiers.d.ts +57 -0
- package/dist/path-classifiers.js +93 -0
- package/dist/piped-command-detector.d.ts +34 -0
- package/dist/piped-command-detector.js +64 -0
- package/dist/ports/dashboard-renderer.port.d.ts +112 -0
- package/dist/ports/dashboard-renderer.port.js +25 -0
- package/dist/ports/metrics-collector.port.d.ts +132 -0
- package/dist/ports/metrics-collector.port.js +26 -0
- package/dist/process-detector.d.ts +84 -0
- package/dist/process-detector.js +172 -0
- package/dist/prompt-linter.d.ts +72 -0
- package/dist/prompt-linter.js +312 -0
- package/dist/prompt-monitor.d.ts +15 -0
- package/dist/prompt-monitor.js +205 -0
- package/dist/rebase-artifact-cleanup.d.ts +145 -0
- package/dist/rebase-artifact-cleanup.js +433 -0
- package/dist/retry-strategy.d.ts +189 -0
- package/dist/retry-strategy.js +283 -0
- package/dist/risk-detector.d.ts +108 -0
- package/dist/risk-detector.js +252 -0
- package/dist/rollback-utils.d.ts +76 -0
- package/dist/rollback-utils.js +104 -0
- package/dist/section-headings.d.ts +43 -0
- package/dist/section-headings.js +49 -0
- package/dist/spawn-escalation.d.ts +90 -0
- package/dist/spawn-escalation.js +253 -0
- package/dist/spawn-monitor.d.ts +229 -0
- package/dist/spawn-monitor.js +672 -0
- package/dist/spawn-recovery.d.ts +82 -0
- package/dist/spawn-recovery.js +298 -0
- package/dist/spawn-registry-schema.d.ts +98 -0
- package/dist/spawn-registry-schema.js +108 -0
- package/dist/spawn-registry-store.d.ts +146 -0
- package/dist/spawn-registry-store.js +273 -0
- package/dist/spawn-tree.d.ts +121 -0
- package/dist/spawn-tree.js +285 -0
- package/dist/stamp-status-validator.d.ts +84 -0
- package/dist/stamp-status-validator.js +134 -0
- package/dist/stamp-utils.d.ts +100 -0
- package/dist/stamp-utils.js +229 -0
- package/dist/state-machine.d.ts +26 -0
- package/dist/state-machine.js +83 -0
- package/dist/system-map-validator.d.ts +80 -0
- package/dist/system-map-validator.js +272 -0
- package/dist/telemetry.d.ts +80 -0
- package/dist/telemetry.js +213 -0
- package/dist/token-counter.d.ts +51 -0
- package/dist/token-counter.js +145 -0
- package/dist/usecases/get-dashboard-data.usecase.d.ts +52 -0
- package/dist/usecases/get-dashboard-data.usecase.js +61 -0
- package/dist/usecases/get-suggestions.usecase.d.ts +100 -0
- package/dist/usecases/get-suggestions.usecase.js +153 -0
- package/dist/user-normalizer.d.ts +41 -0
- package/dist/user-normalizer.js +141 -0
- package/dist/validators/phi-constants.d.ts +97 -0
- package/dist/validators/phi-constants.js +152 -0
- package/dist/validators/phi-scanner.d.ts +58 -0
- package/dist/validators/phi-scanner.js +215 -0
- package/dist/worktree-ownership.d.ts +50 -0
- package/dist/worktree-ownership.js +74 -0
- package/dist/worktree-scanner.d.ts +103 -0
- package/dist/worktree-scanner.js +168 -0
- package/dist/worktree-symlink.d.ts +99 -0
- package/dist/worktree-symlink.js +359 -0
- package/dist/wu-backlog-updater.d.ts +17 -0
- package/dist/wu-backlog-updater.js +37 -0
- package/dist/wu-checkpoint.d.ts +124 -0
- package/dist/wu-checkpoint.js +233 -0
- package/dist/wu-claim-helpers.d.ts +26 -0
- package/dist/wu-claim-helpers.js +63 -0
- package/dist/wu-claim-resume.d.ts +106 -0
- package/dist/wu-claim-resume.js +276 -0
- package/dist/wu-consistency-checker.d.ts +95 -0
- package/dist/wu-consistency-checker.js +567 -0
- package/dist/wu-constants.d.ts +1275 -0
- package/dist/wu-constants.js +1382 -0
- package/dist/wu-create-validators.d.ts +42 -0
- package/dist/wu-create-validators.js +93 -0
- package/dist/wu-done-branch-only.d.ts +63 -0
- package/dist/wu-done-branch-only.js +191 -0
- package/dist/wu-done-messages.d.ts +119 -0
- package/dist/wu-done-messages.js +185 -0
- package/dist/wu-done-pr.d.ts +72 -0
- package/dist/wu-done-pr.js +174 -0
- package/dist/wu-done-retry-helpers.d.ts +85 -0
- package/dist/wu-done-retry-helpers.js +172 -0
- package/dist/wu-done-ui.d.ts +37 -0
- package/dist/wu-done-ui.js +69 -0
- package/dist/wu-done-validators.d.ts +411 -0
- package/dist/wu-done-validators.js +1229 -0
- package/dist/wu-done-worktree.d.ts +182 -0
- package/dist/wu-done-worktree.js +1097 -0
- package/dist/wu-helpers.d.ts +128 -0
- package/dist/wu-helpers.js +248 -0
- package/dist/wu-lint.d.ts +70 -0
- package/dist/wu-lint.js +234 -0
- package/dist/wu-paths.d.ts +171 -0
- package/dist/wu-paths.js +178 -0
- package/dist/wu-preflight-validators.d.ts +86 -0
- package/dist/wu-preflight-validators.js +251 -0
- package/dist/wu-recovery.d.ts +138 -0
- package/dist/wu-recovery.js +341 -0
- package/dist/wu-repair-core.d.ts +131 -0
- package/dist/wu-repair-core.js +669 -0
- package/dist/wu-schema-normalization.d.ts +17 -0
- package/dist/wu-schema-normalization.js +82 -0
- package/dist/wu-schema.d.ts +793 -0
- package/dist/wu-schema.js +881 -0
- package/dist/wu-spawn-helpers.d.ts +121 -0
- package/dist/wu-spawn-helpers.js +271 -0
- package/dist/wu-spawn.d.ts +158 -0
- package/dist/wu-spawn.js +1306 -0
- package/dist/wu-state-schema.d.ts +213 -0
- package/dist/wu-state-schema.js +156 -0
- package/dist/wu-state-store.d.ts +264 -0
- package/dist/wu-state-store.js +691 -0
- package/dist/wu-status-transition.d.ts +63 -0
- package/dist/wu-status-transition.js +382 -0
- package/dist/wu-status-updater.d.ts +25 -0
- package/dist/wu-status-updater.js +116 -0
- package/dist/wu-transaction-collectors.d.ts +116 -0
- package/dist/wu-transaction-collectors.js +272 -0
- package/dist/wu-transaction.d.ts +170 -0
- package/dist/wu-transaction.js +273 -0
- package/dist/wu-validation-constants.d.ts +60 -0
- package/dist/wu-validation-constants.js +66 -0
- package/dist/wu-validation.d.ts +118 -0
- package/dist/wu-validation.js +243 -0
- package/dist/wu-validator.d.ts +62 -0
- package/dist/wu-validator.js +325 -0
- package/dist/wu-yaml-fixer.d.ts +97 -0
- package/dist/wu-yaml-fixer.js +264 -0
- package/dist/wu-yaml.d.ts +86 -0
- package/dist/wu-yaml.js +222 -0
- package/package.json +114 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lumenflow/core - Battle-tested LumenFlow workflow framework
|
|
3
|
+
* @module @lumenflow/core
|
|
4
|
+
*/
|
|
5
|
+
export declare const VERSION = "0.0.0";
|
|
6
|
+
export * from './arg-parser.js';
|
|
7
|
+
export * from './date-utils.js';
|
|
8
|
+
export * from './error-handler.js';
|
|
9
|
+
export * from './retry-strategy.js';
|
|
10
|
+
export { DEFAULT_DOMAIN, inferDefaultDomain, normalizeToEmail, isValidEmail, } from './user-normalizer.js';
|
|
11
|
+
export * from './git-adapter.js';
|
|
12
|
+
export * from './state-machine.js';
|
|
13
|
+
export { WU_EVENT_TYPES, WU_STATUSES, WU_PATTERNS, CreateEventSchema, ClaimEventSchema, BlockEventSchema, UnblockEventSchema, CompleteEventSchema, CheckpointEventSchema, WUEventSchema, validateWUEvent, SpawnEventSchema as WUSpawnEventSchema, type CreateEvent, type ClaimEvent, type BlockEvent, type UnblockEvent, type CompleteEvent, type CheckpointEvent, type WUEvent, type SpawnEvent as WUSpawnEvent, } from './wu-state-schema.js';
|
|
14
|
+
export { WU_EVENTS_FILE_NAME, WUStateStore, acquireLock, releaseLock, repairStateFile, isLockStale as isWULockStale, type WUStateEntry, type LockData as WULockData, type CheckpointOptions, type RepairResult, } from './wu-state-store.js';
|
|
15
|
+
export * from './lane-checker.js';
|
|
16
|
+
export * from './lane-inference.js';
|
|
17
|
+
export { getStaleThresholdMs, getLocksDir, getLockFilePath, isLockStale, isZombieLock, readLockMetadata, acquireLaneLock, releaseLaneLock, checkLaneLock, forceRemoveStaleLock, getAllLaneLocks, auditedUnlock, } from './lane-lock.js';
|
|
18
|
+
export * from './lane-validator.js';
|
|
19
|
+
export * from './wu-yaml.js';
|
|
20
|
+
export { getAssignedEmail } from './wu-claim-helpers.js';
|
|
21
|
+
export * from './wu-done-worktree.js';
|
|
22
|
+
export * from './wu-done-validators.js';
|
|
23
|
+
export * from './wu-helpers.js';
|
|
24
|
+
export * from './wu-schema.js';
|
|
25
|
+
export * from './wu-validator.js';
|
|
26
|
+
export * from './spawn-registry-store.js';
|
|
27
|
+
export * from './spawn-registry-schema.js';
|
|
28
|
+
export * from './spawn-tree.js';
|
|
29
|
+
export * from './spawn-recovery.js';
|
|
30
|
+
export * from './spawn-monitor.js';
|
|
31
|
+
export * from './spawn-escalation.js';
|
|
32
|
+
export * from './backlog-generator.js';
|
|
33
|
+
export * from './backlog-parser.js';
|
|
34
|
+
export * from './backlog-editor.js';
|
|
35
|
+
export * from './backlog-sync-validator.js';
|
|
36
|
+
export * from './worktree-scanner.js';
|
|
37
|
+
export * from './worktree-ownership.js';
|
|
38
|
+
export * from './micro-worktree.js';
|
|
39
|
+
export * from './dependency-guard.js';
|
|
40
|
+
export * from './stamp-utils.js';
|
|
41
|
+
export * from './lumenflow-config.js';
|
|
42
|
+
export * from './lumenflow-config-schema.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @lumenflow/core - Battle-tested LumenFlow workflow framework
|
|
3
|
+
* @module @lumenflow/core
|
|
4
|
+
*/
|
|
5
|
+
// Package version
|
|
6
|
+
export const VERSION = '0.0.0';
|
|
7
|
+
// Core utilities
|
|
8
|
+
export * from './arg-parser.js';
|
|
9
|
+
export * from './date-utils.js';
|
|
10
|
+
export * from './error-handler.js';
|
|
11
|
+
export * from './retry-strategy.js';
|
|
12
|
+
// User normalizer (explicit exports to avoid conflicts)
|
|
13
|
+
export { DEFAULT_DOMAIN, inferDefaultDomain, normalizeToEmail, isValidEmail, } from './user-normalizer.js';
|
|
14
|
+
// Git operations
|
|
15
|
+
export * from './git-adapter.js';
|
|
16
|
+
// State machine
|
|
17
|
+
export * from './state-machine.js';
|
|
18
|
+
// WU State Schema (explicit exports to avoid SpawnEvent conflict with spawn-registry)
|
|
19
|
+
export { WU_EVENT_TYPES, WU_STATUSES, WU_PATTERNS, CreateEventSchema, ClaimEventSchema, BlockEventSchema, UnblockEventSchema, CompleteEventSchema, CheckpointEventSchema, WUEventSchema, validateWUEvent,
|
|
20
|
+
// Rename conflicting exports
|
|
21
|
+
SpawnEventSchema as WUSpawnEventSchema, } from './wu-state-schema.js';
|
|
22
|
+
// WU State Store (explicit exports to avoid isLockStale conflict)
|
|
23
|
+
export { WU_EVENTS_FILE_NAME, WUStateStore, acquireLock, releaseLock, repairStateFile, isLockStale as isWULockStale, } from './wu-state-store.js';
|
|
24
|
+
// Lane management
|
|
25
|
+
export * from './lane-checker.js';
|
|
26
|
+
export * from './lane-inference.js';
|
|
27
|
+
// Lane lock (explicit exports with proper names)
|
|
28
|
+
export { getStaleThresholdMs, getLocksDir, getLockFilePath, isLockStale, isZombieLock, readLockMetadata, acquireLaneLock, releaseLaneLock, checkLaneLock, forceRemoveStaleLock, getAllLaneLocks, auditedUnlock, } from './lane-lock.js';
|
|
29
|
+
export * from './lane-validator.js';
|
|
30
|
+
// WU lifecycle
|
|
31
|
+
export * from './wu-yaml.js';
|
|
32
|
+
// WU claim helpers (skip isValidEmail which conflicts with user-normalizer)
|
|
33
|
+
export { getAssignedEmail } from './wu-claim-helpers.js';
|
|
34
|
+
export * from './wu-done-worktree.js';
|
|
35
|
+
export * from './wu-done-validators.js';
|
|
36
|
+
export * from './wu-helpers.js';
|
|
37
|
+
export * from './wu-schema.js';
|
|
38
|
+
export * from './wu-validator.js';
|
|
39
|
+
// Spawn system
|
|
40
|
+
export * from './spawn-registry-store.js';
|
|
41
|
+
export * from './spawn-registry-schema.js';
|
|
42
|
+
export * from './spawn-tree.js';
|
|
43
|
+
export * from './spawn-recovery.js';
|
|
44
|
+
export * from './spawn-monitor.js';
|
|
45
|
+
export * from './spawn-escalation.js';
|
|
46
|
+
// Backlog management
|
|
47
|
+
export * from './backlog-generator.js';
|
|
48
|
+
export * from './backlog-parser.js';
|
|
49
|
+
export * from './backlog-editor.js';
|
|
50
|
+
export * from './backlog-sync-validator.js';
|
|
51
|
+
// Worktree utilities
|
|
52
|
+
export * from './worktree-scanner.js';
|
|
53
|
+
export * from './worktree-ownership.js';
|
|
54
|
+
export * from './micro-worktree.js';
|
|
55
|
+
// Guards and validators
|
|
56
|
+
// NOTE: Configuration added below
|
|
57
|
+
export * from './dependency-guard.js';
|
|
58
|
+
export * from './stamp-utils.js';
|
|
59
|
+
// Configuration
|
|
60
|
+
export * from './lumenflow-config.js';
|
|
61
|
+
export * from './lumenflow-config-schema.js';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* INV-AUTOMATED-TESTS-FOR-CODE Invariant Check (WU-2333)
|
|
3
|
+
*
|
|
4
|
+
* Validates that WUs with code files in code_paths have automated tests.
|
|
5
|
+
* Config files are excluded from this requirement.
|
|
6
|
+
*
|
|
7
|
+
* This invariant ensures that manual-only tests cannot satisfy validation
|
|
8
|
+
* for code changes, enforcing TDD discipline.
|
|
9
|
+
*
|
|
10
|
+
* Library-first check: This is custom validation logic for PatientPath WU workflow.
|
|
11
|
+
* No external library exists for WU YAML validation - this integrates with
|
|
12
|
+
* the existing manual-test-validator.mjs which already implements the core logic.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link tools/lib/manual-test-validator.mjs} - Core validation logic
|
|
15
|
+
* @see {@link tools/invariants.yml} - Invariant registry
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Invariant metadata
|
|
19
|
+
*/
|
|
20
|
+
export declare const INVARIANT_ID = "INV-AUTOMATED-TESTS-FOR-CODE";
|
|
21
|
+
export declare const INVARIANT_TYPE = "wu-automated-tests";
|
|
22
|
+
/**
|
|
23
|
+
* Run the INV-AUTOMATED-TESTS-FOR-CODE invariant check.
|
|
24
|
+
*
|
|
25
|
+
* Scans WU YAML files and validates that any with code files in code_paths
|
|
26
|
+
* have automated tests (unit, e2e, or integration).
|
|
27
|
+
*
|
|
28
|
+
* WU-2425: When wuId is provided, only validates that specific WU instead of
|
|
29
|
+
* all active WUs. This prevents unrelated WUs from blocking wu:done completion.
|
|
30
|
+
*
|
|
31
|
+
* @param {CheckAutomatedTestsInvariantOptions} [options={}] - Options
|
|
32
|
+
* @returns {{ valid: boolean, violations: Array<object> }} Check result
|
|
33
|
+
*/
|
|
34
|
+
export interface CheckAutomatedTestsInvariantOptions {
|
|
35
|
+
/** Base directory for path resolution */
|
|
36
|
+
baseDir?: string;
|
|
37
|
+
/** Specific WU ID to validate (WU-2425: scoped validation) */
|
|
38
|
+
wuId?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function checkAutomatedTestsInvariant(options?: CheckAutomatedTestsInvariantOptions): {
|
|
41
|
+
valid: boolean;
|
|
42
|
+
violations: any[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Format a violation for display.
|
|
46
|
+
*
|
|
47
|
+
* @param {object} violation - Violation object
|
|
48
|
+
* @returns {string} Formatted error message
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatAutomatedTestsViolation(violation: any): string;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* INV-AUTOMATED-TESTS-FOR-CODE Invariant Check (WU-2333)
|
|
3
|
+
*
|
|
4
|
+
* Validates that WUs with code files in code_paths have automated tests.
|
|
5
|
+
* Config files are excluded from this requirement.
|
|
6
|
+
*
|
|
7
|
+
* This invariant ensures that manual-only tests cannot satisfy validation
|
|
8
|
+
* for code changes, enforcing TDD discipline.
|
|
9
|
+
*
|
|
10
|
+
* Library-first check: This is custom validation logic for PatientPath WU workflow.
|
|
11
|
+
* No external library exists for WU YAML validation - this integrates with
|
|
12
|
+
* the existing manual-test-validator.mjs which already implements the core logic.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link tools/lib/manual-test-validator.mjs} - Core validation logic
|
|
15
|
+
* @see {@link tools/invariants.yml} - Invariant registry
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { parseYAML } from '../wu-yaml.js';
|
|
20
|
+
import { validateAutomatedTestRequirement, isCodeFile } from '../manual-test-validator.js';
|
|
21
|
+
/**
|
|
22
|
+
* Invariant metadata
|
|
23
|
+
*/
|
|
24
|
+
export const INVARIANT_ID = 'INV-AUTOMATED-TESTS-FOR-CODE';
|
|
25
|
+
export const INVARIANT_TYPE = 'wu-automated-tests';
|
|
26
|
+
/**
|
|
27
|
+
* WU statuses that should be validated.
|
|
28
|
+
* Only validate active work - in_progress and blocked WUs.
|
|
29
|
+
* Done, ready, and waiting WUs are either already validated or not yet being worked.
|
|
30
|
+
*/
|
|
31
|
+
const ACTIVE_STATUSES = Object.freeze(['in_progress', 'blocked']);
|
|
32
|
+
/**
|
|
33
|
+
* Default path to WU YAML files relative to base directory.
|
|
34
|
+
*/
|
|
35
|
+
const WU_YAML_PATH = 'docs/04-operations/tasks/wu';
|
|
36
|
+
/**
|
|
37
|
+
* Check a single WU YAML file for automated test requirement.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} filePath - Path to WU YAML file
|
|
40
|
+
* @param {CheckWUFileOptions} [options={}] - Options
|
|
41
|
+
* @returns {{ valid: boolean, wuId: string|null, error: string|null }} Check result
|
|
42
|
+
*/
|
|
43
|
+
function checkWUFile(filePath, options = {}) {
|
|
44
|
+
const { skipStatusCheck = false } = options;
|
|
45
|
+
try {
|
|
46
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
47
|
+
const doc = parseYAML(content);
|
|
48
|
+
if (!doc) {
|
|
49
|
+
return { valid: true, wuId: null, error: null };
|
|
50
|
+
}
|
|
51
|
+
const wuId = doc.id || path.basename(filePath, '.yaml');
|
|
52
|
+
const status = doc.status || '';
|
|
53
|
+
// WU-2425: Skip status check when validating a specific WU (e.g., during wu:done)
|
|
54
|
+
// This is needed because wu:done may set status to 'done' before validation runs
|
|
55
|
+
if (!skipStatusCheck && !ACTIVE_STATUSES.includes(status)) {
|
|
56
|
+
return { valid: true, wuId, error: null };
|
|
57
|
+
}
|
|
58
|
+
// Use the existing validation logic from manual-test-validator.mjs
|
|
59
|
+
const result = validateAutomatedTestRequirement(doc);
|
|
60
|
+
if (!result.valid) {
|
|
61
|
+
return {
|
|
62
|
+
valid: false,
|
|
63
|
+
wuId,
|
|
64
|
+
error: result.errors.join('\n'),
|
|
65
|
+
codeFiles: getCodeFilesFromPaths(doc.code_paths || []),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { valid: true, wuId, error: null };
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Skip files that can't be parsed
|
|
72
|
+
return { valid: true, wuId: null, error: null };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get code files from code_paths (filtering out config files).
|
|
77
|
+
*
|
|
78
|
+
* @param {string[]} codePaths - Array of code paths
|
|
79
|
+
* @returns {string[]} Code files that require automated tests
|
|
80
|
+
*/
|
|
81
|
+
function getCodeFilesFromPaths(codePaths) {
|
|
82
|
+
if (!codePaths || !Array.isArray(codePaths)) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
return codePaths.filter((p) => isCodeFile(p));
|
|
86
|
+
}
|
|
87
|
+
export function checkAutomatedTestsInvariant(options = {}) {
|
|
88
|
+
const { baseDir = process.cwd(), wuId } = options;
|
|
89
|
+
const wuDir = path.join(baseDir, WU_YAML_PATH);
|
|
90
|
+
const violations = [];
|
|
91
|
+
// Check if WU directory exists
|
|
92
|
+
if (!existsSync(wuDir)) {
|
|
93
|
+
return { valid: true, violations: [] };
|
|
94
|
+
}
|
|
95
|
+
// WU-2425: If wuId is provided, only check that specific WU file
|
|
96
|
+
if (wuId) {
|
|
97
|
+
const filePath = path.join(wuDir, `${wuId}.yaml`);
|
|
98
|
+
// If the WU file doesn't exist, pass gracefully (nothing to validate)
|
|
99
|
+
if (!existsSync(filePath)) {
|
|
100
|
+
return { valid: true, violations: [] };
|
|
101
|
+
}
|
|
102
|
+
// When validating a specific WU, skip status check (validate regardless of status)
|
|
103
|
+
// This is needed because wu:done may set status to 'done' before validation runs
|
|
104
|
+
const result = checkWUFile(filePath, { skipStatusCheck: true });
|
|
105
|
+
if (!result.valid) {
|
|
106
|
+
violations.push({
|
|
107
|
+
id: INVARIANT_ID,
|
|
108
|
+
type: INVARIANT_TYPE,
|
|
109
|
+
wuId: result.wuId,
|
|
110
|
+
description: `WU ${result.wuId} has code files but no automated tests`,
|
|
111
|
+
message: result.error,
|
|
112
|
+
codeFiles: result.codeFiles,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
valid: violations.length === 0,
|
|
117
|
+
violations,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Default behavior: check all WU files (existing behavior for gates)
|
|
121
|
+
let files;
|
|
122
|
+
try {
|
|
123
|
+
files = readdirSync(wuDir).filter((f) => f.startsWith('WU-') && (f.endsWith('.yaml') || f.endsWith('.yml')));
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return { valid: true, violations: [] };
|
|
127
|
+
}
|
|
128
|
+
// Check each WU file
|
|
129
|
+
for (const file of files) {
|
|
130
|
+
const filePath = path.join(wuDir, file);
|
|
131
|
+
const result = checkWUFile(filePath);
|
|
132
|
+
if (!result.valid) {
|
|
133
|
+
violations.push({
|
|
134
|
+
id: INVARIANT_ID,
|
|
135
|
+
type: INVARIANT_TYPE,
|
|
136
|
+
wuId: result.wuId,
|
|
137
|
+
description: `WU ${result.wuId} has code files but no automated tests`,
|
|
138
|
+
message: result.error,
|
|
139
|
+
codeFiles: result.codeFiles,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
valid: violations.length === 0,
|
|
145
|
+
violations,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Format a violation for display.
|
|
150
|
+
*
|
|
151
|
+
* @param {object} violation - Violation object
|
|
152
|
+
* @returns {string} Formatted error message
|
|
153
|
+
*/
|
|
154
|
+
export function formatAutomatedTestsViolation(violation) {
|
|
155
|
+
const lines = [
|
|
156
|
+
`INVARIANT VIOLATION: ${violation.id}`,
|
|
157
|
+
`WU: ${violation.wuId}`,
|
|
158
|
+
`Description: ${violation.description}`,
|
|
159
|
+
];
|
|
160
|
+
if (violation.codeFiles && violation.codeFiles.length > 0) {
|
|
161
|
+
lines.push(`Code files requiring tests: ${violation.codeFiles.join(', ')}`);
|
|
162
|
+
}
|
|
163
|
+
lines.push('');
|
|
164
|
+
lines.push('Action: Add automated tests (unit, e2e, or integration) to the tests field in the WU YAML.');
|
|
165
|
+
return lines.join('\n');
|
|
166
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Invariants Runner (WU-2252)
|
|
3
|
+
*
|
|
4
|
+
* Validates durable repo invariants from invariants.yml.
|
|
5
|
+
* Runs as the first gate check and also inside wu:done even when --skip-gates is used.
|
|
6
|
+
*
|
|
7
|
+
* Supported invariant types:
|
|
8
|
+
* - required-file: File must exist
|
|
9
|
+
* - forbidden-file: File must NOT exist
|
|
10
|
+
* - mutual-exclusivity: Only one of the listed files may exist
|
|
11
|
+
* - forbidden-pattern: Pattern must not appear in scoped files
|
|
12
|
+
* - required-pattern: Pattern MUST appear at least once in scoped files (WU-2254)
|
|
13
|
+
* - forbidden-import: Files must not import forbidden modules (WU-2254)
|
|
14
|
+
* - wu-automated-tests: WUs with code files must have automated tests (WU-2333)
|
|
15
|
+
*
|
|
16
|
+
* Performance constraints:
|
|
17
|
+
* - Excludes node_modules/, worktrees/, .next/, dist/, .git/ from scanning
|
|
18
|
+
* - For forbidden-pattern rules, scans only the specified scope paths
|
|
19
|
+
*
|
|
20
|
+
* @module tools/lib/invariants-runner
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Invariant type constants
|
|
24
|
+
*/
|
|
25
|
+
export declare const INVARIANT_TYPES: {
|
|
26
|
+
REQUIRED_FILE: string;
|
|
27
|
+
FORBIDDEN_FILE: string;
|
|
28
|
+
MUTUAL_EXCLUSIVITY: string;
|
|
29
|
+
FORBIDDEN_PATTERN: string;
|
|
30
|
+
REQUIRED_PATTERN: string;
|
|
31
|
+
FORBIDDEN_IMPORT: string;
|
|
32
|
+
WU_AUTOMATED_TESTS: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Custom error class for invariant violations
|
|
36
|
+
*/
|
|
37
|
+
export declare class InvariantError extends Error {
|
|
38
|
+
/** The invariant ID */
|
|
39
|
+
invariantId: string;
|
|
40
|
+
/**
|
|
41
|
+
* @param {string} invariantId - The invariant ID (e.g., 'INV-001')
|
|
42
|
+
* @param {string} message - Error message
|
|
43
|
+
*/
|
|
44
|
+
constructor(invariantId: string, message: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load invariants from a YAML file
|
|
48
|
+
*
|
|
49
|
+
* @param {string} filePath - Path to invariants.yml
|
|
50
|
+
* @returns {Array<object>} Array of invariant definitions
|
|
51
|
+
* @throws {Error} If file doesn't exist or has invalid YAML
|
|
52
|
+
*/
|
|
53
|
+
export declare function loadInvariants(filePath: any): any;
|
|
54
|
+
/**
|
|
55
|
+
* Validate all invariants against the current repo state
|
|
56
|
+
*
|
|
57
|
+
* WU-2425: When wuId is provided, WU-scoped invariants only validate that specific WU.
|
|
58
|
+
*
|
|
59
|
+
* @param {Array<object>} invariants - Array of invariant definitions
|
|
60
|
+
* @param {ValidateInvariantsOptions} [options={}] - Options
|
|
61
|
+
* @returns {{valid: boolean, violations: Array<object>}} Validation result
|
|
62
|
+
*/
|
|
63
|
+
export interface ValidateInvariantsOptions {
|
|
64
|
+
/** Base directory for path resolution */
|
|
65
|
+
baseDir?: string;
|
|
66
|
+
/** Specific WU ID for scoped validation (WU-2425) */
|
|
67
|
+
wuId?: string;
|
|
68
|
+
}
|
|
69
|
+
export declare function validateInvariants(invariants: any, options?: ValidateInvariantsOptions): {
|
|
70
|
+
valid: boolean;
|
|
71
|
+
violations: any[];
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Format an invariant violation for display
|
|
75
|
+
*
|
|
76
|
+
* @param {object} violation - Violation object from validateInvariants
|
|
77
|
+
* @returns {string} Formatted error message
|
|
78
|
+
*/
|
|
79
|
+
export declare function formatInvariantError(violation: any): string;
|
|
80
|
+
/**
|
|
81
|
+
* Run invariants validation and format results for gates output
|
|
82
|
+
*
|
|
83
|
+
* WU-2425: When wuId is provided, WU-scoped invariants (like automated tests)
|
|
84
|
+
* only validate that specific WU, preventing unrelated WUs from blocking wu:done.
|
|
85
|
+
*
|
|
86
|
+
* @param {RunInvariantsOptions} [options={}] - Options
|
|
87
|
+
* @returns {{success: boolean, violations: Array<object>, formatted: string}} Result
|
|
88
|
+
*/
|
|
89
|
+
export interface RunInvariantsOptions {
|
|
90
|
+
/** Path to invariants config */
|
|
91
|
+
configPath?: string;
|
|
92
|
+
/** Base directory */
|
|
93
|
+
baseDir?: string;
|
|
94
|
+
/** Suppress console output */
|
|
95
|
+
silent?: boolean;
|
|
96
|
+
/** Specific WU ID for scoped validation (WU-2425) */
|
|
97
|
+
wuId?: string;
|
|
98
|
+
}
|
|
99
|
+
export declare function runInvariants(options?: RunInvariantsOptions): {
|
|
100
|
+
success: boolean;
|
|
101
|
+
violations: any[];
|
|
102
|
+
formatted: string;
|
|
103
|
+
};
|