edsger 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,21 +11,21 @@ describe('Feature Utils', () => {
11
11
  {
12
12
  id: '1',
13
13
  name: 'Feature 1',
14
- status: 'ready_for_dev',
14
+ status: 'ready_for_ai',
15
15
  product_id: 'test-product',
16
16
  updated_at: '2024-01-15T10:00:00Z',
17
17
  },
18
18
  {
19
19
  id: '2',
20
20
  name: 'Feature 2',
21
- status: 'ready_for_dev',
21
+ status: 'ready_for_ai',
22
22
  product_id: 'test-product',
23
23
  updated_at: '2024-01-10T10:00:00Z',
24
24
  },
25
25
  {
26
26
  id: '3',
27
27
  name: 'Feature 3',
28
- status: 'ready_for_dev',
28
+ status: 'ready_for_ai',
29
29
  product_id: 'test-product',
30
30
  updated_at: '2024-01-20T10:00:00Z',
31
31
  },
@@ -41,21 +41,21 @@ describe('Feature Utils', () => {
41
41
  {
42
42
  id: '1',
43
43
  name: 'Feature 1',
44
- status: 'ready_for_dev',
44
+ status: 'ready_for_ai',
45
45
  product_id: 'test-product',
46
46
  updated_at: '2024-01-15T10:00:00Z',
47
47
  },
48
48
  {
49
49
  id: '2',
50
50
  name: 'Feature 2',
51
- status: 'ready_for_dev',
51
+ status: 'ready_for_ai',
52
52
  product_id: 'test-product',
53
53
  // Missing updated_at
54
54
  },
55
55
  {
56
56
  id: '3',
57
57
  name: 'Feature 3',
58
- status: 'ready_for_dev',
58
+ status: 'ready_for_ai',
59
59
  product_id: 'test-product',
60
60
  updated_at: '2024-01-10T10:00:00Z',
61
61
  },
@@ -77,7 +77,7 @@ describe('Feature Utils', () => {
77
77
  {
78
78
  id: '1',
79
79
  name: 'Feature 1',
80
- status: 'ready_for_dev',
80
+ status: 'ready_for_ai',
81
81
  product_id: 'test-product',
82
82
  updated_at: '2024-01-15T10:00:00Z',
83
83
  },
@@ -91,14 +91,14 @@ describe('Feature Utils', () => {
91
91
  {
92
92
  id: '1',
93
93
  name: 'Feature 1',
94
- status: 'ready_for_dev',
94
+ status: 'ready_for_ai',
95
95
  product_id: 'test-product',
96
96
  updated_at: '2024-01-15T10:00:00Z',
97
97
  },
98
98
  {
99
99
  id: '2',
100
100
  name: 'Feature 2',
101
- status: 'ready_for_dev',
101
+ status: 'ready_for_ai',
102
102
  product_id: 'test-product',
103
103
  updated_at: '2024-01-10T10:00:00Z',
104
104
  },
@@ -117,21 +117,21 @@ describe('Feature Utils', () => {
117
117
  {
118
118
  id: '1',
119
119
  name: 'Feature 1',
120
- status: 'ready_for_dev',
120
+ status: 'ready_for_ai',
121
121
  product_id: 'test-product',
122
122
  updated_at: sameTimestamp,
123
123
  },
124
124
  {
125
125
  id: '2',
126
126
  name: 'Feature 2',
127
- status: 'ready_for_dev',
127
+ status: 'ready_for_ai',
128
128
  product_id: 'test-product',
129
129
  updated_at: sameTimestamp,
130
130
  },
131
131
  {
132
132
  id: '3',
133
133
  name: 'Feature 3',
134
- status: 'ready_for_dev',
134
+ status: 'ready_for_ai',
135
135
  product_id: 'test-product',
136
136
  updated_at: sameTimestamp,
137
137
  },
@@ -146,21 +146,21 @@ describe('Feature Utils', () => {
146
146
  {
147
147
  id: '1',
148
148
  name: 'Feature 1',
149
- status: 'ready_for_dev',
149
+ status: 'ready_for_ai',
150
150
  product_id: 'test-product',
151
151
  updated_at: '2024-01-15', // Date only
152
152
  },
153
153
  {
154
154
  id: '2',
155
155
  name: 'Feature 2',
156
- status: 'ready_for_dev',
156
+ status: 'ready_for_ai',
157
157
  product_id: 'test-product',
158
158
  updated_at: '2024-01-10T10:00:00.000Z', // Full ISO format
159
159
  },
160
160
  {
161
161
  id: '3',
162
162
  name: 'Feature 3',
163
- status: 'ready_for_dev',
163
+ status: 'ready_for_ai',
164
164
  product_id: 'test-product',
165
165
  updated_at: '2024-01-20T15:30:00Z', // ISO with time
166
166
  },
@@ -178,7 +178,7 @@ describe('Feature Utils', () => {
178
178
  {
179
179
  id: '1',
180
180
  name: 'Feature 1',
181
- status: 'ready_for_dev',
181
+ status: 'ready_for_ai',
182
182
  product_id: 'test-product',
183
183
  },
184
184
  {
@@ -190,12 +190,12 @@ describe('Feature Utils', () => {
190
190
  {
191
191
  id: '3',
192
192
  name: 'Feature 3',
193
- status: 'ready_for_dev',
193
+ status: 'ready_for_ai',
194
194
  product_id: 'test-product',
195
195
  },
196
196
  ];
197
- const filtered = filterFeaturesByStatus(features, 'ready_for_dev');
198
- assert.strictEqual(filtered.length, 2, 'Should return 2 ready_for_dev features');
197
+ const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
198
+ assert.strictEqual(filtered.length, 2, 'Should return 2 ready_for_ai features');
199
199
  assert.strictEqual(filtered[0].id, '1', 'Should include Feature 1');
200
200
  assert.strictEqual(filtered[1].id, '3', 'Should include Feature 3');
201
201
  });
@@ -214,12 +214,12 @@ describe('Feature Utils', () => {
214
214
  product_id: 'test-product',
215
215
  },
216
216
  ];
217
- const filtered = filterFeaturesByStatus(features, 'ready_for_dev');
217
+ const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
218
218
  assert.strictEqual(filtered.length, 0, 'Should return empty array');
219
219
  });
220
220
  it('should handle empty input array', () => {
221
221
  const features = [];
222
- const filtered = filterFeaturesByStatus(features, 'ready_for_dev');
222
+ const filtered = filterFeaturesByStatus(features, 'ready_for_ai');
223
223
  assert.strictEqual(filtered.length, 0, 'Should return empty array');
224
224
  });
225
225
  });
@@ -230,21 +230,21 @@ describe('Feature Utils', () => {
230
230
  {
231
231
  id: 'urgent-feature',
232
232
  name: 'Urgent Feature',
233
- status: 'ready_for_dev',
233
+ status: 'ready_for_ai',
234
234
  product_id: 'test-product',
235
235
  updated_at: '2024-01-01T08:00:00Z', // Very old - should be processed first
236
236
  },
237
237
  {
238
238
  id: 'recent-feature',
239
239
  name: 'Recent Feature',
240
- status: 'ready_for_dev',
240
+ status: 'ready_for_ai',
241
241
  product_id: 'test-product',
242
242
  updated_at: '2024-01-20T10:00:00Z', // Recent - should be processed last
243
243
  },
244
244
  {
245
245
  id: 'medium-feature',
246
246
  name: 'Medium Feature',
247
- status: 'ready_for_dev',
247
+ status: 'ready_for_ai',
248
248
  product_id: 'test-product',
249
249
  updated_at: '2024-01-10T12:00:00Z', // Medium age - should be processed second
250
250
  },
@@ -265,21 +265,21 @@ describe('Feature Utils', () => {
265
265
  {
266
266
  id: '1',
267
267
  name: 'Feature 1',
268
- status: 'ready_for_dev',
268
+ status: 'ready_for_ai',
269
269
  product_id: 'test-product',
270
270
  updated_at: '2024-01-15T10:00:00Z',
271
271
  },
272
272
  {
273
273
  id: '2',
274
274
  name: 'Feature 2',
275
- status: 'ready_for_dev',
275
+ status: 'ready_for_ai',
276
276
  product_id: 'test-product',
277
277
  updated_at: '2024-01-10T10:00:00Z',
278
278
  },
279
279
  {
280
280
  id: '3',
281
281
  name: 'Feature 3',
282
- status: 'ready_for_dev',
282
+ status: 'ready_for_ai',
283
283
  product_id: 'test-product',
284
284
  updated_at: '2024-01-20T10:00:00Z',
285
285
  },
@@ -298,21 +298,21 @@ describe('Feature Utils', () => {
298
298
  {
299
299
  id: 'very-old-bug',
300
300
  name: 'Critical Bug Fix',
301
- status: 'ready_for_dev',
301
+ status: 'ready_for_ai',
302
302
  product_id: 'test-product',
303
303
  updated_at: '2024-01-01T00:00:00Z', // Very old, should be highest priority
304
304
  },
305
305
  {
306
306
  id: 'new-enhancement',
307
307
  name: 'Nice to Have Feature',
308
- status: 'ready_for_dev',
308
+ status: 'ready_for_ai',
309
309
  product_id: 'test-product',
310
310
  updated_at: '2024-01-25T00:00:00Z', // Recent, should be lowest priority
311
311
  },
312
312
  {
313
313
  id: 'medium-priority',
314
314
  name: 'Important Feature',
315
- status: 'ready_for_dev',
315
+ status: 'ready_for_ai',
316
316
  product_id: 'test-product',
317
317
  updated_at: '2024-01-15T00:00:00Z', // Medium age, should be middle priority
318
318
  },
@@ -328,36 +328,36 @@ describe('Feature Utils', () => {
328
328
  assert.ok(ages[0] <= ages[1] && ages[1] <= ages[2], 'Features should be processed in age order (oldest first)');
329
329
  });
330
330
  });
331
- describe('getReadyForDevFeatures integration behavior', () => {
331
+ describe('getReadyForAIFeatures integration behavior', () => {
332
332
  it('should use sortFeaturesByUpdatedAt to ensure oldest-first processing', () => {
333
- // This test verifies the integration between getReadyForDevFeatures and sortFeaturesByUpdatedAt
334
- // We can test this indirectly by testing the sorting function that getReadyForDevFeatures uses
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
335
  const mockApiResponse = [
336
336
  {
337
337
  id: 'feat-1',
338
338
  name: 'Feature Added Last Week',
339
- status: 'ready_for_dev',
339
+ status: 'ready_for_ai',
340
340
  product_id: 'product-123',
341
341
  updated_at: '2024-01-18T10:00:00Z',
342
342
  },
343
343
  {
344
344
  id: 'feat-2',
345
345
  name: 'Feature Added Yesterday',
346
- status: 'ready_for_dev',
346
+ status: 'ready_for_ai',
347
347
  product_id: 'product-123',
348
348
  updated_at: '2024-01-24T15:30:00Z',
349
349
  },
350
350
  {
351
351
  id: 'feat-3',
352
352
  name: 'Feature Added Last Month',
353
- status: 'ready_for_dev',
353
+ status: 'ready_for_ai',
354
354
  product_id: 'product-123',
355
355
  updated_at: '2024-01-05T08:00:00Z',
356
356
  },
357
357
  ];
358
- // This simulates what getReadyForDevFeatures does internally
358
+ // This simulates what getReadyForAIFeatures does internally
359
359
  const sortedForWorkflow = sortFeaturesByUpdatedAt(mockApiResponse);
360
- // Verify oldest-first ordering that getReadyForDevFeatures should provide
360
+ // Verify oldest-first ordering that getReadyForAIFeatures should provide
361
361
  assert.strictEqual(sortedForWorkflow[0].id, 'feat-3', 'Oldest feature should be first');
362
362
  assert.strictEqual(sortedForWorkflow[1].id, 'feat-1', 'Second oldest should be second');
363
363
  assert.strictEqual(sortedForWorkflow[2].id, 'feat-2', 'Newest feature should be last');
@@ -8,7 +8,7 @@ import { isForwardProgression } from '../status-updater.js';
8
8
  describe('Status Progression Logic', () => {
9
9
  describe('isForwardProgression', () => {
10
10
  it('should allow forward progression', () => {
11
- assert.strictEqual(isForwardProgression('backlog', 'ready_for_dev'), true, 'Should allow progression from backlog to ready_for_dev');
11
+ assert.strictEqual(isForwardProgression('backlog', 'ready_for_ai'), true, 'Should allow progression from backlog to ready_for_ai');
12
12
  assert.strictEqual(isForwardProgression('feature_analysis', 'technical_design'), true, 'Should allow progression from feature_analysis to technical_design');
13
13
  assert.strictEqual(isForwardProgression('code_implementation', 'shipped'), true, 'Should allow progression from code_implementation to shipped');
14
14
  });
@@ -18,7 +18,7 @@ describe('Status Progression Logic', () => {
18
18
  assert.strictEqual(isForwardProgression('shipped', 'shipped'), true, 'Should allow staying at shipped status');
19
19
  });
20
20
  it('should prevent backward progression', () => {
21
- assert.strictEqual(isForwardProgression('ready_for_dev', 'backlog'), false, 'Should prevent regression from ready_for_dev to backlog');
21
+ assert.strictEqual(isForwardProgression('ready_for_ai', 'backlog'), false, 'Should prevent regression from ready_for_ai to backlog');
22
22
  assert.strictEqual(isForwardProgression('technical_design', 'feature_analysis'), false, 'Should prevent regression from technical_design to feature_analysis');
23
23
  assert.strictEqual(isForwardProgression('shipped', 'code_implementation'), false, 'Should prevent regression from shipped to code_implementation');
24
24
  });
@@ -42,7 +42,7 @@ describe('Status Progression Logic', () => {
42
42
  it('should contain all expected statuses', () => {
43
43
  const expectedStatuses = [
44
44
  'backlog',
45
- 'ready_for_dev',
45
+ 'ready_for_ai',
46
46
  'feature_analysis',
47
47
  'feature_analysis_verification',
48
48
  'technical_design',
@@ -68,13 +68,13 @@ describe('Status Progression Logic', () => {
68
68
  });
69
69
  it('should have correct ordering for key workflow phases', () => {
70
70
  const backlogIndex = STATUS_PROGRESSION_ORDER.indexOf('backlog');
71
- const readyForDevIndex = STATUS_PROGRESSION_ORDER.indexOf('ready_for_dev');
71
+ const readyForDevIndex = STATUS_PROGRESSION_ORDER.indexOf('ready_for_ai');
72
72
  const featureAnalysisIndex = STATUS_PROGRESSION_ORDER.indexOf('feature_analysis');
73
73
  const technicalDesignIndex = STATUS_PROGRESSION_ORDER.indexOf('technical_design');
74
74
  const codeImplementationIndex = STATUS_PROGRESSION_ORDER.indexOf('code_implementation');
75
75
  const shippedIndex = STATUS_PROGRESSION_ORDER.indexOf('shipped');
76
- assert.ok(backlogIndex < readyForDevIndex, 'backlog should come before ready_for_dev');
77
- assert.ok(readyForDevIndex < featureAnalysisIndex, 'ready_for_dev should come before feature_analysis');
76
+ assert.ok(backlogIndex < readyForDevIndex, 'backlog should come before ready_for_ai');
77
+ assert.ok(readyForDevIndex < featureAnalysisIndex, 'ready_for_ai should come before feature_analysis');
78
78
  assert.ok(featureAnalysisIndex < technicalDesignIndex, 'feature_analysis should come before technical_design');
79
79
  assert.ok(technicalDesignIndex < codeImplementationIndex, 'technical_design should come before code_implementation');
80
80
  assert.ok(codeImplementationIndex < shippedIndex, 'code_implementation should come before shipped');
@@ -8,6 +8,6 @@ export declare function filterFeaturesByStatus(features: FeatureInfo[], status:
8
8
  */
9
9
  export declare function sortFeaturesByUpdatedAt(features: FeatureInfo[]): FeatureInfo[];
10
10
  /**
11
- * Get features with ready_for_dev status for a product
11
+ * Get features with ready_for_ai status for a product
12
12
  */
13
- export declare function getReadyForDevFeatures(productId: string, verbose?: boolean): Promise<FeatureInfo[]>;
13
+ export declare function getReadyForAIFeatures(productId: string, verbose?: boolean): Promise<FeatureInfo[]>;
@@ -17,21 +17,21 @@ export function sortFeaturesByUpdatedAt(features) {
17
17
  });
18
18
  }
19
19
  /**
20
- * Get features with ready_for_dev status for a product
20
+ * Get features with ready_for_ai status for a product
21
21
  */
22
- export async function getReadyForDevFeatures(productId, verbose) {
22
+ export async function getReadyForAIFeatures(productId, verbose) {
23
23
  if (verbose) {
24
- logInfo(`Fetching ready_for_dev features for product: ${productId}`);
24
+ logInfo(`Fetching ready_for_ai features for product: ${productId}`);
25
25
  }
26
26
  try {
27
27
  const result = (await callMcpEndpoint('features/list', {
28
28
  product_id: productId,
29
- status: 'ready_for_dev',
29
+ status: 'ready_for_ai',
30
30
  }));
31
31
  const features = result.features || [];
32
32
  const sortedFeatures = sortFeaturesByUpdatedAt(features);
33
33
  if (verbose) {
34
- logInfo(`✅ Found ${sortedFeatures.length} ready_for_dev features (oldest first)`);
34
+ logInfo(`✅ Found ${sortedFeatures.length} ready_for_ai features (oldest first)`);
35
35
  sortedFeatures.forEach((feature, index) => {
36
36
  logInfo(` ${index + 1}. ${feature.name} (updated: ${feature.updated_at})`);
37
37
  });
@@ -40,7 +40,7 @@ export async function getReadyForDevFeatures(productId, verbose) {
40
40
  }
41
41
  catch (error) {
42
42
  const errorMessage = error instanceof Error ? error.message : String(error);
43
- logError(`Failed to fetch ready_for_dev features: ${errorMessage}`);
43
+ logError(`Failed to fetch ready_for_ai features: ${errorMessage}`);
44
44
  throw error;
45
45
  }
46
46
  }
@@ -9,7 +9,7 @@ export const shouldProcessFeature = (maxRetries) => (feature, states) => {
9
9
  if (!state)
10
10
  return true;
11
11
  // If feature was updated after last processing attempt, should reprocess
12
- // This handles cases where user manually changes status back to ready_for_dev
12
+ // This handles cases where user manually changes status back to ready_for_ai
13
13
  if (feature.updated_at) {
14
14
  const featureUpdatedTime = new Date(feature.updated_at).getTime();
15
15
  const lastAttemptTime = state.lastAttempt.getTime();
@@ -49,7 +49,7 @@ export const logFeatureError = (featureName, error) => {
49
49
  logError(`❌ Error processing feature ${featureName}: ${error instanceof Error ? error.message : String(error)}`);
50
50
  };
51
51
  export const logNoFeaturesFound = () => {
52
- logInfo('🔍 No ready_for_dev features found, continuing to monitor...');
52
+ logInfo('🔍 No ready_for_ai features found, continuing to monitor...');
53
53
  };
54
54
  export const logAllFeaturesProcessed = () => {
55
55
  logInfo('🔄 All current features are processed or being processed, continuing to monitor...');
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Main workflow processor for continuous feature development
3
- * Monitors for ready_for_dev features and processes them through the complete pipeline
3
+ * Monitors for ready_for_ai features and processes them through the complete pipeline
4
4
  * Uses functional programming principles
5
5
  */
6
6
  import { EdsgerConfig } from '../../types/index.js';
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Main workflow processor for continuous feature development
3
- * Monitors for ready_for_dev features and processes them through the complete pipeline
3
+ * Monitors for ready_for_ai features and processes them through the complete pipeline
4
4
  * Uses functional programming principles
5
5
  */
6
- import { getReadyForDevFeatures } from '../../api/features/index.js';
6
+ import { getReadyForAIFeatures } from '../../api/features/index.js';
7
7
  import { runFeatureWorkflow } from './feature-coordinator.js';
8
8
  import { logInfo } from '../../utils/logger.js';
9
9
  // Import core modules
@@ -77,7 +77,7 @@ export class WorkflowProcessor {
77
77
  return;
78
78
  }
79
79
  // Fetch features using unified API
80
- const features = await getReadyForDevFeatures(this.options.productId, this.options.verbose);
80
+ const features = await getReadyForAIFeatures(this.options.productId, this.options.verbose);
81
81
  if (features.length === 0) {
82
82
  if (this.options.verbose) {
83
83
  logNoFeaturesFound();
@@ -19,7 +19,7 @@ describe('Feature Status Configuration', () => {
19
19
  it('should maintain logical workflow order', () => {
20
20
  const criticalOrder = [
21
21
  'backlog',
22
- 'ready_for_dev',
22
+ 'ready_for_ai',
23
23
  'feature_analysis',
24
24
  'technical_design',
25
25
  'code_implementation',
@@ -22,7 +22,7 @@
22
22
  */
23
23
  export const STATUS_PROGRESSION_ORDER = [
24
24
  'backlog',
25
- 'ready_for_dev',
25
+ 'ready_for_ai',
26
26
  'feature_analysis',
27
27
  'feature_analysis_verification',
28
28
  'technical_design',
@@ -130,4 +130,4 @@ export interface FeatureAnalysisDisplayResult {
130
130
  createdUserStories?: DisplayUserStory[];
131
131
  createdTestCases?: DisplayTestCase[];
132
132
  }
133
- export type FeatureStatus = 'backlog' | 'ready_for_dev' | 'feature_analysis' | 'feature_analysis_verification' | 'technical_design' | 'technical_design_verification' | 'code_implementation' | 'code_implementation_verification' | 'code_refine' | 'code_refine_verification' | 'bug_fixing' | 'code_review' | 'pull_request' | 'functional_testing' | 'ready_for_review' | 'shipped' | 'testing_in_progress' | 'testing_passed' | 'testing_failed';
133
+ export type FeatureStatus = 'backlog' | 'ready_for_ai' | 'feature_analysis' | 'feature_analysis_verification' | 'technical_design' | 'technical_design_verification' | 'code_implementation' | 'code_implementation_verification' | 'code_refine' | 'code_refine_verification' | 'bug_fixing' | 'code_review' | 'pull_request' | 'functional_testing' | 'ready_for_review' | 'shipped' | 'testing_in_progress' | 'testing_passed' | 'testing_failed';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edsger",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "edsger": "dist/index.js"