edsger 0.2.3 → 0.2.5
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.
- package/README.md +17 -0
- package/dist/api/features/batch-operations.d.ts +16 -0
- package/dist/api/features/batch-operations.js +100 -0
- package/dist/api/features/index.d.ts +1 -0
- package/dist/api/features/index.js +1 -0
- package/dist/api/features/test-cases.d.ts +8 -0
- package/dist/api/features/test-cases.js +45 -0
- package/dist/api/features/user-stories.d.ts +8 -0
- package/dist/api/features/user-stories.js +45 -0
- package/dist/cli/commands/refactor-command.d.ts +2 -0
- package/dist/cli/commands/refactor-command.js +123 -0
- package/dist/cli/formatters/formatter-utils.d.ts +23 -0
- package/dist/cli/formatters/formatter-utils.js +67 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/utils/command-handler.d.ts +23 -0
- package/dist/cli/utils/command-handler.js +39 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +4 -99
- package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
- package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
- package/dist/phases/code-implementation/analyzer.d.ts +2 -0
- package/dist/phases/code-implementation/analyzer.js +304 -175
- package/dist/phases/code-implementation-verification/index.d.ts +1 -0
- package/dist/phases/code-implementation-verification/index.js +1 -0
- package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
- package/dist/phases/code-implementation-verification/verifier.js +196 -0
- package/dist/phases/feature-analysis/analyzer-helpers.d.ts +62 -0
- package/dist/phases/feature-analysis/analyzer-helpers.js +450 -0
- package/dist/phases/feature-analysis/analyzer.d.ts +1 -0
- package/dist/phases/feature-analysis/analyzer.js +132 -219
- package/dist/phases/feature-analysis-verification/index.d.ts +1 -0
- package/dist/phases/feature-analysis-verification/index.js +1 -0
- package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
- package/dist/phases/feature-analysis-verification/verifier.js +147 -0
- package/dist/phases/pull-request/creator.js +2 -1
- package/dist/phases/technical-design/analyzer-helpers.d.ts +37 -0
- package/dist/phases/technical-design/analyzer-helpers.js +144 -0
- package/dist/phases/technical-design/analyzer.d.ts +3 -0
- package/dist/phases/technical-design/analyzer.js +282 -318
- package/dist/phases/technical-design-verification/index.d.ts +1 -0
- package/dist/phases/technical-design-verification/index.js +1 -0
- package/dist/phases/technical-design-verification/verifier.d.ts +36 -0
- package/dist/phases/technical-design-verification/verifier.js +147 -0
- package/dist/prompts/checklist-verification.d.ts +11 -0
- package/dist/prompts/checklist-verification.js +153 -0
- package/dist/prompts/code-implementation-improvement.d.ts +5 -0
- package/dist/prompts/code-implementation-improvement.js +108 -0
- package/dist/prompts/code-implementation-verification.d.ts +3 -0
- package/dist/prompts/code-implementation-verification.js +176 -0
- package/dist/prompts/feature-analysis-improvement.d.ts +8 -0
- package/dist/prompts/feature-analysis-improvement.js +109 -0
- package/dist/prompts/feature-analysis.js +1 -1
- package/dist/prompts/technical-design-improvement.d.ts +5 -0
- package/dist/prompts/technical-design-improvement.js +93 -0
- package/dist/prompts/technical-design-verification.d.ts +11 -0
- package/dist/prompts/technical-design-verification.js +134 -0
- package/dist/prompts/technical-design.js +1 -1
- package/dist/services/audit-logs.d.ts +60 -0
- package/dist/services/audit-logs.js +115 -0
- package/dist/services/checklist.d.ts +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/workflow-runner/executors/phase-executor.js +56 -12
- package/package.json +1 -1
- package/dist/api/features.d.ts +0 -100
- package/dist/api/features.js +0 -219
- package/dist/logger.d.ts +0 -19
- package/dist/logger.js +0 -52
- package/dist/types.d.ts +0 -99
- package/dist/types.js +0 -1
- package/dist/utils/image-processor.d.ts +0 -5
- package/dist/utils/image-processor.js +0 -55
- package/dist/workflow-runner/config/stage-configs.d.ts +0 -5
- package/dist/workflow-runner/config/stage-configs.js +0 -34
- package/dist/workflow-runner/core/feature-filter.test.d.ts +0 -4
- package/dist/workflow-runner/core/feature-filter.test.js +0 -127
- package/dist/workflow-runner/executors/stage-executor.d.ts +0 -8
- package/dist/workflow-runner/executors/stage-executor.js +0 -49
- package/dist/workflow-runner/feature-fetcher.d.ts +0 -41
- package/dist/workflow-runner/feature-fetcher.js +0 -121
- package/dist/workflow-runner/feature-service.d.ts +0 -17
- package/dist/workflow-runner/feature-service.js +0 -60
- package/dist/workflow-runner/pipeline.d.ts +0 -18
- package/dist/workflow-runner/pipeline.js +0 -197
- package/dist/workflow-runner/processor.d.ts +0 -40
- package/dist/workflow-runner/processor.js +0 -191
- package/dist/workflow-runner/status-updater.d.ts +0 -27
- package/dist/workflow-runner/status-updater.js +0 -80
- package/dist/workflow-runner/types.d.ts +0 -48
- package/dist/workflow-runner/types.js +0 -4
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage configurations for the pipeline runner
|
|
3
|
-
*/
|
|
4
|
-
import { analyzeFeatureWithMCP, checkFeatureAnalysisRequirements, } from '../../phases/feature-analysis/analyzer.js';
|
|
5
|
-
import { generateTechnicalDesign, checkTechnicalDesignRequirements, } from '../../phases/technical-design/analyzer.js';
|
|
6
|
-
import { implementFeatureCode, checkCodeImplementationRequirements, } from '../../phases/code-implementation/analyzer.js';
|
|
7
|
-
import { runFunctionalTesting, checkFunctionalTestingRequirements, } from '../../phases/functional-testing/analyzer.js';
|
|
8
|
-
// Pipeline stage configurations
|
|
9
|
-
export const stageConfigs = [
|
|
10
|
-
{
|
|
11
|
-
name: 'feature-analysis',
|
|
12
|
-
checkRequirements: checkFeatureAnalysisRequirements,
|
|
13
|
-
execute: analyzeFeatureWithMCP,
|
|
14
|
-
requirementsError: 'Feature analysis requirements not met. Install with: npm install @anthropic-ai/claude-code zod',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: 'technical-design',
|
|
18
|
-
checkRequirements: checkTechnicalDesignRequirements,
|
|
19
|
-
execute: generateTechnicalDesign,
|
|
20
|
-
requirementsError: 'Technical design requirements not met. Install with: npm install @anthropic-ai/claude-code zod',
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
name: 'code-implementation',
|
|
24
|
-
checkRequirements: checkCodeImplementationRequirements,
|
|
25
|
-
execute: implementFeatureCode,
|
|
26
|
-
requirementsError: 'Code implementation requirements not met. Install with: npm install @anthropic-ai/claude-code zod',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'functional-testing',
|
|
30
|
-
checkRequirements: checkFunctionalTestingRequirements,
|
|
31
|
-
execute: runFunctionalTesting,
|
|
32
|
-
requirementsError: 'Functional testing requirements not met. Install with: npm install @anthropic-ai/claude-code zod',
|
|
33
|
-
},
|
|
34
|
-
];
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for feature filtering with timestamp-based reprocessing
|
|
3
|
-
*/
|
|
4
|
-
import { shouldProcessFeature } from './feature-filter.js';
|
|
5
|
-
describe('shouldProcessFeature with timestamp checking', () => {
|
|
6
|
-
const maxRetries = 3;
|
|
7
|
-
it('should process feature that has never been processed', () => {
|
|
8
|
-
const feature = {
|
|
9
|
-
id: 'feature-1',
|
|
10
|
-
name: 'Test Feature',
|
|
11
|
-
status: 'ready_for_dev',
|
|
12
|
-
product_id: 'product-1',
|
|
13
|
-
updated_at: '2024-01-01T10:00:00Z',
|
|
14
|
-
};
|
|
15
|
-
const states = new Map();
|
|
16
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
17
|
-
expect(result).toBe(true);
|
|
18
|
-
});
|
|
19
|
-
it('should reprocess completed feature if updated after last attempt', () => {
|
|
20
|
-
const feature = {
|
|
21
|
-
id: 'feature-1',
|
|
22
|
-
name: 'Test Feature',
|
|
23
|
-
status: 'ready_for_dev',
|
|
24
|
-
product_id: 'product-1',
|
|
25
|
-
updated_at: '2024-01-01T12:00:00Z', // Updated at noon
|
|
26
|
-
};
|
|
27
|
-
const states = new Map();
|
|
28
|
-
states.set('feature-1', {
|
|
29
|
-
featureId: 'feature-1',
|
|
30
|
-
retryCount: 1,
|
|
31
|
-
lastAttempt: new Date('2024-01-01T10:00:00Z'), // Processed at 10 AM
|
|
32
|
-
status: 'completed',
|
|
33
|
-
});
|
|
34
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
35
|
-
expect(result).toBe(true); // Should reprocess because updated after last attempt
|
|
36
|
-
});
|
|
37
|
-
it('should not reprocess completed feature if not updated after last attempt', () => {
|
|
38
|
-
const feature = {
|
|
39
|
-
id: 'feature-1',
|
|
40
|
-
name: 'Test Feature',
|
|
41
|
-
status: 'ready_for_dev',
|
|
42
|
-
product_id: 'product-1',
|
|
43
|
-
updated_at: '2024-01-01T10:00:00Z', // Updated at 10 AM
|
|
44
|
-
};
|
|
45
|
-
const states = new Map();
|
|
46
|
-
states.set('feature-1', {
|
|
47
|
-
featureId: 'feature-1',
|
|
48
|
-
retryCount: 1,
|
|
49
|
-
lastAttempt: new Date('2024-01-01T12:00:00Z'), // Processed at noon
|
|
50
|
-
status: 'completed',
|
|
51
|
-
});
|
|
52
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
53
|
-
expect(result).toBe(false); // Should not reprocess because not updated after last attempt
|
|
54
|
-
});
|
|
55
|
-
it('should reprocess failed feature if updated after last attempt', () => {
|
|
56
|
-
const feature = {
|
|
57
|
-
id: 'feature-1',
|
|
58
|
-
name: 'Test Feature',
|
|
59
|
-
status: 'ready_for_dev',
|
|
60
|
-
product_id: 'product-1',
|
|
61
|
-
updated_at: '2024-01-01T12:00:00Z', // Updated at noon
|
|
62
|
-
};
|
|
63
|
-
const states = new Map();
|
|
64
|
-
states.set('feature-1', {
|
|
65
|
-
featureId: 'feature-1',
|
|
66
|
-
retryCount: 2,
|
|
67
|
-
lastAttempt: new Date('2024-01-01T10:00:00Z'), // Failed at 10 AM
|
|
68
|
-
status: 'failed',
|
|
69
|
-
});
|
|
70
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
71
|
-
expect(result).toBe(true); // Should reprocess because updated after last attempt
|
|
72
|
-
});
|
|
73
|
-
it('should reprocess failed feature within retry limit even without update', () => {
|
|
74
|
-
const feature = {
|
|
75
|
-
id: 'feature-1',
|
|
76
|
-
name: 'Test Feature',
|
|
77
|
-
status: 'ready_for_dev',
|
|
78
|
-
product_id: 'product-1',
|
|
79
|
-
updated_at: '2024-01-01T09:00:00Z', // Not updated
|
|
80
|
-
};
|
|
81
|
-
const states = new Map();
|
|
82
|
-
states.set('feature-1', {
|
|
83
|
-
featureId: 'feature-1',
|
|
84
|
-
retryCount: 2, // Less than maxRetries (3)
|
|
85
|
-
lastAttempt: new Date('2024-01-01T10:00:00Z'),
|
|
86
|
-
status: 'failed',
|
|
87
|
-
});
|
|
88
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
89
|
-
expect(result).toBe(true); // Should retry because within retry limit
|
|
90
|
-
});
|
|
91
|
-
it('should not reprocess failed feature beyond retry limit without update', () => {
|
|
92
|
-
const feature = {
|
|
93
|
-
id: 'feature-1',
|
|
94
|
-
name: 'Test Feature',
|
|
95
|
-
status: 'ready_for_dev',
|
|
96
|
-
product_id: 'product-1',
|
|
97
|
-
updated_at: '2024-01-01T09:00:00Z', // Not updated
|
|
98
|
-
};
|
|
99
|
-
const states = new Map();
|
|
100
|
-
states.set('feature-1', {
|
|
101
|
-
featureId: 'feature-1',
|
|
102
|
-
retryCount: 3, // Equal to maxRetries
|
|
103
|
-
lastAttempt: new Date('2024-01-01T10:00:00Z'),
|
|
104
|
-
status: 'failed',
|
|
105
|
-
});
|
|
106
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
107
|
-
expect(result).toBe(false); // Should not retry because exceeded retry limit
|
|
108
|
-
});
|
|
109
|
-
it('should handle feature without updated_at timestamp', () => {
|
|
110
|
-
const feature = {
|
|
111
|
-
id: 'feature-1',
|
|
112
|
-
name: 'Test Feature',
|
|
113
|
-
status: 'ready_for_dev',
|
|
114
|
-
product_id: 'product-1',
|
|
115
|
-
// No updated_at field
|
|
116
|
-
};
|
|
117
|
-
const states = new Map();
|
|
118
|
-
states.set('feature-1', {
|
|
119
|
-
featureId: 'feature-1',
|
|
120
|
-
retryCount: 1,
|
|
121
|
-
lastAttempt: new Date('2024-01-01T10:00:00Z'),
|
|
122
|
-
status: 'completed',
|
|
123
|
-
});
|
|
124
|
-
const result = shouldProcessFeature(maxRetries)(feature, states);
|
|
125
|
-
expect(result).toBe(false); // Should not reprocess without timestamp info
|
|
126
|
-
});
|
|
127
|
-
});
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage execution logic for pipeline runner
|
|
3
|
-
*/
|
|
4
|
-
import { EdsgerConfig } from '../../types/index.js';
|
|
5
|
-
import { PipelineStageOptions, PipelineResult, StageConfig } from '../../types/pipeline.js';
|
|
6
|
-
export declare const createStageRunner: (stageConfig: StageConfig) => (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>;
|
|
7
|
-
declare const runFeatureAnalysisStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runTechnicalDesignStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runCodeImplementationStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>, runFunctionalTestingStage: (options: PipelineStageOptions, config: EdsgerConfig) => Promise<PipelineResult>;
|
|
8
|
-
export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stage execution logic for pipeline runner
|
|
3
|
-
*/
|
|
4
|
-
import { updateFeatureStatusForStage } from '../../api/features/index.js';
|
|
5
|
-
import { stageConfigs } from '../config/stage-configs.js';
|
|
6
|
-
// Higher-order function for stage execution
|
|
7
|
-
export const createStageRunner = (stageConfig) => async (options, config) => {
|
|
8
|
-
const { featureId, mcpServerUrl, mcpToken, verbose } = options;
|
|
9
|
-
const { name, checkRequirements, execute, requirementsError } = stageConfig;
|
|
10
|
-
try {
|
|
11
|
-
// Check requirements
|
|
12
|
-
const hasRequirements = await checkRequirements();
|
|
13
|
-
if (!hasRequirements) {
|
|
14
|
-
return {
|
|
15
|
-
featureId,
|
|
16
|
-
stage: name,
|
|
17
|
-
status: 'error',
|
|
18
|
-
message: requirementsError,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
// Update feature status to reflect current stage
|
|
22
|
-
await updateFeatureStatusForStage({ mcpServerUrl, mcpToken }, featureId, name, verbose);
|
|
23
|
-
if (verbose) {
|
|
24
|
-
console.log(`🎯 Starting ${name} for: ${featureId}`);
|
|
25
|
-
}
|
|
26
|
-
const result = await execute(options, config);
|
|
27
|
-
return {
|
|
28
|
-
featureId,
|
|
29
|
-
stage: name,
|
|
30
|
-
status: result.status === 'success' ? 'success' : 'error',
|
|
31
|
-
message: result.status === 'success'
|
|
32
|
-
? `${name.replace('-', ' ')} completed successfully`
|
|
33
|
-
: `${name.replace('-', ' ')} failed`,
|
|
34
|
-
data: result,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
return {
|
|
39
|
-
featureId,
|
|
40
|
-
stage: name,
|
|
41
|
-
status: 'error',
|
|
42
|
-
message: `${name.replace('-', ' ')} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
// Create stage runners using the configuration
|
|
47
|
-
const [runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage,] = stageConfigs.map(createStageRunner);
|
|
48
|
-
// Export individual stage runners for granular control
|
|
49
|
-
export { runFeatureAnalysisStage, runTechnicalDesignStage, runCodeImplementationStage, runFunctionalTestingStage, };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature fetcher module for workflow processing
|
|
3
|
-
* Fetches features with ready_for_dev status and handles product queries via MCP
|
|
4
|
-
* Uses functional programming principles
|
|
5
|
-
*/
|
|
6
|
-
export interface McpClientConfig {
|
|
7
|
-
readonly mcpServerUrl: string;
|
|
8
|
-
readonly mcpToken: string;
|
|
9
|
-
readonly verbose?: boolean;
|
|
10
|
-
}
|
|
11
|
-
export declare const createMcpClient: (config: McpClientConfig) => {
|
|
12
|
-
call: <T>(method: string, params: unknown) => Promise<T>;
|
|
13
|
-
};
|
|
14
|
-
export interface FeatureInfo {
|
|
15
|
-
readonly id: string;
|
|
16
|
-
readonly name: string;
|
|
17
|
-
readonly description: string;
|
|
18
|
-
readonly status: string;
|
|
19
|
-
readonly product_id: string;
|
|
20
|
-
readonly created_at: string;
|
|
21
|
-
readonly updated_at: string;
|
|
22
|
-
}
|
|
23
|
-
export interface FetchFeaturesOptions {
|
|
24
|
-
readonly mcpServerUrl: string;
|
|
25
|
-
readonly mcpToken: string;
|
|
26
|
-
readonly productId: string;
|
|
27
|
-
readonly verbose?: boolean;
|
|
28
|
-
}
|
|
29
|
-
declare const filterFeaturesByStatus: (status: string) => (features: FeatureInfo[]) => FeatureInfo[];
|
|
30
|
-
declare const sortFeaturesByUpdatedAt: (features: FeatureInfo[]) => FeatureInfo[];
|
|
31
|
-
/**
|
|
32
|
-
* Fetch all features with ready_for_dev status for a product, sorted by updated_at
|
|
33
|
-
* Pure functional approach with composition
|
|
34
|
-
*/
|
|
35
|
-
export declare const fetchReadyForDevFeatures: (options: FetchFeaturesOptions) => () => Promise<FeatureInfo[]>;
|
|
36
|
-
/**
|
|
37
|
-
* Get feature details by ID
|
|
38
|
-
* Functional approach with error handling
|
|
39
|
-
*/
|
|
40
|
-
export declare const getFeatureDetails: (featureId: string, options: Omit<FetchFeaturesOptions, "productId">) => () => Promise<FeatureInfo | null>;
|
|
41
|
-
export { filterFeaturesByStatus, sortFeaturesByUpdatedAt };
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature fetcher module for workflow processing
|
|
3
|
-
* Fetches features with ready_for_dev status and handles product queries via MCP
|
|
4
|
-
* Uses functional programming principles
|
|
5
|
-
*/
|
|
6
|
-
// Pure function to create MCP request payload
|
|
7
|
-
const createMcpRequest = (method, params) => ({
|
|
8
|
-
jsonrpc: '2.0',
|
|
9
|
-
method,
|
|
10
|
-
params,
|
|
11
|
-
id: Math.random().toString(36).substring(7),
|
|
12
|
-
});
|
|
13
|
-
// Higher-order function to create MCP client
|
|
14
|
-
export const createMcpClient = (config) => {
|
|
15
|
-
const { mcpServerUrl, mcpToken } = config;
|
|
16
|
-
return {
|
|
17
|
-
call: async (method, params) => {
|
|
18
|
-
const requestBody = createMcpRequest(method, params);
|
|
19
|
-
const response = await fetch(`${mcpServerUrl}/mcp`, {
|
|
20
|
-
method: 'POST',
|
|
21
|
-
headers: {
|
|
22
|
-
'Content-Type': 'application/json',
|
|
23
|
-
Authorization: `Bearer ${mcpToken}`,
|
|
24
|
-
},
|
|
25
|
-
body: JSON.stringify(requestBody),
|
|
26
|
-
});
|
|
27
|
-
if (!response.ok) {
|
|
28
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
29
|
-
}
|
|
30
|
-
const data = await response.json();
|
|
31
|
-
if (data.error) {
|
|
32
|
-
throw new Error(data.error.message || 'MCP call failed');
|
|
33
|
-
}
|
|
34
|
-
return data.result;
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
// Pure function to filter features by status
|
|
39
|
-
const filterFeaturesByStatus = (status) => (features) => features.filter((feature) => feature.status === status);
|
|
40
|
-
// Pure function to sort features by updated_at (most recent first)
|
|
41
|
-
const sortFeaturesByUpdatedAt = (features) => [...features].sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime());
|
|
42
|
-
// Curried logging function
|
|
43
|
-
const logFeatureResults = (verbose) => (features) => {
|
|
44
|
-
if (verbose) {
|
|
45
|
-
console.log(`✅ Found ${features.length} ready_for_dev features`);
|
|
46
|
-
features.forEach((feature, index) => {
|
|
47
|
-
console.log(` ${index + 1}. ${feature.name} (updated: ${feature.updated_at})`);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
return features;
|
|
51
|
-
};
|
|
52
|
-
// Composition helpers
|
|
53
|
-
const pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);
|
|
54
|
-
const tap = (fn) => (value) => {
|
|
55
|
-
fn(value);
|
|
56
|
-
return value;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Fetch all features with ready_for_dev status for a product, sorted by updated_at
|
|
60
|
-
* Pure functional approach with composition
|
|
61
|
-
*/
|
|
62
|
-
export const fetchReadyForDevFeatures = (options) => {
|
|
63
|
-
const { mcpServerUrl, mcpToken, productId, verbose } = options;
|
|
64
|
-
const client = createMcpClient({ mcpServerUrl, mcpToken, verbose });
|
|
65
|
-
const logStart = () => {
|
|
66
|
-
if (verbose) {
|
|
67
|
-
console.log(`📋 Fetching ready_for_dev features for product: ${productId}`);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const logMcpResponse = (result) => {
|
|
71
|
-
if (verbose) {
|
|
72
|
-
console.log(`📊 MCP server response:`, result);
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
};
|
|
76
|
-
const extractFeatures = (result) => result?.features || [];
|
|
77
|
-
const processFeatures = logFeatureResults(verbose || false);
|
|
78
|
-
return async () => {
|
|
79
|
-
try {
|
|
80
|
-
logStart();
|
|
81
|
-
const result = await client.call('features/list', {
|
|
82
|
-
product_id: productId,
|
|
83
|
-
status: 'ready_for_dev',
|
|
84
|
-
});
|
|
85
|
-
const mcpLogged = tap(logMcpResponse)(result);
|
|
86
|
-
const features = extractFeatures(mcpLogged);
|
|
87
|
-
return processFeatures(features);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
console.error(`❌ Error fetching features:`, error);
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* Get feature details by ID
|
|
97
|
-
* Functional approach with error handling
|
|
98
|
-
*/
|
|
99
|
-
export const getFeatureDetails = (featureId, options) => {
|
|
100
|
-
const { mcpServerUrl, mcpToken, verbose } = options;
|
|
101
|
-
const client = createMcpClient({ mcpServerUrl, mcpToken, verbose });
|
|
102
|
-
const logStart = () => {
|
|
103
|
-
if (verbose) {
|
|
104
|
-
console.log(`🔍 Getting details for feature: ${featureId}`);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
const extractFeature = (result) => result?.features?.[0] || null;
|
|
108
|
-
return async () => {
|
|
109
|
-
try {
|
|
110
|
-
logStart();
|
|
111
|
-
const result = await client.call('features/get', { feature_id: featureId });
|
|
112
|
-
return extractFeature(result);
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
console.error(`❌ Error getting feature details:`, error);
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
// Export utility functions for composition
|
|
121
|
-
export { filterFeaturesByStatus, sortFeaturesByUpdatedAt };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature fetching and status management service
|
|
3
|
-
*/
|
|
4
|
-
import { FeatureStatus } from '../types.js';
|
|
5
|
-
import { type FeatureInfo } from '../api/features.js';
|
|
6
|
-
/**
|
|
7
|
-
* Fetch features with ready_for_dev status for a product
|
|
8
|
-
*/
|
|
9
|
-
export declare function fetchReadyForDevFeatures(mcpServerUrl: string, mcpToken: string, productId: string, verbose?: boolean): Promise<FeatureInfo[]>;
|
|
10
|
-
/**
|
|
11
|
-
* Map pipeline stage to feature status
|
|
12
|
-
*/
|
|
13
|
-
export declare function getStatusForStage(stage: string): FeatureStatus;
|
|
14
|
-
/**
|
|
15
|
-
* Update feature status based on pipeline stage
|
|
16
|
-
*/
|
|
17
|
-
export declare function updateFeatureStatusForStage(mcpServerUrl: string, mcpToken: string, featureId: string, stage: string, verbose?: boolean): Promise<boolean>;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature fetching and status management service
|
|
3
|
-
*/
|
|
4
|
-
import { logInfo, logError } from '../logger.js';
|
|
5
|
-
import { updateFeatureStatus, } from '../api/features.js';
|
|
6
|
-
import { callMcpEndpoint } from '../api/mcp-client.js';
|
|
7
|
-
/**
|
|
8
|
-
* Fetch features with ready_for_dev status for a product
|
|
9
|
-
*/
|
|
10
|
-
export async function fetchReadyForDevFeatures(mcpServerUrl, mcpToken, productId, verbose) {
|
|
11
|
-
try {
|
|
12
|
-
if (verbose) {
|
|
13
|
-
logInfo(`📋 Fetching ready_for_dev features for product: ${productId}`);
|
|
14
|
-
}
|
|
15
|
-
const result = (await callMcpEndpoint(mcpServerUrl, mcpToken, 'features/list', {
|
|
16
|
-
product_id: productId,
|
|
17
|
-
status: 'ready_for_dev',
|
|
18
|
-
}));
|
|
19
|
-
const features = result?.features || [];
|
|
20
|
-
if (verbose) {
|
|
21
|
-
logInfo(`✅ Found ${features.length} ready_for_dev features`);
|
|
22
|
-
features.forEach((feature, index) => {
|
|
23
|
-
logInfo(` ${index + 1}. ${feature.name} (${feature.id})`);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return features;
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
logError(`❌ Error fetching features: ${error}`);
|
|
30
|
-
throw error;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Map pipeline stage to feature status
|
|
35
|
-
*/
|
|
36
|
-
export function getStatusForStage(stage) {
|
|
37
|
-
switch (stage) {
|
|
38
|
-
case 'feature-analysis':
|
|
39
|
-
return 'feature_analysis';
|
|
40
|
-
case 'technical-design':
|
|
41
|
-
return 'technical_design';
|
|
42
|
-
case 'code-implementation':
|
|
43
|
-
return 'code_implementation';
|
|
44
|
-
case 'functional-testing':
|
|
45
|
-
return 'testing_in_progress';
|
|
46
|
-
case 'testing-passed':
|
|
47
|
-
return 'testing_passed';
|
|
48
|
-
case 'testing-failed':
|
|
49
|
-
return 'testing_failed';
|
|
50
|
-
default:
|
|
51
|
-
return 'backlog';
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Update feature status based on pipeline stage
|
|
56
|
-
*/
|
|
57
|
-
export async function updateFeatureStatusForStage(mcpServerUrl, mcpToken, featureId, stage, verbose) {
|
|
58
|
-
const status = getStatusForStage(stage);
|
|
59
|
-
return await updateFeatureStatus(mcpServerUrl, mcpToken, featureId, status, verbose);
|
|
60
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pipeline execution logic for feature development workflow
|
|
3
|
-
*/
|
|
4
|
-
import { EdsgerConfig } from '../types.js';
|
|
5
|
-
import { PipelineStageOptions, PipelineResult } from './types.js';
|
|
6
|
-
/**
|
|
7
|
-
* Run the complete pipeline for a feature
|
|
8
|
-
*/
|
|
9
|
-
export declare function runCompletePipeline(options: PipelineStageOptions, config: EdsgerConfig, githubConfig?: {
|
|
10
|
-
githubToken: string;
|
|
11
|
-
githubOwner: string;
|
|
12
|
-
githubRepo: string;
|
|
13
|
-
githubBaseBranch?: string;
|
|
14
|
-
}): Promise<PipelineResult[]>;
|
|
15
|
-
/**
|
|
16
|
-
* Log pipeline results summary
|
|
17
|
-
*/
|
|
18
|
-
export declare function logPipelineResults(results: readonly PipelineResult[]): void;
|