@lumenflow/cli 2.20.1 → 2.21.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 (111) hide show
  1. package/README.md +8 -4
  2. package/dist/hooks/enforcement-checks.js +120 -0
  3. package/dist/hooks/enforcement-checks.js.map +1 -1
  4. package/dist/init-lane-validation.js +141 -0
  5. package/dist/init-lane-validation.js.map +1 -0
  6. package/dist/init-templates.js +36 -8
  7. package/dist/init-templates.js.map +1 -1
  8. package/dist/init.js +27 -58
  9. package/dist/init.js.map +1 -1
  10. package/dist/initiative-create.js +35 -4
  11. package/dist/initiative-create.js.map +1 -1
  12. package/dist/lane-lifecycle-process.js +364 -0
  13. package/dist/lane-lifecycle-process.js.map +1 -0
  14. package/dist/lane-lock.js +41 -0
  15. package/dist/lane-lock.js.map +1 -0
  16. package/dist/lane-setup.js +55 -0
  17. package/dist/lane-setup.js.map +1 -0
  18. package/dist/lane-status.js +38 -0
  19. package/dist/lane-status.js.map +1 -0
  20. package/dist/lane-validate.js +43 -0
  21. package/dist/lane-validate.js.map +1 -0
  22. package/dist/onboarding-smoke-test.js +17 -0
  23. package/dist/onboarding-smoke-test.js.map +1 -1
  24. package/dist/public-manifest.js +28 -0
  25. package/dist/public-manifest.js.map +1 -1
  26. package/dist/wu-claim-cloud.js +16 -0
  27. package/dist/wu-claim-cloud.js.map +1 -1
  28. package/dist/wu-claim.js +12 -2
  29. package/dist/wu-claim.js.map +1 -1
  30. package/dist/wu-create-content.js +8 -2
  31. package/dist/wu-create-content.js.map +1 -1
  32. package/dist/wu-create-validation.js +5 -3
  33. package/dist/wu-create-validation.js.map +1 -1
  34. package/dist/wu-create.js +21 -1
  35. package/dist/wu-create.js.map +1 -1
  36. package/dist/wu-done.js +57 -8
  37. package/dist/wu-done.js.map +1 -1
  38. package/dist/wu-prep.js +22 -0
  39. package/dist/wu-prep.js.map +1 -1
  40. package/package.json +15 -11
  41. package/dist/__tests__/agent-log-issue.test.js +0 -56
  42. package/dist/__tests__/agent-spawn-coordination.test.js +0 -451
  43. package/dist/__tests__/backlog-prune.test.js +0 -478
  44. package/dist/__tests__/cli-entry-point.test.js +0 -160
  45. package/dist/__tests__/cli-subprocess.test.js +0 -89
  46. package/dist/__tests__/commands/integrate.test.js +0 -165
  47. package/dist/__tests__/commands.test.js +0 -271
  48. package/dist/__tests__/deps-operations.test.js +0 -206
  49. package/dist/__tests__/doctor.test.js +0 -510
  50. package/dist/__tests__/file-operations.test.js +0 -906
  51. package/dist/__tests__/flow-report.test.js +0 -24
  52. package/dist/__tests__/gates-config.test.js +0 -303
  53. package/dist/__tests__/gates-integration-tests.test.js +0 -112
  54. package/dist/__tests__/git-operations.test.js +0 -668
  55. package/dist/__tests__/guard-main-branch.test.js +0 -79
  56. package/dist/__tests__/guards-validation.test.js +0 -416
  57. package/dist/__tests__/hooks/enforcement.test.js +0 -279
  58. package/dist/__tests__/init-config-lanes.test.js +0 -131
  59. package/dist/__tests__/init-docs-structure.test.js +0 -152
  60. package/dist/__tests__/init-greenfield.test.js +0 -247
  61. package/dist/__tests__/init-lane-inference.test.js +0 -125
  62. package/dist/__tests__/init-onboarding-docs.test.js +0 -132
  63. package/dist/__tests__/init-quick-ref.test.js +0 -144
  64. package/dist/__tests__/init-scripts.test.js +0 -207
  65. package/dist/__tests__/init-template-portability.test.js +0 -96
  66. package/dist/__tests__/init.test.js +0 -968
  67. package/dist/__tests__/initiative-add-wu.test.js +0 -490
  68. package/dist/__tests__/initiative-e2e.test.js +0 -442
  69. package/dist/__tests__/initiative-plan-replacement.test.js +0 -161
  70. package/dist/__tests__/initiative-plan.test.js +0 -340
  71. package/dist/__tests__/initiative-remove-wu.test.js +0 -458
  72. package/dist/__tests__/lumenflow-upgrade.test.js +0 -260
  73. package/dist/__tests__/mem-cleanup-execution.test.js +0 -19
  74. package/dist/__tests__/memory-integration.test.js +0 -333
  75. package/dist/__tests__/merge-block.test.js +0 -220
  76. package/dist/__tests__/metrics-cli.test.js +0 -619
  77. package/dist/__tests__/metrics-snapshot.test.js +0 -24
  78. package/dist/__tests__/no-beacon-references-docs.test.js +0 -30
  79. package/dist/__tests__/no-beacon-references.test.js +0 -39
  80. package/dist/__tests__/onboarding-smoke-test.test.js +0 -211
  81. package/dist/__tests__/path-centralization-cli.test.js +0 -234
  82. package/dist/__tests__/plan-create.test.js +0 -126
  83. package/dist/__tests__/plan-edit.test.js +0 -157
  84. package/dist/__tests__/plan-link.test.js +0 -239
  85. package/dist/__tests__/plan-promote.test.js +0 -181
  86. package/dist/__tests__/release.test.js +0 -372
  87. package/dist/__tests__/rotate-progress.test.js +0 -127
  88. package/dist/__tests__/safe-git.test.js +0 -190
  89. package/dist/__tests__/session-coordinator.test.js +0 -109
  90. package/dist/__tests__/state-bootstrap.test.js +0 -432
  91. package/dist/__tests__/state-doctor.test.js +0 -328
  92. package/dist/__tests__/sync-templates.test.js +0 -255
  93. package/dist/__tests__/templates-sync.test.js +0 -219
  94. package/dist/__tests__/trace-gen.test.js +0 -115
  95. package/dist/__tests__/wu-create-required-fields.test.js +0 -143
  96. package/dist/__tests__/wu-create-strict.test.js +0 -118
  97. package/dist/__tests__/wu-create.test.js +0 -121
  98. package/dist/__tests__/wu-done-auto-cleanup.test.js +0 -135
  99. package/dist/__tests__/wu-done-docs-only-policy.test.js +0 -20
  100. package/dist/__tests__/wu-done-staging-whitelist.test.js +0 -35
  101. package/dist/__tests__/wu-done.test.js +0 -36
  102. package/dist/__tests__/wu-edit-strict.test.js +0 -109
  103. package/dist/__tests__/wu-edit.test.js +0 -119
  104. package/dist/__tests__/wu-lifecycle-integration.test.js +0 -388
  105. package/dist/__tests__/wu-prep-default-exec.test.js +0 -35
  106. package/dist/__tests__/wu-prep.test.js +0 -140
  107. package/dist/__tests__/wu-proto.test.js +0 -97
  108. package/dist/__tests__/wu-validate-strict.test.js +0 -113
  109. package/dist/__tests__/wu-validate.test.js +0 -36
  110. package/dist/spawn-list.js +0 -143
  111. package/dist/spawn-list.js.map +0 -1
@@ -1,24 +0,0 @@
1
- /**
2
- * @file flow-report.test.ts
3
- * @description Tests for flow-report CLI command (WU-1018)
4
- *
5
- * These are smoke tests to verify the CLI module can be imported.
6
- * The CLI commands are wrappers around @lumenflow/metrics library functions
7
- * which have their own comprehensive tests.
8
- */
9
- import { describe, it, expect } from 'vitest';
10
- import { existsSync } from 'node:fs';
11
- import { join } from 'node:path';
12
- import { fileURLToPath } from 'node:url';
13
- const __dirname = fileURLToPath(new URL('.', import.meta.url));
14
- describe('flow-report CLI', () => {
15
- it('should have the CLI source file', () => {
16
- const srcPath = join(__dirname, '../flow-report.ts');
17
- expect(existsSync(srcPath)).toBe(true);
18
- });
19
- it('should be buildable (dist file exists after build)', () => {
20
- // This test verifies that tsc compiled the file successfully
21
- const distPath = join(__dirname, '../../dist/flow-report.js');
22
- expect(existsSync(distPath)).toBe(true);
23
- });
24
- });
@@ -1,303 +0,0 @@
1
- /**
2
- * @file gates-config.test.ts
3
- * WU-1356: Tests for package manager and script name configuration.
4
- *
5
- * Tests configurable package_manager, gates.commands, test_runner, and build_command
6
- * in .lumenflow.config.yaml for framework agnosticism.
7
- */
8
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
- import * as fs from 'node:fs';
10
- import * as path from 'node:path';
11
- import * as os from 'node:os';
12
- import * as yaml from 'yaml';
13
- // Import the schema and functions we're testing
14
- import { PackageManagerSchema, TestRunnerSchema, GatesCommandsConfigSchema, parseConfig, } from '@lumenflow/core/dist/lumenflow-config-schema.js';
15
- import { resolvePackageManager, resolveBuildCommand, resolveGatesCommands, resolveTestRunner, getIgnorePatterns, } from '@lumenflow/core/dist/gates-config.js';
16
- describe('WU-1356: Package manager and script configuration', () => {
17
- let tempDir;
18
- beforeEach(() => {
19
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lumenflow-test-'));
20
- });
21
- afterEach(() => {
22
- fs.rmSync(tempDir, { recursive: true, force: true });
23
- });
24
- describe('PackageManagerSchema', () => {
25
- it('accepts pnpm as default', () => {
26
- const result = PackageManagerSchema.parse(undefined);
27
- expect(result).toBe('pnpm');
28
- });
29
- it('accepts npm', () => {
30
- const result = PackageManagerSchema.parse('npm');
31
- expect(result).toBe('npm');
32
- });
33
- it('accepts yarn', () => {
34
- const result = PackageManagerSchema.parse('yarn');
35
- expect(result).toBe('yarn');
36
- });
37
- it('accepts bun', () => {
38
- const result = PackageManagerSchema.parse('bun');
39
- expect(result).toBe('bun');
40
- });
41
- it('rejects invalid package manager', () => {
42
- expect(() => PackageManagerSchema.parse('invalid')).toThrow();
43
- });
44
- });
45
- describe('TestRunnerSchema', () => {
46
- it('accepts vitest as default', () => {
47
- const result = TestRunnerSchema.parse(undefined);
48
- expect(result).toBe('vitest');
49
- });
50
- it('accepts jest', () => {
51
- const result = TestRunnerSchema.parse('jest');
52
- expect(result).toBe('jest');
53
- });
54
- it('accepts mocha', () => {
55
- const result = TestRunnerSchema.parse('mocha');
56
- expect(result).toBe('mocha');
57
- });
58
- it('rejects invalid test runner', () => {
59
- expect(() => TestRunnerSchema.parse('invalid')).toThrow();
60
- });
61
- });
62
- describe('GatesCommandsConfigSchema', () => {
63
- it('has sensible defaults for test commands', () => {
64
- const result = GatesCommandsConfigSchema.parse({});
65
- expect(result.test_full).toBeDefined();
66
- expect(result.test_docs_only).toBeDefined();
67
- expect(result.test_incremental).toBeDefined();
68
- });
69
- it('allows custom test commands', () => {
70
- const config = {
71
- test_full: 'npm test',
72
- test_docs_only: 'npm test -- --grep docs',
73
- test_incremental: 'npm test -- --changed',
74
- };
75
- const result = GatesCommandsConfigSchema.parse(config);
76
- expect(result.test_full).toBe('npm test');
77
- expect(result.test_docs_only).toBe('npm test -- --grep docs');
78
- expect(result.test_incremental).toBe('npm test -- --changed');
79
- });
80
- });
81
- describe('LumenFlowConfigSchema - package_manager field', () => {
82
- it('includes package_manager with default pnpm', () => {
83
- const config = parseConfig({});
84
- expect(config.package_manager).toBe('pnpm');
85
- });
86
- it('accepts npm as package_manager', () => {
87
- const config = parseConfig({ package_manager: 'npm' });
88
- expect(config.package_manager).toBe('npm');
89
- });
90
- it('accepts yarn as package_manager', () => {
91
- const config = parseConfig({ package_manager: 'yarn' });
92
- expect(config.package_manager).toBe('yarn');
93
- });
94
- it('accepts bun as package_manager', () => {
95
- const config = parseConfig({ package_manager: 'bun' });
96
- expect(config.package_manager).toBe('bun');
97
- });
98
- });
99
- describe('LumenFlowConfigSchema - test_runner field', () => {
100
- it('includes test_runner with default vitest', () => {
101
- const config = parseConfig({});
102
- expect(config.test_runner).toBe('vitest');
103
- });
104
- it('accepts jest as test_runner', () => {
105
- const config = parseConfig({ test_runner: 'jest' });
106
- expect(config.test_runner).toBe('jest');
107
- });
108
- it('accepts mocha as test_runner', () => {
109
- const config = parseConfig({ test_runner: 'mocha' });
110
- expect(config.test_runner).toBe('mocha');
111
- });
112
- });
113
- describe('LumenFlowConfigSchema - gates.commands section', () => {
114
- it('includes gates.commands with defaults', () => {
115
- const config = parseConfig({});
116
- expect(config.gates.commands).toBeDefined();
117
- expect(config.gates.commands.test_full).toBeDefined();
118
- expect(config.gates.commands.test_docs_only).toBeDefined();
119
- expect(config.gates.commands.test_incremental).toBeDefined();
120
- });
121
- it('allows custom gates commands configuration', () => {
122
- const config = parseConfig({
123
- gates: {
124
- commands: {
125
- test_full: 'npm test',
126
- test_docs_only: 'npm test -- --docs',
127
- test_incremental: 'npm test -- --changed',
128
- },
129
- },
130
- });
131
- expect(config.gates.commands.test_full).toBe('npm test');
132
- expect(config.gates.commands.test_docs_only).toBe('npm test -- --docs');
133
- expect(config.gates.commands.test_incremental).toBe('npm test -- --changed');
134
- });
135
- });
136
- describe('LumenFlowConfigSchema - build_command field', () => {
137
- it('includes build_command with default for pnpm', () => {
138
- const config = parseConfig({});
139
- expect(config.build_command).toBe('pnpm --filter @lumenflow/cli build');
140
- });
141
- it('allows custom build_command', () => {
142
- const config = parseConfig({ build_command: 'npm run build' });
143
- expect(config.build_command).toBe('npm run build');
144
- });
145
- });
146
- describe('resolvePackageManager', () => {
147
- it('returns pnpm when no config file exists', () => {
148
- const result = resolvePackageManager(tempDir);
149
- expect(result).toBe('pnpm');
150
- });
151
- it('returns configured package manager from config file', () => {
152
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
153
- fs.writeFileSync(configPath, yaml.stringify({ package_manager: 'npm' }));
154
- const result = resolvePackageManager(tempDir);
155
- expect(result).toBe('npm');
156
- });
157
- it('returns yarn when configured', () => {
158
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
159
- fs.writeFileSync(configPath, yaml.stringify({ package_manager: 'yarn' }));
160
- const result = resolvePackageManager(tempDir);
161
- expect(result).toBe('yarn');
162
- });
163
- });
164
- describe('resolveBuildCommand', () => {
165
- it('returns default build command when no config file exists', () => {
166
- const result = resolveBuildCommand(tempDir);
167
- expect(result).toBe('pnpm --filter @lumenflow/cli build');
168
- });
169
- it('returns configured build_command from config file', () => {
170
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
171
- fs.writeFileSync(configPath, yaml.stringify({ build_command: 'npm run build' }));
172
- const result = resolveBuildCommand(tempDir);
173
- expect(result).toBe('npm run build');
174
- });
175
- it('adapts default build command for different package managers', () => {
176
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
177
- fs.writeFileSync(configPath, yaml.stringify({ package_manager: 'npm' }));
178
- const result = resolveBuildCommand(tempDir);
179
- expect(result).toContain('npm');
180
- });
181
- });
182
- describe('resolveGatesCommands', () => {
183
- it('returns default commands when no config file exists', () => {
184
- const commands = resolveGatesCommands(tempDir);
185
- expect(commands.test_full).toBeDefined();
186
- expect(commands.test_docs_only).toBeDefined();
187
- expect(commands.test_incremental).toBeDefined();
188
- });
189
- it('returns configured commands from config file', () => {
190
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
191
- fs.writeFileSync(configPath, yaml.stringify({
192
- gates: {
193
- commands: {
194
- test_full: 'npm test',
195
- test_docs_only: 'npm test -- --docs',
196
- test_incremental: 'npm test -- --changed',
197
- },
198
- },
199
- }));
200
- const commands = resolveGatesCommands(tempDir);
201
- expect(commands.test_full).toBe('npm test');
202
- expect(commands.test_docs_only).toBe('npm test -- --docs');
203
- expect(commands.test_incremental).toBe('npm test -- --changed');
204
- });
205
- });
206
- describe('resolveTestRunner', () => {
207
- it('returns vitest when no config file exists', () => {
208
- const result = resolveTestRunner(tempDir);
209
- expect(result).toBe('vitest');
210
- });
211
- it('returns jest when configured', () => {
212
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
213
- fs.writeFileSync(configPath, yaml.stringify({ test_runner: 'jest' }));
214
- const result = resolveTestRunner(tempDir);
215
- expect(result).toBe('jest');
216
- });
217
- });
218
- describe('getIgnorePatterns', () => {
219
- it('returns .turbo pattern for vitest', () => {
220
- const patterns = getIgnorePatterns('vitest');
221
- expect(patterns).toContain('.turbo');
222
- });
223
- it('returns different pattern for jest', () => {
224
- const patterns = getIgnorePatterns('jest');
225
- expect(patterns).not.toContain('.turbo');
226
- });
227
- it('returns custom pattern from config', () => {
228
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
229
- fs.writeFileSync(configPath, yaml.stringify({
230
- gates: {
231
- ignore_patterns: ['.nx', 'dist'],
232
- },
233
- }));
234
- // This would be a config-aware version
235
- const patterns = getIgnorePatterns('jest');
236
- expect(Array.isArray(patterns)).toBe(true);
237
- });
238
- });
239
- });
240
- describe('WU-1356: npm+jest configuration', () => {
241
- let tempDir;
242
- beforeEach(() => {
243
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lumenflow-npm-jest-'));
244
- });
245
- afterEach(() => {
246
- fs.rmSync(tempDir, { recursive: true, force: true });
247
- });
248
- it('supports npm+jest configuration', () => {
249
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
250
- fs.writeFileSync(configPath, yaml.stringify({
251
- package_manager: 'npm',
252
- test_runner: 'jest',
253
- gates: {
254
- commands: {
255
- test_full: 'npm test',
256
- test_docs_only: 'npm test -- --testPathPattern=docs',
257
- test_incremental: 'npm test -- --onlyChanged',
258
- },
259
- },
260
- build_command: 'npm run build',
261
- }));
262
- const pkgManager = resolvePackageManager(tempDir);
263
- const testRunner = resolveTestRunner(tempDir);
264
- const commands = resolveGatesCommands(tempDir);
265
- const buildCmd = resolveBuildCommand(tempDir);
266
- expect(pkgManager).toBe('npm');
267
- expect(testRunner).toBe('jest');
268
- expect(commands.test_full).toBe('npm test');
269
- expect(commands.test_incremental).toBe('npm test -- --onlyChanged');
270
- expect(buildCmd).toBe('npm run build');
271
- });
272
- });
273
- describe('WU-1356: yarn+nx configuration', () => {
274
- let tempDir;
275
- beforeEach(() => {
276
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lumenflow-yarn-nx-'));
277
- });
278
- afterEach(() => {
279
- fs.rmSync(tempDir, { recursive: true, force: true });
280
- });
281
- it('supports yarn+nx configuration', () => {
282
- const configPath = path.join(tempDir, '.lumenflow.config.yaml');
283
- fs.writeFileSync(configPath, yaml.stringify({
284
- package_manager: 'yarn',
285
- test_runner: 'jest',
286
- gates: {
287
- commands: {
288
- test_full: 'yarn nx run-many --target=test --all',
289
- test_docs_only: 'yarn nx test docs',
290
- test_incremental: 'yarn nx affected --target=test',
291
- },
292
- },
293
- build_command: 'yarn nx build @lumenflow/cli',
294
- }));
295
- const pkgManager = resolvePackageManager(tempDir);
296
- const commands = resolveGatesCommands(tempDir);
297
- const buildCmd = resolveBuildCommand(tempDir);
298
- expect(pkgManager).toBe('yarn');
299
- expect(commands.test_full).toBe('yarn nx run-many --target=test --all');
300
- expect(commands.test_incremental).toBe('yarn nx affected --target=test');
301
- expect(buildCmd).toBe('yarn nx build @lumenflow/cli');
302
- });
303
- });
@@ -1,112 +0,0 @@
1
- /**
2
- * @file gates-integration-tests.test.ts
3
- * @description Tests for gates infrastructure fixes (WU-1415)
4
- *
5
- * Bug 1: vitest --include is not a valid CLI option
6
- * Bug 2: docs-only turbo filter uses directory names instead of package names
7
- */
8
- import { describe, it, expect } from 'vitest';
9
- import { extractPackagesFromCodePaths, resolveDocsOnlyTestPlan } from '../gates.js';
10
- describe('WU-1415: Gates infrastructure fixes', () => {
11
- describe('Bug 1: vitest integration test command', () => {
12
- it('should NOT use --include flag (vitest does not support it)', async () => {
13
- // Import the module to inspect the command construction
14
- // We need to verify that runIntegrationTests uses valid vitest syntax
15
- //
16
- // vitest run accepts positional glob patterns, NOT --include flags:
17
- // WRONG: vitest run --include='**/*.integration.*'
18
- // RIGHT: vitest run '**/*.integration.*'
19
- //
20
- // This test ensures we're using the correct vitest CLI syntax
21
- const gatesModule = await import('../gates.js');
22
- // The command construction happens in runIntegrationTests
23
- // We can't directly test the internal function, but we can verify
24
- // via the module's exported constants or by checking the implementation
25
- // doesn't contain --include
26
- // Read the source to verify no --include in vitest commands
27
- const fs = await import('fs');
28
- const path = await import('path');
29
- const gatesPath = path.join(import.meta.dirname, '..', 'gates.ts');
30
- const source = fs.readFileSync(gatesPath, 'utf-8');
31
- // Find the runIntegrationTests function and check it doesn't use --include
32
- const integrationTestMatch = source.match(/function runIntegrationTests[\s\S]*?^}/m);
33
- if (integrationTestMatch) {
34
- const functionBody = integrationTestMatch[0];
35
- // vitest run should NOT have --include flags
36
- expect(functionBody).not.toMatch(/vitest.*--include/);
37
- // Instead, glob patterns should be positional args or via proper config
38
- // The fix should pass patterns directly: vitest run 'pattern1' 'pattern2'
39
- }
40
- });
41
- });
42
- describe('Bug 2: docs-only turbo filter', () => {
43
- describe('extractPackagesFromCodePaths', () => {
44
- it('should extract scoped package names from packages/ paths', () => {
45
- const codePaths = [
46
- 'packages/@lumenflow/cli/src/gates.ts',
47
- 'packages/@lumenflow/core/src/index.ts',
48
- ];
49
- const packages = extractPackagesFromCodePaths(codePaths);
50
- expect(packages).toContain('@lumenflow/cli');
51
- expect(packages).toContain('@lumenflow/core');
52
- });
53
- it('should return empty array for apps/ paths that are not real turbo packages', () => {
54
- // apps/docs/ directory name is 'docs' but the turbo package might be
55
- // named differently (e.g., '@lumenflow/docs' or not exist at all)
56
- //
57
- // The current implementation returns 'docs' which causes turbo to fail:
58
- // "No package found with name 'docs' in workspace"
59
- //
60
- // Fix: Either lookup actual package.json name or skip apps
61
- const codePaths = ['apps/docs/src/content/docs/', 'apps/github-app/'];
62
- const packages = extractPackagesFromCodePaths(codePaths);
63
- // Current buggy behavior returns ['docs', 'github-app']
64
- // Fixed behavior should either:
65
- // - Return actual package names from package.json
66
- // - Or return empty array (apps don't have turbo test tasks)
67
- //
68
- // For now, the fix should skip apps that aren't valid turbo packages
69
- // because apps/docs has no test script and apps/github-app was deleted
70
- expect(packages).not.toContain('docs');
71
- expect(packages).not.toContain('github-app');
72
- });
73
- it('should handle mixed code_paths (packages + apps + docs)', () => {
74
- const codePaths = [
75
- 'packages/@lumenflow/cli/src/file.ts',
76
- 'apps/docs/astro.config.mjs',
77
- 'docs/DISTRIBUTION.md',
78
- ];
79
- const packages = extractPackagesFromCodePaths(codePaths);
80
- // Should include the real package
81
- expect(packages).toContain('@lumenflow/cli');
82
- // Should NOT include apps (no valid turbo package)
83
- expect(packages).not.toContain('docs');
84
- // Should NOT include docs/ (not a package)
85
- expect(packages.length).toBe(1);
86
- });
87
- it('should return empty array for pure docs paths', () => {
88
- const codePaths = ['docs/01-product/product-lines.md', 'docs/DISTRIBUTION.md'];
89
- const packages = extractPackagesFromCodePaths(codePaths);
90
- expect(packages).toEqual([]);
91
- });
92
- });
93
- describe('resolveDocsOnlyTestPlan', () => {
94
- it('should return skip mode for pure documentation WUs', () => {
95
- const plan = resolveDocsOnlyTestPlan({
96
- codePaths: ['docs/README.md', 'apps/docs/content/'],
97
- });
98
- expect(plan.mode).toBe('skip');
99
- expect(plan.packages).toEqual([]);
100
- });
101
- it('should return filtered mode only for valid package paths', () => {
102
- const plan = resolveDocsOnlyTestPlan({
103
- codePaths: ['packages/@lumenflow/cli/src/gates.ts', 'apps/docs/content/'],
104
- });
105
- expect(plan.mode).toBe('filtered');
106
- expect(plan.packages).toContain('@lumenflow/cli');
107
- // apps/docs should not be included
108
- expect(plan.packages).not.toContain('docs');
109
- });
110
- });
111
- });
112
- });