edsger 0.45.0 → 0.45.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 (95) hide show
  1. package/package.json +3 -3
  2. package/tsconfig.build.json +4 -0
  3. package/tsconfig.json +3 -9
  4. package/dist/api/__tests__/app-store.test.d.ts +0 -7
  5. package/dist/api/__tests__/app-store.test.js +0 -60
  6. package/dist/api/__tests__/intelligence.test.d.ts +0 -11
  7. package/dist/api/__tests__/intelligence.test.js +0 -315
  8. package/dist/api/features/__tests__/feature-utils.test.d.ts +0 -4
  9. package/dist/api/features/__tests__/feature-utils.test.js +0 -370
  10. package/dist/api/features/__tests__/status-updater.test.d.ts +0 -4
  11. package/dist/api/features/__tests__/status-updater.test.js +0 -88
  12. package/dist/commands/build/__tests__/build.test.d.ts +0 -5
  13. package/dist/commands/build/__tests__/build.test.js +0 -206
  14. package/dist/commands/build/__tests__/detect-project.test.d.ts +0 -6
  15. package/dist/commands/build/__tests__/detect-project.test.js +0 -160
  16. package/dist/commands/build/__tests__/run-build.test.d.ts +0 -6
  17. package/dist/commands/build/__tests__/run-build.test.js +0 -433
  18. package/dist/commands/intelligence/__tests__/command.test.d.ts +0 -4
  19. package/dist/commands/intelligence/__tests__/command.test.js +0 -48
  20. package/dist/commands/workflow/core/__tests__/feature-filter.test.d.ts +0 -5
  21. package/dist/commands/workflow/core/__tests__/feature-filter.test.js +0 -316
  22. package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.d.ts +0 -4
  23. package/dist/commands/workflow/core/__tests__/pipeline-evaluator.test.js +0 -397
  24. package/dist/commands/workflow/core/__tests__/state-manager.test.d.ts +0 -4
  25. package/dist/commands/workflow/core/__tests__/state-manager.test.js +0 -384
  26. package/dist/config/__tests__/config.test.d.ts +0 -4
  27. package/dist/config/__tests__/config.test.js +0 -286
  28. package/dist/config/__tests__/feature-status.test.d.ts +0 -4
  29. package/dist/config/__tests__/feature-status.test.js +0 -111
  30. package/dist/errors/__tests__/index.test.d.ts +0 -4
  31. package/dist/errors/__tests__/index.test.js +0 -349
  32. package/dist/phases/app-store-generation/__tests__/agent.test.d.ts +0 -5
  33. package/dist/phases/app-store-generation/__tests__/agent.test.js +0 -142
  34. package/dist/phases/app-store-generation/__tests__/context.test.d.ts +0 -4
  35. package/dist/phases/app-store-generation/__tests__/context.test.js +0 -284
  36. package/dist/phases/app-store-generation/__tests__/prompts.test.d.ts +0 -4
  37. package/dist/phases/app-store-generation/__tests__/prompts.test.js +0 -122
  38. package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.d.ts +0 -5
  39. package/dist/phases/app-store-generation/__tests__/screenshot-composer.test.js +0 -826
  40. package/dist/phases/code-review/__tests__/diff-utils.test.d.ts +0 -1
  41. package/dist/phases/code-review/__tests__/diff-utils.test.js +0 -101
  42. package/dist/phases/intelligence-analysis/__tests__/context.test.d.ts +0 -4
  43. package/dist/phases/intelligence-analysis/__tests__/context.test.js +0 -192
  44. package/dist/phases/intelligence-analysis/__tests__/matching.test.d.ts +0 -13
  45. package/dist/phases/intelligence-analysis/__tests__/matching.test.js +0 -154
  46. package/dist/phases/intelligence-analysis/__tests__/orchestration.test.d.ts +0 -5
  47. package/dist/phases/intelligence-analysis/__tests__/orchestration.test.js +0 -378
  48. package/dist/phases/intelligence-analysis/__tests__/prompts.test.d.ts +0 -4
  49. package/dist/phases/intelligence-analysis/__tests__/prompts.test.js +0 -33
  50. package/dist/phases/pr-execution/__tests__/file-assigner.test.d.ts +0 -1
  51. package/dist/phases/pr-execution/__tests__/file-assigner.test.js +0 -303
  52. package/dist/phases/pr-resolve/__tests__/checklist-learner.test.d.ts +0 -1
  53. package/dist/phases/pr-resolve/__tests__/checklist-learner.test.js +0 -157
  54. package/dist/phases/pr-resolve/__tests__/prompts.test.d.ts +0 -1
  55. package/dist/phases/pr-resolve/__tests__/prompts.test.js +0 -116
  56. package/dist/phases/pr-resolve/__tests__/resolve-mapping.test.d.ts +0 -1
  57. package/dist/phases/pr-resolve/__tests__/resolve-mapping.test.js +0 -138
  58. package/dist/phases/pr-resolve/__tests__/types.test.d.ts +0 -1
  59. package/dist/phases/pr-resolve/__tests__/types.test.js +0 -43
  60. package/dist/phases/pr-resolve/__tests__/workspace.test.d.ts +0 -1
  61. package/dist/phases/pr-resolve/__tests__/workspace.test.js +0 -111
  62. package/dist/phases/pr-review/__tests__/prompts.test.d.ts +0 -1
  63. package/dist/phases/pr-review/__tests__/prompts.test.js +0 -49
  64. package/dist/phases/pr-review/__tests__/review-comments.test.d.ts +0 -1
  65. package/dist/phases/pr-review/__tests__/review-comments.test.js +0 -110
  66. package/dist/phases/pr-shared/__tests__/agent-utils.test.d.ts +0 -1
  67. package/dist/phases/pr-shared/__tests__/agent-utils.test.js +0 -91
  68. package/dist/phases/pr-shared/__tests__/context.test.d.ts +0 -1
  69. package/dist/phases/pr-shared/__tests__/context.test.js +0 -94
  70. package/dist/phases/pr-splitting/__tests__/import-dep-validator.test.d.ts +0 -1
  71. package/dist/phases/pr-splitting/__tests__/import-dep-validator.test.js +0 -331
  72. package/dist/phases/release-sync/__tests__/github.test.d.ts +0 -9
  73. package/dist/phases/release-sync/__tests__/github.test.js +0 -123
  74. package/dist/phases/release-sync/__tests__/snapshot.test.d.ts +0 -8
  75. package/dist/phases/release-sync/__tests__/snapshot.test.js +0 -93
  76. package/dist/phases/smoke-test/__tests__/agent.test.d.ts +0 -4
  77. package/dist/phases/smoke-test/__tests__/agent.test.js +0 -85
  78. package/dist/services/coaching/__tests__/coaching-agent.test.d.ts +0 -1
  79. package/dist/services/coaching/__tests__/coaching-agent.test.js +0 -74
  80. package/dist/services/coaching/__tests__/coaching-loop.test.d.ts +0 -1
  81. package/dist/services/coaching/__tests__/coaching-loop.test.js +0 -59
  82. package/dist/services/coaching/__tests__/self-rating.test.d.ts +0 -1
  83. package/dist/services/coaching/__tests__/self-rating.test.js +0 -188
  84. package/dist/services/phase-hooks/__tests__/bindings-fetcher.test.d.ts +0 -1
  85. package/dist/services/phase-hooks/__tests__/bindings-fetcher.test.js +0 -122
  86. package/dist/services/phase-hooks/__tests__/hook-executor.test.d.ts +0 -1
  87. package/dist/services/phase-hooks/__tests__/hook-executor.test.js +0 -321
  88. package/dist/services/phase-hooks/__tests__/hook-runner.test.d.ts +0 -1
  89. package/dist/services/phase-hooks/__tests__/hook-runner.test.js +0 -261
  90. package/dist/services/phase-hooks/__tests__/plugin-loader.test.d.ts +0 -1
  91. package/dist/services/phase-hooks/__tests__/plugin-loader.test.js +0 -158
  92. package/dist/services/video/__tests__/video-pipeline.test.d.ts +0 -6
  93. package/dist/services/video/__tests__/video-pipeline.test.js +0 -249
  94. package/dist/workspace/__tests__/workspace-manager.test.d.ts +0 -7
  95. package/dist/workspace/__tests__/workspace-manager.test.js +0 -52
@@ -1,370 +0,0 @@
1
- /**
2
- * Unit tests for feature utility functions
3
- */
4
- import assert from 'node:assert';
5
- import { describe, it } from 'node:test';
6
- import { filterFeaturesByStatus, sortFeaturesByUpdatedAt, } from '../feature-utils.js';
7
- void describe('Feature Utils', () => {
8
- void describe('sortFeaturesByUpdatedAt', () => {
9
- void it('should sort features by updated_at in ascending order (oldest first)', () => {
10
- const features = [
11
- {
12
- id: '1',
13
- name: 'Feature 1',
14
- status: 'ready_for_ai',
15
- product_id: 'test-product',
16
- updated_at: '2024-01-15T10:00:00Z',
17
- },
18
- {
19
- id: '2',
20
- name: 'Feature 2',
21
- status: 'ready_for_ai',
22
- product_id: 'test-product',
23
- updated_at: '2024-01-10T10:00:00Z',
24
- },
25
- {
26
- id: '3',
27
- name: 'Feature 3',
28
- status: 'ready_for_ai',
29
- product_id: 'test-product',
30
- updated_at: '2024-01-20T10:00:00Z',
31
- },
32
- ];
33
- const sorted = sortFeaturesByUpdatedAt(features);
34
- // Should be sorted oldest first: Feature 2, Feature 1, Feature 3
35
- assert.strictEqual(sorted[0].id, '2', 'First should be Feature 2 (oldest)');
36
- assert.strictEqual(sorted[1].id, '1', 'Second should be Feature 1');
37
- assert.strictEqual(sorted[2].id, '3', 'Third should be Feature 3 (newest)');
38
- });
39
- void it('should handle features with missing updated_at dates', () => {
40
- const features = [
41
- {
42
- id: '1',
43
- name: 'Feature 1',
44
- status: 'ready_for_ai',
45
- product_id: 'test-product',
46
- updated_at: '2024-01-15T10:00:00Z',
47
- },
48
- {
49
- id: '2',
50
- name: 'Feature 2',
51
- status: 'ready_for_ai',
52
- product_id: 'test-product',
53
- // Missing updated_at
54
- },
55
- {
56
- id: '3',
57
- name: 'Feature 3',
58
- status: 'ready_for_ai',
59
- product_id: 'test-product',
60
- updated_at: '2024-01-10T10:00:00Z',
61
- },
62
- ];
63
- const sorted = sortFeaturesByUpdatedAt(features);
64
- // Feature without updated_at should be treated as epoch (1970-01-01)
65
- // and sorted first
66
- assert.strictEqual(sorted[0].id, '2', 'Feature without date should come first');
67
- assert.strictEqual(sorted[1].id, '3', 'Feature 3 should be second (older date)');
68
- assert.strictEqual(sorted[2].id, '1', 'Feature 1 should be third (newer date)');
69
- });
70
- void it('should handle empty array', () => {
71
- const features = [];
72
- const sorted = sortFeaturesByUpdatedAt(features);
73
- assert.strictEqual(sorted.length, 0, 'Empty array should remain empty');
74
- });
75
- void it('should handle single feature', () => {
76
- const features = [
77
- {
78
- id: '1',
79
- name: 'Feature 1',
80
- status: 'ready_for_ai',
81
- product_id: 'test-product',
82
- updated_at: '2024-01-15T10:00:00Z',
83
- },
84
- ];
85
- const sorted = sortFeaturesByUpdatedAt(features);
86
- assert.strictEqual(sorted.length, 1, 'Should return single feature');
87
- assert.strictEqual(sorted[0].id, '1', 'Should be the same feature');
88
- });
89
- void it('should create a new array and not mutate the original', () => {
90
- const features = [
91
- {
92
- id: '1',
93
- name: 'Feature 1',
94
- status: 'ready_for_ai',
95
- product_id: 'test-product',
96
- updated_at: '2024-01-15T10:00:00Z',
97
- },
98
- {
99
- id: '2',
100
- name: 'Feature 2',
101
- status: 'ready_for_ai',
102
- product_id: 'test-product',
103
- updated_at: '2024-01-10T10:00:00Z',
104
- },
105
- ];
106
- const originalOrder = features.map((f) => f.id);
107
- const sorted = sortFeaturesByUpdatedAt(features);
108
- const originalAfterSort = features.map((f) => f.id);
109
- // Original array should be unchanged
110
- assert.deepStrictEqual(originalAfterSort, originalOrder, 'Original array should not be mutated');
111
- // Sorted array should be different
112
- assert.notDeepStrictEqual(sorted.map((f) => f.id), originalOrder, 'Sorted array should have different order');
113
- });
114
- void it('should handle features with same updated_at timestamps consistently', () => {
115
- const sameTimestamp = '2024-01-15T10:00:00Z';
116
- const features = [
117
- {
118
- id: '1',
119
- name: 'Feature 1',
120
- status: 'ready_for_ai',
121
- product_id: 'test-product',
122
- updated_at: sameTimestamp,
123
- },
124
- {
125
- id: '2',
126
- name: 'Feature 2',
127
- status: 'ready_for_ai',
128
- product_id: 'test-product',
129
- updated_at: sameTimestamp,
130
- },
131
- {
132
- id: '3',
133
- name: 'Feature 3',
134
- status: 'ready_for_ai',
135
- product_id: 'test-product',
136
- updated_at: sameTimestamp,
137
- },
138
- ];
139
- const sorted = sortFeaturesByUpdatedAt(features);
140
- assert.strictEqual(sorted.length, 3, 'Should return all features');
141
- // Order should be stable (same as original for equal timestamps)
142
- // Note: JavaScript sort is stable in modern engines
143
- });
144
- void it('should handle various date formats correctly', () => {
145
- const features = [
146
- {
147
- id: '1',
148
- name: 'Feature 1',
149
- status: 'ready_for_ai',
150
- product_id: 'test-product',
151
- updated_at: '2024-01-15', // Date only
152
- },
153
- {
154
- id: '2',
155
- name: 'Feature 2',
156
- status: 'ready_for_ai',
157
- product_id: 'test-product',
158
- updated_at: '2024-01-10T10:00:00.000Z', // Full ISO format
159
- },
160
- {
161
- id: '3',
162
- name: 'Feature 3',
163
- status: 'ready_for_ai',
164
- product_id: 'test-product',
165
- updated_at: '2024-01-20T15:30:00Z', // ISO with time
166
- },
167
- ];
168
- const sorted = sortFeaturesByUpdatedAt(features);
169
- // Should handle different date formats and sort correctly
170
- assert.strictEqual(sorted[0].id, '2', 'Feature 2 should be first (oldest)');
171
- assert.strictEqual(sorted[1].id, '1', 'Feature 1 should be second');
172
- assert.strictEqual(sorted[2].id, '3', 'Feature 3 should be third (newest)');
173
- });
174
- });
175
- void describe('filterFeaturesByStatus', () => {
176
- void it('should filter features by exact status match', () => {
177
- const features = [
178
- {
179
- id: '1',
180
- name: 'Feature 1',
181
- status: 'ready_for_ai',
182
- product_id: 'test-product',
183
- },
184
- {
185
- id: '2',
186
- name: 'Feature 2',
187
- status: 'feature_analysis',
188
- product_id: 'test-product',
189
- },
190
- {
191
- id: '3',
192
- name: 'Feature 3',
193
- status: 'ready_for_ai',
194
- product_id: 'test-product',
195
- },
196
- ];
197
- const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
198
- assert.strictEqual(filtered.length, 2, 'Should return 2 ready_for_ai features');
199
- assert.strictEqual(filtered[0].id, '1', 'Should include Feature 1');
200
- assert.strictEqual(filtered[1].id, '3', 'Should include Feature 3');
201
- });
202
- void it('should return empty array when no features match status', () => {
203
- const features = [
204
- {
205
- id: '1',
206
- name: 'Feature 1',
207
- status: 'feature_analysis',
208
- product_id: 'test-product',
209
- },
210
- {
211
- id: '2',
212
- name: 'Feature 2',
213
- status: 'code_implementation',
214
- product_id: 'test-product',
215
- },
216
- ];
217
- const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
218
- assert.strictEqual(filtered.length, 0, 'Should return empty array');
219
- });
220
- void it('should handle empty input array', () => {
221
- const features = [];
222
- const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
223
- assert.strictEqual(filtered.length, 0, 'Should return empty array');
224
- });
225
- });
226
- void describe('Integration Tests - Workflow Processing Order', () => {
227
- void it('should process features in oldest-first order for workflow execution', () => {
228
- // This test simulates the expected behavior for workflow processing
229
- const simulatedWorkflowFeatures = [
230
- {
231
- id: 'urgent-feature',
232
- name: 'Urgent Feature',
233
- status: 'ready_for_ai',
234
- product_id: 'test-product',
235
- updated_at: '2024-01-01T08:00:00Z', // Very old - should be processed first
236
- },
237
- {
238
- id: 'recent-feature',
239
- name: 'Recent Feature',
240
- status: 'ready_for_ai',
241
- product_id: 'test-product',
242
- updated_at: '2024-01-20T10:00:00Z', // Recent - should be processed last
243
- },
244
- {
245
- id: 'medium-feature',
246
- name: 'Medium Feature',
247
- status: 'ready_for_ai',
248
- product_id: 'test-product',
249
- updated_at: '2024-01-10T12:00:00Z', // Medium age - should be processed second
250
- },
251
- ];
252
- const processingOrder = sortFeaturesByUpdatedAt(simulatedWorkflowFeatures);
253
- // Verify processing order matches expected workflow behavior
254
- assert.strictEqual(processingOrder[0].id, 'urgent-feature', 'Oldest feature should be processed first in workflow');
255
- assert.strictEqual(processingOrder[1].id, 'medium-feature', 'Medium-age feature should be processed second in workflow');
256
- assert.strictEqual(processingOrder[2].id, 'recent-feature', 'Newest feature should be processed last in workflow');
257
- // Verify timestamps are in correct ascending order
258
- const timestamps = processingOrder.map((f) => new Date(f.updated_at || 0).getTime());
259
- for (let i = 1; i < timestamps.length; i++) {
260
- assert.ok(timestamps[i] >= timestamps[i - 1], `Feature ${i} should have timestamp >= feature ${i - 1}`);
261
- }
262
- });
263
- void it('should maintain consistent ordering across multiple calls', () => {
264
- const features = [
265
- {
266
- id: '1',
267
- name: 'Feature 1',
268
- status: 'ready_for_ai',
269
- product_id: 'test-product',
270
- updated_at: '2024-01-15T10:00:00Z',
271
- },
272
- {
273
- id: '2',
274
- name: 'Feature 2',
275
- status: 'ready_for_ai',
276
- product_id: 'test-product',
277
- updated_at: '2024-01-10T10:00:00Z',
278
- },
279
- {
280
- id: '3',
281
- name: 'Feature 3',
282
- status: 'ready_for_ai',
283
- product_id: 'test-product',
284
- updated_at: '2024-01-20T10:00:00Z',
285
- },
286
- ];
287
- // Sort multiple times to ensure consistency
288
- const sorted1 = sortFeaturesByUpdatedAt(features);
289
- const sorted2 = sortFeaturesByUpdatedAt(features);
290
- const sorted3 = sortFeaturesByUpdatedAt(features);
291
- // All should produce the same order
292
- assert.deepStrictEqual(sorted1.map((f) => f.id), sorted2.map((f) => f.id), 'First and second sort should produce same order');
293
- assert.deepStrictEqual(sorted2.map((f) => f.id), sorted3.map((f) => f.id), 'Second and third sort should produce same order');
294
- });
295
- void it('should verify oldest-first ordering is critical for fair workflow processing', () => {
296
- // Test that demonstrates why oldest-first ordering is important
297
- const featuresWithVariousAges = [
298
- {
299
- id: 'very-old-bug',
300
- name: 'Critical Bug Fix',
301
- status: 'ready_for_ai',
302
- product_id: 'test-product',
303
- updated_at: '2024-01-01T00:00:00Z', // Very old, should be highest priority
304
- },
305
- {
306
- id: 'new-enhancement',
307
- name: 'Nice to Have Feature',
308
- status: 'ready_for_ai',
309
- product_id: 'test-product',
310
- updated_at: '2024-01-25T00:00:00Z', // Recent, should be lowest priority
311
- },
312
- {
313
- id: 'medium-priority',
314
- name: 'Important Feature',
315
- status: 'ready_for_ai',
316
- product_id: 'test-product',
317
- updated_at: '2024-01-15T00:00:00Z', // Medium age, should be middle priority
318
- },
319
- ];
320
- const orderedFeatures = sortFeaturesByUpdatedAt(featuresWithVariousAges);
321
- // The oldest feature (potentially a bug that's been waiting) should be processed first
322
- assert.strictEqual(orderedFeatures[0].id, 'very-old-bug');
323
- assert.strictEqual(orderedFeatures[1].id, 'medium-priority');
324
- assert.strictEqual(orderedFeatures[2].id, 'new-enhancement');
325
- // Verify the business logic: older items get processed before newer ones
326
- // This ensures fairness and prevents newer features from always jumping ahead
327
- const ages = orderedFeatures.map((f) => new Date(f.updated_at ?? '').getTime());
328
- assert.ok(ages[0] <= ages[1] && ages[1] <= ages[2], 'Features should be processed in age order (oldest first)');
329
- });
330
- });
331
- void describe('getReadyForAIFeatures integration behavior', () => {
332
- void it('should use sortFeaturesByUpdatedAt to ensure oldest-first processing', () => {
333
- // This test verifies the integration between getReadyForAIFeatures and sortFeaturesByUpdatedAt
334
- // We can test this indirectly by testing the sorting function that getReadyForAIFeatures uses
335
- const mockApiResponse = [
336
- {
337
- id: 'feat-1',
338
- name: 'Feature Added Last Week',
339
- status: 'ready_for_ai',
340
- product_id: 'product-123',
341
- updated_at: '2024-01-18T10:00:00Z',
342
- },
343
- {
344
- id: 'feat-2',
345
- name: 'Feature Added Yesterday',
346
- status: 'ready_for_ai',
347
- product_id: 'product-123',
348
- updated_at: '2024-01-24T15:30:00Z',
349
- },
350
- {
351
- id: 'feat-3',
352
- name: 'Feature Added Last Month',
353
- status: 'ready_for_ai',
354
- product_id: 'product-123',
355
- updated_at: '2024-01-05T08:00:00Z',
356
- },
357
- ];
358
- // This simulates what getReadyForAIFeatures does internally
359
- const sortedForWorkflow = sortFeaturesByUpdatedAt(mockApiResponse);
360
- // Verify oldest-first ordering that getReadyForAIFeatures should provide
361
- assert.strictEqual(sortedForWorkflow[0].id, 'feat-3', 'Oldest feature should be first');
362
- assert.strictEqual(sortedForWorkflow[1].id, 'feat-1', 'Second oldest should be second');
363
- assert.strictEqual(sortedForWorkflow[2].id, 'feat-2', 'Newest feature should be last');
364
- // Verify the function returns the features in the correct order for workflow processing
365
- const expectedOrder = ['feat-3', 'feat-1', 'feat-2'];
366
- const actualOrder = sortedForWorkflow.map((f) => f.id);
367
- assert.deepStrictEqual(actualOrder, expectedOrder, 'Features should be ordered for fair workflow processing');
368
- });
369
- });
370
- });
@@ -1,4 +0,0 @@
1
- /**
2
- * Unit tests for status progression logic
3
- */
4
- export {};
@@ -1,88 +0,0 @@
1
- /**
2
- * Unit tests for status progression logic
3
- */
4
- import assert from 'node:assert';
5
- import { describe, it } from 'node:test';
6
- import { STATUS_PROGRESSION_ORDER } from '../../../config/feature-status.js';
7
- import { isForwardProgression } from '../status-updater.js';
8
- void describe('Status Progression Logic', () => {
9
- void describe('isForwardProgression', () => {
10
- void it('should allow forward progression', () => {
11
- assert.strictEqual(isForwardProgression('backlog', 'ready_for_ai'), true, 'Should allow progression from backlog to ready_for_ai');
12
- assert.strictEqual(isForwardProgression('feature_analysis', 'technical_design'), true, 'Should allow progression from feature_analysis to technical_design');
13
- assert.strictEqual(isForwardProgression('code_implementation', 'shipped'), true, 'Should allow progression from code_implementation to shipped');
14
- });
15
- void it('should allow staying at same status', () => {
16
- assert.strictEqual(isForwardProgression('backlog', 'backlog'), true, 'Should allow staying at backlog status');
17
- assert.strictEqual(isForwardProgression('feature_analysis', 'feature_analysis'), true, 'Should allow staying at feature_analysis status');
18
- assert.strictEqual(isForwardProgression('shipped', 'shipped'), true, 'Should allow staying at shipped status');
19
- });
20
- void it('should prevent backward progression', () => {
21
- assert.strictEqual(isForwardProgression('ready_for_ai', 'backlog'), false, 'Should prevent regression from ready_for_ai to backlog');
22
- assert.strictEqual(isForwardProgression('technical_design', 'feature_analysis'), false, 'Should prevent regression from technical_design to feature_analysis');
23
- assert.strictEqual(isForwardProgression('shipped', 'code_implementation'), false, 'Should prevent regression from shipped to code_implementation');
24
- });
25
- void it('should handle edge cases correctly', () => {
26
- // First status to last status
27
- assert.strictEqual(isForwardProgression('backlog', 'shipped'), true, 'Should allow progression from first to last status');
28
- // Last status to first status
29
- assert.strictEqual(isForwardProgression('shipped', 'backlog'), false, 'Should prevent regression from last to first status');
30
- });
31
- void it('should handle testing workflow correctly', () => {
32
- // Allow progression through testing states
33
- assert.strictEqual(isForwardProgression('functional_testing', 'testing_in_progress'), true, 'Should allow progression to testing_in_progress');
34
- assert.strictEqual(isForwardProgression('testing_in_progress', 'testing_passed'), true, 'Should allow progression to testing_passed');
35
- // Allow retry after failed testing
36
- assert.strictEqual(isForwardProgression('testing_in_progress', 'testing_failed'), true, 'Should allow marking tests as failed');
37
- // Prevent going back to testing_in_progress from passed
38
- assert.strictEqual(isForwardProgression('testing_passed', 'testing_in_progress'), false, 'Should prevent going back from testing_passed to testing_in_progress');
39
- });
40
- });
41
- void describe('STATUS_PROGRESSION_ORDER', () => {
42
- void it('should contain all expected statuses', () => {
43
- const expectedStatuses = [
44
- 'backlog',
45
- 'ready_for_ai',
46
- 'feature_analysis',
47
- 'feature_analysis_verification',
48
- 'technical_design',
49
- 'technical_design_verification',
50
- 'branch_planning',
51
- 'branch_planning_verification',
52
- 'code_implementation',
53
- 'code_implementation_verification',
54
- 'code_refine',
55
- 'code_refine_verification',
56
- 'bug_fixing',
57
- 'code_review',
58
- 'functional_testing',
59
- 'testing_in_progress',
60
- 'testing_passed',
61
- 'testing_failed',
62
- 'ready_for_review',
63
- 'shipped',
64
- ];
65
- assert.strictEqual(STATUS_PROGRESSION_ORDER.length, expectedStatuses.length, 'Should contain the correct number of statuses');
66
- for (const status of expectedStatuses) {
67
- assert.ok(STATUS_PROGRESSION_ORDER.includes(status), `Should include status: ${status}`);
68
- }
69
- });
70
- void it('should have correct ordering for key workflow phases', () => {
71
- const backlogIndex = STATUS_PROGRESSION_ORDER.indexOf('backlog');
72
- const readyForDevIndex = STATUS_PROGRESSION_ORDER.indexOf('ready_for_ai');
73
- const featureAnalysisIndex = STATUS_PROGRESSION_ORDER.indexOf('feature_analysis');
74
- const technicalDesignIndex = STATUS_PROGRESSION_ORDER.indexOf('technical_design');
75
- const codeImplementationIndex = STATUS_PROGRESSION_ORDER.indexOf('code_implementation');
76
- const shippedIndex = STATUS_PROGRESSION_ORDER.indexOf('shipped');
77
- assert.ok(backlogIndex < readyForDevIndex, 'backlog should come before ready_for_ai');
78
- assert.ok(readyForDevIndex < featureAnalysisIndex, 'ready_for_ai should come before feature_analysis');
79
- assert.ok(featureAnalysisIndex < technicalDesignIndex, 'feature_analysis should come before technical_design');
80
- assert.ok(technicalDesignIndex < codeImplementationIndex, 'technical_design should come before code_implementation');
81
- assert.ok(codeImplementationIndex < shippedIndex, 'code_implementation should come before shipped');
82
- });
83
- void it('should not have duplicate statuses', () => {
84
- const uniqueStatuses = new Set(STATUS_PROGRESSION_ORDER);
85
- assert.strictEqual(uniqueStatuses.size, STATUS_PROGRESSION_ORDER.length, 'Should not contain duplicate statuses');
86
- });
87
- });
88
- });
@@ -1,5 +0,0 @@
1
- /**
2
- * Unit tests for the build command's pure/utility functions.
3
- * Tests project discovery, scheme parsing, plist generation, and API key management.
4
- */
5
- export {};