@lumenflow/cli 2.4.0 → 2.5.1

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.
Files changed (147) hide show
  1. package/README.md +11 -8
  2. package/dist/__tests__/init-config-lanes.test.js +131 -0
  3. package/dist/__tests__/init-docs-structure.test.js +119 -0
  4. package/dist/__tests__/init-lane-inference.test.js +125 -0
  5. package/dist/__tests__/init-onboarding-docs.test.js +132 -0
  6. package/dist/__tests__/init-quick-ref.test.js +145 -0
  7. package/dist/__tests__/init-scripts.test.js +207 -0
  8. package/dist/__tests__/init-template-portability.test.js +97 -0
  9. package/dist/__tests__/init.test.js +7 -2
  10. package/dist/__tests__/initiative-add-wu.test.js +420 -0
  11. package/dist/__tests__/initiative-plan-replacement.test.js +162 -0
  12. package/dist/__tests__/initiative-remove-wu.test.js +458 -0
  13. package/dist/__tests__/onboarding-smoke-test.test.js +211 -0
  14. package/dist/__tests__/path-centralization-cli.test.js +234 -0
  15. package/dist/__tests__/plan-create.test.js +126 -0
  16. package/dist/__tests__/plan-edit.test.js +157 -0
  17. package/dist/__tests__/plan-link.test.js +239 -0
  18. package/dist/__tests__/plan-promote.test.js +181 -0
  19. package/dist/__tests__/templates-sync.test.js +219 -0
  20. package/dist/__tests__/wu-create-strict.test.js +118 -0
  21. package/dist/__tests__/wu-edit-strict.test.js +109 -0
  22. package/dist/__tests__/wu-validate-strict.test.js +113 -0
  23. package/dist/flow-bottlenecks.js +4 -2
  24. package/dist/gates.js +22 -0
  25. package/dist/init.js +670 -87
  26. package/dist/initiative-add-wu.js +112 -16
  27. package/dist/initiative-remove-wu.js +248 -0
  28. package/dist/onboarding-smoke-test.js +400 -0
  29. package/dist/orchestrate-init-status.js +37 -9
  30. package/dist/orchestrate-initiative.js +10 -4
  31. package/dist/plan-create.js +199 -0
  32. package/dist/plan-edit.js +235 -0
  33. package/dist/plan-link.js +233 -0
  34. package/dist/plan-promote.js +231 -0
  35. package/dist/sync-templates.js +137 -5
  36. package/dist/wu-block.js +16 -5
  37. package/dist/wu-claim.js +15 -9
  38. package/dist/wu-create.js +50 -2
  39. package/dist/wu-deps.js +3 -1
  40. package/dist/wu-done.js +14 -5
  41. package/dist/wu-edit.js +35 -0
  42. package/dist/wu-prep.js +131 -8
  43. package/dist/wu-spawn.js +14 -1
  44. package/dist/wu-unblock.js +34 -2
  45. package/dist/wu-validate.js +25 -17
  46. package/package.json +11 -7
  47. package/templates/core/.lumenflow/constraints.md.template +61 -3
  48. package/templates/core/AGENTS.md.template +2 -2
  49. package/templates/core/LUMENFLOW.md.template +85 -23
  50. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +157 -0
  51. package/templates/core/ai/onboarding/agent-safety-card.md.template +227 -0
  52. package/templates/core/ai/onboarding/docs-generation.md.template +277 -0
  53. package/templates/core/ai/onboarding/first-wu-mistakes.md.template +49 -7
  54. package/templates/core/ai/onboarding/quick-ref-commands.md.template +343 -110
  55. package/templates/core/ai/onboarding/release-process.md.template +8 -2
  56. package/templates/core/ai/onboarding/starting-prompt.md.template +407 -0
  57. package/templates/core/ai/onboarding/test-ratchet.md.template +131 -0
  58. package/templates/core/ai/onboarding/troubleshooting-wu-done.md.template +91 -38
  59. package/templates/core/ai/onboarding/vendor-support.md.template +219 -0
  60. package/templates/vendors/claude/.claude/skills/context-management/SKILL.md.template +13 -1
  61. package/templates/vendors/claude/.claude/skills/execution-memory/SKILL.md.template +14 -16
  62. package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +48 -4
  63. package/templates/vendors/claude/.claude/skills/worktree-discipline/SKILL.md.template +5 -1
  64. package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +19 -8
  65. package/dist/__tests__/init-plan.test.js +0 -340
  66. package/dist/agent-issues-query.d.ts +0 -16
  67. package/dist/agent-log-issue.d.ts +0 -10
  68. package/dist/agent-session-end.d.ts +0 -10
  69. package/dist/agent-session.d.ts +0 -10
  70. package/dist/backlog-prune.d.ts +0 -84
  71. package/dist/cli-entry-point.d.ts +0 -8
  72. package/dist/deps-add.d.ts +0 -91
  73. package/dist/deps-remove.d.ts +0 -17
  74. package/dist/docs-sync.d.ts +0 -50
  75. package/dist/file-delete.d.ts +0 -84
  76. package/dist/file-edit.d.ts +0 -82
  77. package/dist/file-read.d.ts +0 -92
  78. package/dist/file-write.d.ts +0 -90
  79. package/dist/flow-bottlenecks.d.ts +0 -16
  80. package/dist/flow-report.d.ts +0 -16
  81. package/dist/gates.d.ts +0 -94
  82. package/dist/git-branch.d.ts +0 -65
  83. package/dist/git-diff.d.ts +0 -58
  84. package/dist/git-log.d.ts +0 -69
  85. package/dist/git-status.d.ts +0 -58
  86. package/dist/guard-locked.d.ts +0 -62
  87. package/dist/guard-main-branch.d.ts +0 -50
  88. package/dist/guard-worktree-commit.d.ts +0 -59
  89. package/dist/index.d.ts +0 -10
  90. package/dist/init-plan.d.ts +0 -80
  91. package/dist/init-plan.js +0 -337
  92. package/dist/init.d.ts +0 -46
  93. package/dist/initiative-add-wu.d.ts +0 -22
  94. package/dist/initiative-bulk-assign-wus.d.ts +0 -16
  95. package/dist/initiative-create.d.ts +0 -28
  96. package/dist/initiative-edit.d.ts +0 -34
  97. package/dist/initiative-list.d.ts +0 -12
  98. package/dist/initiative-status.d.ts +0 -11
  99. package/dist/lumenflow-upgrade.d.ts +0 -103
  100. package/dist/mem-checkpoint.d.ts +0 -16
  101. package/dist/mem-cleanup.d.ts +0 -29
  102. package/dist/mem-create.d.ts +0 -17
  103. package/dist/mem-export.d.ts +0 -10
  104. package/dist/mem-inbox.d.ts +0 -35
  105. package/dist/mem-init.d.ts +0 -15
  106. package/dist/mem-ready.d.ts +0 -16
  107. package/dist/mem-signal.d.ts +0 -16
  108. package/dist/mem-start.d.ts +0 -16
  109. package/dist/mem-summarize.d.ts +0 -22
  110. package/dist/mem-triage.d.ts +0 -22
  111. package/dist/metrics-cli.d.ts +0 -90
  112. package/dist/metrics-snapshot.d.ts +0 -18
  113. package/dist/orchestrate-init-status.d.ts +0 -11
  114. package/dist/orchestrate-initiative.d.ts +0 -12
  115. package/dist/orchestrate-monitor.d.ts +0 -11
  116. package/dist/release.d.ts +0 -117
  117. package/dist/rotate-progress.d.ts +0 -48
  118. package/dist/session-coordinator.d.ts +0 -74
  119. package/dist/spawn-list.d.ts +0 -16
  120. package/dist/state-bootstrap.d.ts +0 -92
  121. package/dist/sync-templates.d.ts +0 -52
  122. package/dist/trace-gen.d.ts +0 -84
  123. package/dist/validate-agent-skills.d.ts +0 -50
  124. package/dist/validate-agent-sync.d.ts +0 -36
  125. package/dist/validate-backlog-sync.d.ts +0 -37
  126. package/dist/validate-skills-spec.d.ts +0 -40
  127. package/dist/validate.d.ts +0 -60
  128. package/dist/wu-block.d.ts +0 -16
  129. package/dist/wu-claim.d.ts +0 -74
  130. package/dist/wu-cleanup.d.ts +0 -35
  131. package/dist/wu-create.d.ts +0 -69
  132. package/dist/wu-delete.d.ts +0 -21
  133. package/dist/wu-deps.d.ts +0 -13
  134. package/dist/wu-done.d.ts +0 -225
  135. package/dist/wu-edit.d.ts +0 -63
  136. package/dist/wu-infer-lane.d.ts +0 -17
  137. package/dist/wu-preflight.d.ts +0 -47
  138. package/dist/wu-prune.d.ts +0 -16
  139. package/dist/wu-recover.d.ts +0 -37
  140. package/dist/wu-release.d.ts +0 -19
  141. package/dist/wu-repair.d.ts +0 -60
  142. package/dist/wu-spawn-completion.d.ts +0 -10
  143. package/dist/wu-spawn.d.ts +0 -192
  144. package/dist/wu-status.d.ts +0 -25
  145. package/dist/wu-unblock.d.ts +0 -16
  146. package/dist/wu-unlock-lane.d.ts +0 -19
  147. package/dist/wu-validate.d.ts +0 -16
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @file wu-create-strict.test.ts
3
+ * Test suite for wu:create strict validation behavior (WU-1329)
4
+ *
5
+ * WU-1329: Make wu:create run strict validation by default
6
+ *
7
+ * Tests:
8
+ * - Strict validation runs by default (validates code_paths/test_paths exist)
9
+ * - --no-strict flag bypasses strict validation
10
+ * - --no-strict usage is logged
11
+ */
12
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
13
+ // Import test utilities (WU-1329)
14
+ import { validateCreateSpec } from '../wu-create.js';
15
+ // WU-1329: Constants for test file paths
16
+ const NON_EXISTENT_CODE_PATH = 'non-existent/file.ts';
17
+ const NON_EXISTENT_TEST_PATH = 'non-existent/test.test.ts';
18
+ describe('wu:create strict validation (WU-1329)', () => {
19
+ describe('validateCreateSpec strict mode', () => {
20
+ const baseOpts = {
21
+ id: 'WU-9999',
22
+ lane: 'Framework: CLI',
23
+ title: 'Test WU',
24
+ priority: 'P2',
25
+ type: 'feature',
26
+ opts: {
27
+ description: 'Context: test context.\nProblem: test problem.\nSolution: test solution that exceeds minimum length requirement.',
28
+ acceptance: ['Acceptance criterion 1'],
29
+ codePaths: ['packages/@lumenflow/cli/src/wu-create.ts'],
30
+ testPathsUnit: ['packages/@lumenflow/cli/src/__tests__/wu-create-strict.test.ts'],
31
+ exposure: 'backend-only',
32
+ specRefs: ['lumenflow://plans/WU-9999-plan.md'],
33
+ },
34
+ };
35
+ it('should pass validation with valid spec in non-strict mode', () => {
36
+ const result = validateCreateSpec({
37
+ ...baseOpts,
38
+ opts: {
39
+ ...baseOpts.opts,
40
+ strict: false,
41
+ },
42
+ });
43
+ expect(result.valid).toBe(true);
44
+ expect(result.errors).toHaveLength(0);
45
+ });
46
+ // WU-1329: This test verifies that strict validation is the default
47
+ it('should validate code_paths existence by default (strict=true)', () => {
48
+ const result = validateCreateSpec({
49
+ ...baseOpts,
50
+ opts: {
51
+ ...baseOpts.opts,
52
+ codePaths: [NON_EXISTENT_CODE_PATH],
53
+ // strict is not explicitly set - should default to true
54
+ },
55
+ });
56
+ // In strict mode, non-existent paths should be caught
57
+ expect(result.valid).toBe(false);
58
+ expect(result.errors.some((e) => e.includes('code_paths') || e.includes('not found'))).toBe(true);
59
+ });
60
+ // WU-1329: This test verifies --no-strict bypasses path validation
61
+ it('should skip code_paths existence check when strict=false', () => {
62
+ const result = validateCreateSpec({
63
+ ...baseOpts,
64
+ opts: {
65
+ ...baseOpts.opts,
66
+ codePaths: [NON_EXISTENT_CODE_PATH],
67
+ strict: false,
68
+ },
69
+ });
70
+ // In non-strict mode, non-existent paths should not fail validation
71
+ // (other schema validation may still fail)
72
+ expect(result.errors.every((e) => !e.includes('not found') && !e.includes('does not exist'))).toBe(true);
73
+ });
74
+ // WU-1329: This test verifies test_paths validation in strict mode
75
+ it('should validate test_paths existence by default (strict=true)', () => {
76
+ const result = validateCreateSpec({
77
+ ...baseOpts,
78
+ opts: {
79
+ ...baseOpts.opts,
80
+ testPathsUnit: [NON_EXISTENT_TEST_PATH],
81
+ },
82
+ });
83
+ // In strict mode, non-existent test paths should be caught
84
+ expect(result.valid).toBe(false);
85
+ expect(result.errors.some((e) => e.includes('test') || e.includes('not found'))).toBe(true);
86
+ });
87
+ });
88
+ describe('--no-strict logging', () => {
89
+ let consoleSpy;
90
+ beforeEach(() => {
91
+ consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
92
+ });
93
+ afterEach(() => {
94
+ consoleSpy.mockRestore();
95
+ });
96
+ // WU-1329: This test verifies --no-strict usage is logged
97
+ it('should log warning when --no-strict is used', () => {
98
+ validateCreateSpec({
99
+ id: 'WU-9999',
100
+ lane: 'Framework: CLI',
101
+ title: 'Test WU',
102
+ priority: 'P2',
103
+ type: 'feature',
104
+ opts: {
105
+ description: 'Context: test context.\nProblem: test problem.\nSolution: test solution that exceeds minimum.',
106
+ acceptance: ['Acceptance criterion'],
107
+ codePaths: [NON_EXISTENT_CODE_PATH],
108
+ testPathsUnit: [NON_EXISTENT_TEST_PATH],
109
+ exposure: 'backend-only',
110
+ specRefs: ['lumenflow://plans/WU-9999-plan.md'],
111
+ strict: false,
112
+ },
113
+ });
114
+ // Should log that strict validation was bypassed
115
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('strict validation bypassed'));
116
+ });
117
+ });
118
+ });
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @file wu-edit-strict.test.ts
3
+ * Test suite for wu:edit strict validation behavior (WU-1329)
4
+ *
5
+ * WU-1329: Make wu:edit run strict validation by default
6
+ *
7
+ * Tests:
8
+ * - applyEdits function works correctly (unit test for edit logic)
9
+ * - validateDoneWUEdits properly validates done WU edits
10
+ * - The main() function validates paths in strict mode (covered by e2e tests)
11
+ */
12
+ import { describe, it, expect } from 'vitest';
13
+ // Import test utilities (WU-1329)
14
+ import { applyEdits, validateDoneWUEdits, validateExposureValue } from '../wu-edit.js';
15
+ // WU-1329: Constants for test file paths
16
+ const TEST_NEW_FILE_PATH = 'new/file.ts';
17
+ const TEST_NEW_TEST_PATH = 'new/test.test.ts';
18
+ describe('wu:edit strict validation (WU-1329)', () => {
19
+ describe('applyEdits code_paths handling', () => {
20
+ const baseWU = {
21
+ id: 'WU-9999',
22
+ title: 'Test WU',
23
+ lane: 'Framework: CLI',
24
+ type: 'feature',
25
+ status: 'ready',
26
+ priority: 'P2',
27
+ description: 'Context: test context.\nProblem: test problem.\nSolution: test solution that exceeds minimum length.',
28
+ acceptance: ['Existing criterion'],
29
+ code_paths: ['packages/@lumenflow/cli/src/wu-edit.ts'],
30
+ tests: {
31
+ unit: ['packages/@lumenflow/cli/src/__tests__/wu-edit-strict.test.ts'],
32
+ manual: [],
33
+ e2e: [],
34
+ },
35
+ };
36
+ // WU-1329: applyEdits transforms WU object - path validation is done separately
37
+ it('should apply code_paths edits correctly', () => {
38
+ const result = applyEdits(baseWU, {
39
+ codePaths: [TEST_NEW_FILE_PATH],
40
+ replaceCodePaths: true,
41
+ });
42
+ // applyEdits transforms the WU, validation happens later in main()
43
+ expect(result.code_paths).toContain(TEST_NEW_FILE_PATH);
44
+ expect(result.code_paths).toHaveLength(1);
45
+ });
46
+ it('should append code_paths by default', () => {
47
+ const result = applyEdits(baseWU, {
48
+ codePaths: [TEST_NEW_FILE_PATH],
49
+ });
50
+ expect(result.code_paths).toContain('packages/@lumenflow/cli/src/wu-edit.ts');
51
+ expect(result.code_paths).toContain(TEST_NEW_FILE_PATH);
52
+ expect(result.code_paths).toHaveLength(2);
53
+ });
54
+ it('should apply test_paths edits correctly', () => {
55
+ const result = applyEdits(baseWU, {
56
+ testPathsUnit: [TEST_NEW_TEST_PATH],
57
+ });
58
+ // Should append test paths
59
+ expect(result.tests.unit).toContain('packages/@lumenflow/cli/src/__tests__/wu-edit-strict.test.ts');
60
+ expect(result.tests.unit).toContain(TEST_NEW_TEST_PATH);
61
+ });
62
+ });
63
+ describe('validateDoneWUEdits', () => {
64
+ // WU-1329: Done WUs only allow initiative/phase/exposure edits
65
+ it('should allow exposure edits on done WUs', () => {
66
+ const result = validateDoneWUEdits({ exposure: 'backend-only' });
67
+ expect(result.valid).toBe(true);
68
+ expect(result.disallowedEdits).toHaveLength(0);
69
+ });
70
+ it('should disallow code_paths edits on done WUs', () => {
71
+ const result = validateDoneWUEdits({ codePaths: [TEST_NEW_FILE_PATH] });
72
+ expect(result.valid).toBe(false);
73
+ expect(result.disallowedEdits).toContain('--code-paths');
74
+ });
75
+ it('should disallow description edits on done WUs', () => {
76
+ const result = validateDoneWUEdits({ description: 'new description' });
77
+ expect(result.valid).toBe(false);
78
+ expect(result.disallowedEdits).toContain('--description');
79
+ });
80
+ });
81
+ describe('validateExposureValue', () => {
82
+ it('should accept valid exposure values', () => {
83
+ expect(validateExposureValue('ui').valid).toBe(true);
84
+ expect(validateExposureValue('api').valid).toBe(true);
85
+ expect(validateExposureValue('backend-only').valid).toBe(true);
86
+ expect(validateExposureValue('documentation').valid).toBe(true);
87
+ });
88
+ it('should reject invalid exposure values', () => {
89
+ const result = validateExposureValue('invalid-exposure');
90
+ expect(result.valid).toBe(false);
91
+ expect(result.error).toContain('Invalid exposure value');
92
+ });
93
+ });
94
+ describe('noStrict option support', () => {
95
+ // WU-1329: Verify CLI option parsing pattern
96
+ it('should support noStrict option in CLI argument pattern', () => {
97
+ // CLI uses --no-strict which Commander.js parses as noStrict
98
+ // The main() function converts this to strict: !noStrict
99
+ const cliArgs = { noStrict: true };
100
+ const strict = !cliArgs.noStrict;
101
+ expect(strict).toBe(false);
102
+ });
103
+ it('should default to strict=true when noStrict is undefined', () => {
104
+ const cliArgs = { noStrict: undefined };
105
+ const strict = !cliArgs.noStrict;
106
+ expect(strict).toBe(true);
107
+ });
108
+ });
109
+ });
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @file wu-validate-strict.test.ts
3
+ * Test suite for wu:validate strict validation behavior (WU-1329)
4
+ *
5
+ * WU-1329: Make wu:validate treat warnings as errors by default
6
+ *
7
+ * Tests:
8
+ * - Default strict mode behavior (warnings treated as errors)
9
+ * - --no-strict flag restores original behavior (warnings advisory)
10
+ * - Help text documents strict default
11
+ */
12
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
13
+ import { WU_OPTIONS, NEGATED_OPTIONS } from '@lumenflow/core/dist/arg-parser.js';
14
+ describe('wu:validate strict validation (WU-1329)', () => {
15
+ describe('WU_OPTIONS.noStrict configuration', () => {
16
+ // WU-1329: Verify the noStrict option is properly configured
17
+ it('should have noStrict option defined in WU_OPTIONS', () => {
18
+ expect(WU_OPTIONS.noStrict).toBeDefined();
19
+ expect(WU_OPTIONS.noStrict.name).toBe('noStrict');
20
+ expect(WU_OPTIONS.noStrict.flags).toBe('--no-strict');
21
+ expect(WU_OPTIONS.noStrict.isNegated).toBe(true);
22
+ });
23
+ it('should include description about bypassing strict validation', () => {
24
+ expect(WU_OPTIONS.noStrict.description).toContain('Bypass strict validation');
25
+ });
26
+ // WU-1329: Verify 'strict' is in NEGATED_OPTIONS array
27
+ it('should include strict in NEGATED_OPTIONS array', () => {
28
+ expect(NEGATED_OPTIONS).toContain('strict');
29
+ });
30
+ });
31
+ describe('strict mode logic', () => {
32
+ // WU-1329: Verify the strict mode conversion pattern
33
+ it('should default to strict=true when noStrict is undefined', () => {
34
+ const args = { noStrict: undefined };
35
+ const strict = !args.noStrict;
36
+ expect(strict).toBe(true);
37
+ });
38
+ it('should set strict=false when noStrict is true (--no-strict flag)', () => {
39
+ const args = { noStrict: true };
40
+ const strict = !args.noStrict;
41
+ expect(strict).toBe(false);
42
+ });
43
+ it('should set strict=true when noStrict is false (explicit)', () => {
44
+ const args = { noStrict: false };
45
+ const strict = !args.noStrict;
46
+ expect(strict).toBe(true);
47
+ });
48
+ });
49
+ describe('--no-strict logging behavior', () => {
50
+ let consoleSpy;
51
+ beforeEach(() => {
52
+ consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
53
+ });
54
+ afterEach(() => {
55
+ consoleSpy.mockRestore();
56
+ });
57
+ // WU-1329: The logging behavior is implemented in main() functions
58
+ // This test documents the expected behavior pattern using the spy
59
+ it('should log when --no-strict bypass is used', () => {
60
+ // Simulate the logging pattern from wu-validate.ts main()
61
+ const noStrict = true;
62
+ const LOG_PREFIX = '[wu:validate]';
63
+ const message = `${LOG_PREFIX} WARNING: strict validation bypassed (--no-strict). Warnings will be advisory only.`;
64
+ if (noStrict) {
65
+ // Use the spy to simulate logging
66
+ consoleSpy(message);
67
+ }
68
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('strict validation bypassed'));
69
+ });
70
+ it('should not log when strict mode is active', () => {
71
+ // When noStrict is false, no logging should occur
72
+ const noStrict = false;
73
+ if (noStrict) {
74
+ consoleSpy('This should not be called');
75
+ }
76
+ expect(consoleSpy).not.toHaveBeenCalled();
77
+ });
78
+ });
79
+ describe('validateSingleWU strict mode behavior', () => {
80
+ // WU-1329: These tests document the expected behavior
81
+ // The actual validation is done by calling the CLI command
82
+ it('should treat warnings as errors by default (strict=true)', () => {
83
+ // In strict mode, any warnings from completeness validation
84
+ // should become errors and cause validation to fail
85
+ const strict = true;
86
+ const warnings = ['Missing recommended field: notes'];
87
+ const errors = [];
88
+ if (strict && warnings.length > 0) {
89
+ errors.push(...warnings.map((w) => `[STRICT] ${w}`));
90
+ }
91
+ expect(errors.length).toBeGreaterThan(0);
92
+ expect(errors[0]).toContain('[STRICT]');
93
+ });
94
+ it('should allow warnings when strict=false (--no-strict)', () => {
95
+ // In non-strict mode, warnings should remain warnings
96
+ // and validation should pass
97
+ const strict = false;
98
+ const warnings = ['Missing recommended field: notes'];
99
+ const errors = [];
100
+ if (strict && warnings.length > 0) {
101
+ errors.push(...warnings.map((w) => `[STRICT] ${w}`));
102
+ }
103
+ expect(errors.length).toBe(0);
104
+ });
105
+ });
106
+ describe('help text documentation', () => {
107
+ // WU-1329: Verify help text documents strict default
108
+ it('should document that --no-strict bypasses strict validation', () => {
109
+ const expectedDescription = 'Bypass strict validation';
110
+ expect(WU_OPTIONS.noStrict.description).toContain(expectedDescription);
111
+ });
112
+ });
113
+ });
@@ -15,8 +15,9 @@
15
15
  */
16
16
  import { Command } from 'commander';
17
17
  import { getBottleneckAnalysis, } from '@lumenflow/metrics';
18
- import { buildDependencyGraphAsync, renderMermaid, } from '@lumenflow/core/dist/dependency-graph.js';
18
+ import { buildDependencyGraphAsync, renderMermaid } from '@lumenflow/core/dist/dependency-graph.js';
19
19
  import { die } from '@lumenflow/core/dist/error-handler.js';
20
+ import { getConfig } from '@lumenflow/core/dist/lumenflow-config.js';
20
21
  /** Log prefix for console output */
21
22
  const LOG_PREFIX = '[flow:bottlenecks]';
22
23
  /** Default bottleneck limit */
@@ -147,7 +148,8 @@ async function main() {
147
148
  const coreGraph = await buildDependencyGraphAsync();
148
149
  if (coreGraph.size === 0) {
149
150
  console.log(`${LOG_PREFIX} No WUs found in dependency graph.`);
150
- console.log(`${LOG_PREFIX} Ensure WU YAML files exist in docs/04-operations/tasks/wu/ with blocked_by/blocks fields.`);
151
+ // WU-1311: Use config-based WU directory path
152
+ console.log(`${LOG_PREFIX} Ensure WU YAML files exist in ${getConfig().directories.wuDir}/ with blocked_by/blocks fields.`);
151
153
  return;
152
154
  }
153
155
  console.log(`${LOG_PREFIX} Found ${coreGraph.size} WUs in graph`);
package/dist/gates.js CHANGED
@@ -68,6 +68,8 @@ import { runSystemMapValidation } from '@lumenflow/core/dist/system-map-validato
68
68
  import { loadLaneHealthConfig, resolveTestPolicy, } from '@lumenflow/core/dist/gates-config.js';
69
69
  // WU-1191: Lane health check
70
70
  import { runLaneHealthCheck } from './lane-health.js';
71
+ // WU-1315: Onboarding smoke test
72
+ import { runOnboardingSmokeTestGate } from './onboarding-smoke-test.js';
71
73
  import { BRANCHES, PACKAGES, PKG_MANAGER, ESLINT_FLAGS, ESLINT_COMMANDS, ESLINT_DEFAULTS, SCRIPTS, CACHE_STRATEGIES, DIRECTORIES, GATE_NAMES, GATE_COMMANDS, CLI_MODES, EXIT_CODES, FILE_SYSTEM, PRETTIER_ARGS, PRETTIER_FLAGS, } from '@lumenflow/core/dist/wu-constants.js';
72
74
  /**
73
75
  * WU-1087: Gates-specific option definitions for createWUParser.
@@ -1115,6 +1117,11 @@ async function executeGates(opts) {
1115
1117
  run: (ctx) => runLaneHealthGate({ ...ctx, mode: laneHealthMode }),
1116
1118
  warnOnly: laneHealthMode !== 'error',
1117
1119
  },
1120
+ // WU-1315: Onboarding smoke test (init + wu:create validation)
1121
+ {
1122
+ name: GATE_NAMES.ONBOARDING_SMOKE_TEST,
1123
+ cmd: GATE_COMMANDS.ONBOARDING_SMOKE_TEST,
1124
+ },
1118
1125
  // WU-1299: Filtered tests for packages in code_paths (if any)
1119
1126
  // When docs-only mode has packages in code_paths, run tests only for those packages
1120
1127
  // This prevents pre-existing failures in unrelated packages from blocking
@@ -1163,6 +1170,11 @@ async function executeGates(opts) {
1163
1170
  run: (ctx) => runLaneHealthGate({ ...ctx, mode: laneHealthMode }),
1164
1171
  warnOnly: laneHealthMode !== 'error',
1165
1172
  },
1173
+ // WU-1315: Onboarding smoke test (init + wu:create validation)
1174
+ {
1175
+ name: GATE_NAMES.ONBOARDING_SMOKE_TEST,
1176
+ cmd: GATE_COMMANDS.ONBOARDING_SMOKE_TEST,
1177
+ },
1166
1178
  // WU-2062: Safety-critical tests ALWAYS run
1167
1179
  // WU-1280: When tests_required=false (methodology.testing: none), failures only warn
1168
1180
  {
@@ -1285,6 +1297,16 @@ async function executeGates(opts) {
1285
1297
  : console,
1286
1298
  });
1287
1299
  }
1300
+ else if (gate.cmd === GATE_COMMANDS.ONBOARDING_SMOKE_TEST) {
1301
+ // WU-1315: Onboarding smoke test (init + wu:create validation)
1302
+ const logLine = useAgentMode
1303
+ ? (line) => writeSync(agentLog.logFd, `${line}\n`)
1304
+ : (line) => console.log(line);
1305
+ logLine('\n> Onboarding smoke test\n');
1306
+ result = await runOnboardingSmokeTestGate({
1307
+ logger: { log: logLine },
1308
+ });
1309
+ }
1288
1310
  else {
1289
1311
  result = run(gate.cmd, { agentLog });
1290
1312
  }