@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,220 +0,0 @@
1
- /**
2
- * @file merge-block.test.ts
3
- * Tests for merge block functionality (WU-1171)
4
- *
5
- * Tests the LUMENFLOW:START/END block insertion and update logic
6
- * that enables safe, idempotent merging of LumenFlow config into existing files.
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 the functions we'll implement
13
- import { detectLineEnding, extractMergeBlock, insertMergeBlock, updateMergeBlock, } from '../merge-block.js';
14
- describe('merge-block', () => {
15
- let tempDir;
16
- beforeEach(() => {
17
- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'merge-block-test-'));
18
- });
19
- afterEach(() => {
20
- fs.rmSync(tempDir, { recursive: true, force: true });
21
- });
22
- describe('detectLineEnding', () => {
23
- it('should detect LF line endings', () => {
24
- const content = 'line1\nline2\nline3\n';
25
- expect(detectLineEnding(content)).toBe('\n');
26
- });
27
- it('should detect CRLF line endings', () => {
28
- const content = 'line1\r\nline2\r\nline3\r\n';
29
- expect(detectLineEnding(content)).toBe('\r\n');
30
- });
31
- it('should default to LF for empty content', () => {
32
- expect(detectLineEnding('')).toBe('\n');
33
- });
34
- it('should default to LF for content without line endings', () => {
35
- expect(detectLineEnding('single line')).toBe('\n');
36
- });
37
- it('should use majority line ending when mixed', () => {
38
- const content = 'line1\r\nline2\r\nline3\n';
39
- // 2 CRLF vs 1 LF, should detect CRLF
40
- expect(detectLineEnding(content)).toBe('\r\n');
41
- });
42
- });
43
- describe('extractMergeBlock', () => {
44
- it('should extract content between LUMENFLOW:START and LUMENFLOW:END markers', () => {
45
- const content = `# My Project
46
-
47
- <!-- LUMENFLOW:START -->
48
- This is LumenFlow content.
49
- <!-- LUMENFLOW:END -->
50
-
51
- Other content
52
- `;
53
- const result = extractMergeBlock(content);
54
- expect(result.found).toBe(true);
55
- expect(result.content).toBe('This is LumenFlow content.');
56
- expect(result.startIndex).toBeGreaterThan(0);
57
- expect(result.endIndex).toBeGreaterThan(result.startIndex);
58
- });
59
- it('should return not found when no markers exist', () => {
60
- const content = '# My Project\n\nNo LumenFlow content here.';
61
- const result = extractMergeBlock(content);
62
- expect(result.found).toBe(false);
63
- expect(result.content).toBeUndefined();
64
- });
65
- it('should handle malformed markers (only START)', () => {
66
- const content = `# My Project
67
-
68
- <!-- LUMENFLOW:START -->
69
- Incomplete block
70
- `;
71
- const result = extractMergeBlock(content);
72
- expect(result.found).toBe(false);
73
- expect(result.malformed).toBe(true);
74
- expect(result.malformedReason).toBe('missing-end');
75
- });
76
- it('should handle malformed markers (only END)', () => {
77
- const content = `# My Project
78
-
79
- Some content
80
- <!-- LUMENFLOW:END -->
81
- `;
82
- const result = extractMergeBlock(content);
83
- expect(result.found).toBe(false);
84
- expect(result.malformed).toBe(true);
85
- expect(result.malformedReason).toBe('missing-start');
86
- });
87
- it('should handle multiple START markers', () => {
88
- const content = `<!-- LUMENFLOW:START -->
89
- First block
90
- <!-- LUMENFLOW:START -->
91
- Second start
92
- <!-- LUMENFLOW:END -->
93
- `;
94
- const result = extractMergeBlock(content);
95
- expect(result.malformed).toBe(true);
96
- expect(result.malformedReason).toBe('multiple-start');
97
- });
98
- });
99
- describe('insertMergeBlock', () => {
100
- it('should append block to end of file', () => {
101
- const originalContent = '# My Project\n\nExisting content.\n';
102
- const blockContent = 'LumenFlow configuration goes here.';
103
- const result = insertMergeBlock(originalContent, blockContent);
104
- expect(result).toContain('<!-- LUMENFLOW:START -->');
105
- expect(result).toContain(blockContent);
106
- expect(result).toContain('<!-- LUMENFLOW:END -->');
107
- expect(result.startsWith('# My Project')).toBe(true);
108
- });
109
- it('should preserve original line endings (LF)', () => {
110
- const originalContent = '# My Project\nExisting content.\n';
111
- const blockContent = 'New content';
112
- const result = insertMergeBlock(originalContent, blockContent);
113
- // Should not contain CRLF
114
- expect(result).not.toContain('\r\n');
115
- expect(result).toContain('\n');
116
- });
117
- it('should preserve original line endings (CRLF)', () => {
118
- const originalContent = '# My Project\r\nExisting content.\r\n';
119
- const blockContent = 'New content';
120
- const result = insertMergeBlock(originalContent, blockContent);
121
- // Should contain CRLF
122
- expect(result).toContain('\r\n');
123
- });
124
- it('should add blank line before block if not present', () => {
125
- const originalContent = '# My Project\nNo trailing newline';
126
- const blockContent = 'New content';
127
- const result = insertMergeBlock(originalContent, blockContent);
128
- // Should have separation between original and block
129
- expect(result).toMatch(/No trailing newline\n\n<!-- LUMENFLOW:START -->/);
130
- });
131
- });
132
- describe('updateMergeBlock', () => {
133
- it('should replace existing block content', () => {
134
- const originalContent = `# My Project
135
-
136
- <!-- LUMENFLOW:START -->
137
- Old LumenFlow content.
138
- <!-- LUMENFLOW:END -->
139
-
140
- Other content
141
- `;
142
- const newBlockContent = 'New LumenFlow content.';
143
- const result = updateMergeBlock(originalContent, newBlockContent);
144
- expect(result.content).toContain('New LumenFlow content.');
145
- expect(result.content).not.toContain('Old LumenFlow content.');
146
- expect(result.content).toContain('Other content');
147
- expect(result.updated).toBe(true);
148
- });
149
- it('should preserve content before and after the block', () => {
150
- const originalContent = `# Header
151
-
152
- Before the block.
153
-
154
- <!-- LUMENFLOW:START -->
155
- Old content
156
- <!-- LUMENFLOW:END -->
157
-
158
- After the block.
159
- `;
160
- const newBlockContent = 'Updated content';
161
- const result = updateMergeBlock(originalContent, newBlockContent);
162
- expect(result.content).toContain('# Header');
163
- expect(result.content).toContain('Before the block.');
164
- expect(result.content).toContain('After the block.');
165
- });
166
- it('should preserve original line endings when updating', () => {
167
- const originalContent = `# Project\r\n\r\n<!-- LUMENFLOW:START -->\r\nOld\r\n<!-- LUMENFLOW:END -->\r\n`;
168
- const newBlockContent = 'New';
169
- const result = updateMergeBlock(originalContent, newBlockContent);
170
- // All line endings in result should be CRLF
171
- const lfCount = (result.content.match(/(?<!\r)\n/g) || []).length;
172
- expect(lfCount).toBe(0); // No standalone LF
173
- });
174
- it('should insert block when no existing block (append mode)', () => {
175
- const originalContent = '# Project\n\nNo block here.\n';
176
- const newBlockContent = 'New content';
177
- const result = updateMergeBlock(originalContent, newBlockContent);
178
- expect(result.content).toContain('<!-- LUMENFLOW:START -->');
179
- expect(result.content).toContain(newBlockContent);
180
- expect(result.updated).toBe(true);
181
- expect(result.wasInserted).toBe(true);
182
- });
183
- it('should warn and append fresh block on malformed markers', () => {
184
- const originalContent = `# Project
185
-
186
- <!-- LUMENFLOW:START -->
187
- Incomplete block without end marker
188
- `;
189
- const newBlockContent = 'Fresh content';
190
- const result = updateMergeBlock(originalContent, newBlockContent);
191
- expect(result.warning).toContain('malformed');
192
- expect(result.content).toContain('<!-- LUMENFLOW:START -->');
193
- expect(result.content).toContain('Fresh content');
194
- expect(result.content).toContain('<!-- LUMENFLOW:END -->');
195
- });
196
- });
197
- describe('idempotency', () => {
198
- it('should produce identical output when run twice with same input', () => {
199
- const originalContent = '# My Project\n\nSome content.\n';
200
- const blockContent = 'LumenFlow configuration';
201
- // First merge
202
- const firstResult = updateMergeBlock(originalContent, blockContent);
203
- // Second merge with same block content
204
- const secondResult = updateMergeBlock(firstResult.content, blockContent);
205
- expect(firstResult.content).toBe(secondResult.content);
206
- });
207
- it('should not modify file when block content is unchanged', () => {
208
- const existingContent = `# Project
209
-
210
- <!-- LUMENFLOW:START -->
211
- Same content
212
- <!-- LUMENFLOW:END -->
213
- `;
214
- const blockContent = 'Same content';
215
- const result = updateMergeBlock(existingContent, blockContent);
216
- expect(result.unchanged).toBe(true);
217
- expect(result.content).toBe(existingContent);
218
- });
219
- });
220
- });