edsger 0.2.0 → 0.2.2
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/dist/api/features/feature-utils.d.ts +13 -0
- package/dist/api/features/feature-utils.js +46 -0
- package/dist/api/features/get-feature.d.ts +5 -0
- package/dist/api/features/get-feature.js +19 -0
- package/dist/api/features/index.d.ts +7 -0
- package/dist/api/features/index.js +9 -0
- package/dist/api/features/status-updater.d.ts +27 -0
- package/dist/api/features/status-updater.js +64 -0
- package/dist/api/features/test-cases.d.ts +21 -0
- package/dist/api/features/test-cases.js +63 -0
- package/dist/api/features/update-feature.d.ts +13 -0
- package/dist/api/features/update-feature.js +31 -0
- package/dist/api/features/user-stories.d.ts +21 -0
- package/dist/api/features/user-stories.js +63 -0
- package/dist/api/features.d.ts +100 -0
- package/dist/api/features.js +219 -0
- package/dist/api/mcp-client.d.ts +18 -0
- package/dist/api/mcp-client.js +58 -0
- package/dist/api/products.d.ts +10 -0
- package/dist/api/products.js +22 -0
- package/dist/api/test-reports.d.ts +9 -0
- package/dist/api/test-reports.js +25 -0
- package/dist/cli/commands/code-implementation-command.d.ts +2 -0
- package/dist/cli/commands/code-implementation-command.js +36 -0
- package/dist/cli/commands/code-review-command.d.ts +2 -0
- package/dist/cli/commands/code-review-command.js +39 -0
- package/dist/cli/commands/feature-analysis-command.d.ts +2 -0
- package/dist/cli/commands/feature-analysis-command.js +36 -0
- package/dist/cli/commands/functional-testing-command.d.ts +2 -0
- package/dist/cli/commands/functional-testing-command.js +36 -0
- package/dist/cli/commands/technical-design-command.d.ts +2 -0
- package/dist/cli/commands/technical-design-command.js +36 -0
- package/dist/cli/commands/workflow-command.d.ts +2 -0
- package/dist/cli/commands/workflow-command.js +34 -0
- package/dist/cli/formatters/code-implementation-formatter.d.ts +9 -0
- package/dist/cli/formatters/code-implementation-formatter.js +27 -0
- package/dist/cli/formatters/feature-analysis-formatter.d.ts +2 -0
- package/dist/cli/formatters/feature-analysis-formatter.js +27 -0
- package/dist/cli/formatters/functional-testing-formatter.d.ts +15 -0
- package/dist/cli/formatters/functional-testing-formatter.js +37 -0
- package/dist/cli/formatters/technical-design-formatter.d.ts +7 -0
- package/dist/cli/formatters/technical-design-formatter.js +30 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/utils/validation.d.ts +25 -0
- package/dist/cli/utils/validation.js +58 -0
- package/dist/cli/utils/workflow-utils.d.ts +21 -0
- package/dist/cli/utils/workflow-utils.js +47 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +11 -466
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.d.ts +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/analyzer.js +1 -1
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.d.ts +4 -22
- package/dist/{bug-fixing → phases/bug-fixing}/context-fetcher.js +14 -58
- package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.js +1 -30
- package/dist/phases/code-implementation/analyzer.d.ts +33 -0
- package/dist/{code-implementation → phases/code-implementation}/analyzer.js +174 -15
- package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
- package/dist/phases/code-implementation/context-fetcher.js +86 -0
- package/dist/{code-implementation → phases/code-implementation}/mcp-server.js +1 -30
- package/dist/{code-review → phases/code-review}/reviewer.d.ts +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.d.ts +3 -2
- package/dist/{feature-analysis → phases/feature-analysis}/analyzer.js +29 -127
- package/dist/phases/feature-analysis/context-fetcher.d.ts +18 -0
- package/dist/phases/feature-analysis/context-fetcher.js +86 -0
- package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.js +1 -1
- package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.js +1 -24
- package/dist/{functional-testing → phases/functional-testing}/analyzer.d.ts +17 -2
- package/dist/{functional-testing → phases/functional-testing}/analyzer.js +225 -31
- package/dist/phases/functional-testing/context-fetcher.d.ts +16 -0
- package/dist/phases/functional-testing/context-fetcher.js +81 -0
- package/dist/{functional-testing → phases/functional-testing}/http-fallback.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.d.ts +1 -1
- package/dist/{functional-testing → phases/functional-testing}/index.js +1 -1
- package/dist/{functional-testing → phases/functional-testing}/mcp-server.js +1 -30
- package/dist/{functional-testing → phases/functional-testing}/test-report-creator.d.ts +26 -0
- package/dist/{functional-testing → phases/functional-testing}/test-report-creator.js +87 -5
- package/dist/phases/functional-testing/test-retry-handler.d.ts +16 -0
- package/dist/phases/functional-testing/test-retry-handler.js +75 -0
- package/dist/{pull-request → phases/pull-request}/creator.js +47 -6
- package/dist/phases/pull-request/handler.d.ts +16 -0
- package/dist/phases/pull-request/handler.js +60 -0
- package/dist/{technical-design → phases/technical-design}/analyzer.d.ts +7 -2
- package/dist/phases/technical-design/analyzer.js +418 -0
- package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
- package/dist/phases/technical-design/context-fetcher.js +39 -0
- package/dist/{technical-design → phases/technical-design}/http-fallback.js +1 -1
- package/dist/{technical-design → phases/technical-design}/mcp-server.js +1 -30
- package/dist/prompts/bug-fixing.d.ts +2 -0
- package/dist/prompts/bug-fixing.js +63 -0
- package/dist/prompts/code-implementation.d.ts +3 -0
- package/dist/prompts/code-implementation.js +132 -0
- package/dist/prompts/feature-analysis.d.ts +3 -0
- package/dist/prompts/feature-analysis.js +149 -0
- package/dist/prompts/formatters.d.ts +29 -0
- package/dist/prompts/formatters.js +139 -0
- package/dist/prompts/functional-testing.d.ts +3 -0
- package/dist/prompts/functional-testing.js +126 -0
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.js +7 -0
- package/dist/prompts/technical-design.d.ts +3 -0
- package/dist/prompts/technical-design.js +130 -0
- package/dist/services/checklist.d.ts +99 -0
- package/dist/services/checklist.js +337 -0
- package/dist/types/features.d.ts +29 -0
- package/dist/types/features.js +1 -0
- package/dist/types/index.d.ts +112 -0
- package/dist/types/index.js +1 -0
- package/dist/types/pipeline.d.ts +25 -0
- package/dist/types/pipeline.js +4 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/pipeline-logger.d.ts +8 -0
- package/dist/utils/pipeline-logger.js +35 -0
- package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
- package/dist/workflow-runner/config/phase-configs.js +34 -0
- package/dist/workflow-runner/config/stage-configs.d.ts +5 -0
- package/dist/workflow-runner/config/stage-configs.js +34 -0
- package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
- package/dist/workflow-runner/core/feature-filter.js +46 -0
- package/dist/workflow-runner/core/feature-filter.test.d.ts +4 -0
- package/dist/workflow-runner/core/feature-filter.test.js +127 -0
- package/dist/workflow-runner/core/index.d.ts +8 -0
- package/dist/workflow-runner/core/index.js +12 -0
- package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
- package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
- package/dist/workflow-runner/core/state-manager.d.ts +24 -0
- package/dist/workflow-runner/core/state-manager.js +42 -0
- package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
- package/dist/workflow-runner/core/workflow-logger.js +65 -0
- package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/phase-executor.js +183 -0
- package/dist/workflow-runner/executors/stage-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/stage-executor.js +49 -0
- package/dist/workflow-runner/feature-service.d.ts +17 -0
- package/dist/workflow-runner/feature-service.js +60 -0
- package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
- package/dist/workflow-runner/feature-workflow-runner.js +113 -0
- package/dist/workflow-runner/index.d.ts +0 -1
- package/dist/workflow-runner/index.js +0 -1
- package/dist/workflow-runner/pipeline-runner.d.ts +9 -19
- package/dist/workflow-runner/pipeline-runner.js +247 -256
- package/dist/workflow-runner/pipeline.d.ts +18 -0
- package/dist/workflow-runner/pipeline.js +197 -0
- package/dist/workflow-runner/processor.d.ts +40 -0
- package/dist/workflow-runner/processor.js +191 -0
- package/dist/workflow-runner/types.d.ts +48 -0
- package/dist/workflow-runner/types.js +4 -0
- package/dist/workflow-runner/workflow-processor.d.ts +6 -23
- package/dist/workflow-runner/workflow-processor.js +38 -100
- package/package.json +2 -2
- package/dist/code-implementation/analyzer.d.ts +0 -19
- package/dist/code-implementation/context-fetcher.d.ts +0 -38
- package/dist/code-implementation/context-fetcher.js +0 -147
- package/dist/feature-analysis/context-fetcher.d.ts +0 -54
- package/dist/feature-analysis/context-fetcher.js +0 -193
- package/dist/functional-testing/context-fetcher.d.ts +0 -47
- package/dist/functional-testing/context-fetcher.js +0 -192
- package/dist/technical-design/analyzer.js +0 -338
- package/dist/technical-design/context-fetcher.d.ts +0 -42
- package/dist/technical-design/context-fetcher.js +0 -170
- /package/dist/{bug-fixing → phases/bug-fixing}/index.d.ts +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/index.js +0 -0
- /package/dist/{bug-fixing → phases/bug-fixing}/mcp-server.d.ts +0 -0
- /package/dist/{code-implementation → phases/code-implementation}/mcp-server.d.ts +0 -0
- /package/dist/{code-review → phases/code-review}/reviewer.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/http-fallback.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.d.ts +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/index.js +0 -0
- /package/dist/{feature-analysis → phases/feature-analysis}/mcp-server.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/http-fallback.d.ts +0 -0
- /package/dist/{functional-testing → phases/functional-testing}/mcp-server.d.ts +0 -0
- /package/dist/{pull-request → phases/pull-request}/creator.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/http-fallback.d.ts +0 -0
- /package/dist/{technical-design → phases/technical-design}/mcp-server.d.ts +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export interface EdsgerConfig {
|
|
2
|
+
patterns: string[];
|
|
3
|
+
exclude: string[];
|
|
4
|
+
severity: 'error' | 'warning';
|
|
5
|
+
maxFiles: number;
|
|
6
|
+
claude: {
|
|
7
|
+
model?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface GitFile {
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
status: 'modified' | 'added' | 'deleted' | 'renamed';
|
|
15
|
+
}
|
|
16
|
+
export interface ReviewResult {
|
|
17
|
+
file: string;
|
|
18
|
+
status: 'OK' | 'WARN' | 'BLOCK';
|
|
19
|
+
message: string;
|
|
20
|
+
details?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CliOptions {
|
|
23
|
+
review?: boolean;
|
|
24
|
+
staged?: boolean;
|
|
25
|
+
files?: string[];
|
|
26
|
+
config?: string;
|
|
27
|
+
verbose?: boolean;
|
|
28
|
+
featureAnalysis?: string;
|
|
29
|
+
technicalDesign?: string;
|
|
30
|
+
implement?: string;
|
|
31
|
+
test?: string;
|
|
32
|
+
workflow?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export type ReviewSeverity = 'error' | 'warning';
|
|
35
|
+
export type ExitCode = 0 | 1;
|
|
36
|
+
export interface FeatureAnalysisResult {
|
|
37
|
+
featureId: string;
|
|
38
|
+
productInfo: unknown;
|
|
39
|
+
featureInfo: unknown;
|
|
40
|
+
existingUserStories: UserStory[];
|
|
41
|
+
existingTestCases: TestCase[];
|
|
42
|
+
createdUserStories: UserStory[];
|
|
43
|
+
createdTestCases: TestCase[];
|
|
44
|
+
summary: string;
|
|
45
|
+
status: 'pending' | 'success' | 'error';
|
|
46
|
+
data?: {
|
|
47
|
+
checklist_results?: Array<{
|
|
48
|
+
checklist_id: string;
|
|
49
|
+
satisfied: boolean;
|
|
50
|
+
notes?: string;
|
|
51
|
+
}>;
|
|
52
|
+
checklist_item_results?: Array<{
|
|
53
|
+
checklist_item_id: string;
|
|
54
|
+
is_passed: boolean;
|
|
55
|
+
value?: any;
|
|
56
|
+
notes?: string;
|
|
57
|
+
}>;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface FeatureData {
|
|
61
|
+
feature: {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
description: string;
|
|
65
|
+
status: string;
|
|
66
|
+
product_id: string;
|
|
67
|
+
created_at: string;
|
|
68
|
+
updated_at: string;
|
|
69
|
+
};
|
|
70
|
+
product: {
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
description: string;
|
|
74
|
+
status: string;
|
|
75
|
+
features: unknown[];
|
|
76
|
+
metadata: {
|
|
77
|
+
created_at: string;
|
|
78
|
+
updated_at: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export interface UserStory {
|
|
83
|
+
id: string;
|
|
84
|
+
title: string;
|
|
85
|
+
description: string;
|
|
86
|
+
status: 'draft' | 'ready' | 'in_progress' | 'done' | 'cancelled';
|
|
87
|
+
created_at: string;
|
|
88
|
+
updated_at: string;
|
|
89
|
+
}
|
|
90
|
+
export interface TestCase {
|
|
91
|
+
id: string;
|
|
92
|
+
name: string;
|
|
93
|
+
description: string;
|
|
94
|
+
is_critical: boolean;
|
|
95
|
+
created_at: string;
|
|
96
|
+
updated_at: string;
|
|
97
|
+
}
|
|
98
|
+
export interface DisplayUserStory {
|
|
99
|
+
title: string;
|
|
100
|
+
}
|
|
101
|
+
export interface DisplayTestCase {
|
|
102
|
+
name: string;
|
|
103
|
+
is_critical?: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface FeatureAnalysisDisplayResult {
|
|
106
|
+
featureId: string;
|
|
107
|
+
status: string;
|
|
108
|
+
summary?: string;
|
|
109
|
+
createdUserStories?: DisplayUserStory[];
|
|
110
|
+
createdTestCases?: DisplayTestCase[];
|
|
111
|
+
}
|
|
112
|
+
export type FeatureStatus = 'backlog' | 'ready_for_dev' | 'feature_analysis' | 'technical_design' | 'code_implementation' | 'code_review' | 'ready_for_review' | 'shipped' | 'testing_in_progress' | 'testing_passed' | 'testing_failed';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { EdsgerConfig } from './index.js';
|
|
5
|
+
import { ChecklistPhaseContext } from '../services/checklist.js';
|
|
6
|
+
export type ExecutionMode = 'full_pipeline' | 'only_feature_analysis' | 'only_technical_design' | 'only_code_implementation' | 'only_functional_testing' | 'from_feature_analysis' | 'from_technical_design' | 'from_code_implementation' | 'from_functional_testing';
|
|
7
|
+
export interface PipelinePhaseOptions {
|
|
8
|
+
readonly featureId: string;
|
|
9
|
+
readonly mcpServerUrl: string;
|
|
10
|
+
readonly mcpToken: string;
|
|
11
|
+
readonly verbose?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface PipelineResult {
|
|
14
|
+
readonly featureId: string;
|
|
15
|
+
readonly phase: string;
|
|
16
|
+
readonly status: 'success' | 'error';
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly data?: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface PhaseConfig {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly checkRequirements: () => Promise<boolean>;
|
|
23
|
+
readonly execute: (options: PipelinePhaseOptions, config: EdsgerConfig, checklistContext?: ChecklistPhaseContext | null) => Promise<any>;
|
|
24
|
+
readonly requirementsError: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReviewResult } from '../types/index.js';
|
|
2
|
+
export declare const colors: {
|
|
3
|
+
reset: string;
|
|
4
|
+
bright: string;
|
|
5
|
+
red: string;
|
|
6
|
+
green: string;
|
|
7
|
+
yellow: string;
|
|
8
|
+
blue: string;
|
|
9
|
+
magenta: string;
|
|
10
|
+
cyan: string;
|
|
11
|
+
gray: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const colorize: (text: string, color: keyof typeof colors) => string;
|
|
14
|
+
export declare const logInfo: (message: string) => void;
|
|
15
|
+
export declare const logSuccess: (message: string) => void;
|
|
16
|
+
export declare const logWarning: (message: string) => void;
|
|
17
|
+
export declare const logError: (message: string) => void;
|
|
18
|
+
export declare const logProgress: (current: number, total: number, file: string) => void;
|
|
19
|
+
export declare const logResults: (results: ReviewResult[], verbose?: boolean) => void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const colors = {
|
|
2
|
+
reset: '\x1b[0m',
|
|
3
|
+
bright: '\x1b[1m',
|
|
4
|
+
red: '\x1b[31m',
|
|
5
|
+
green: '\x1b[32m',
|
|
6
|
+
yellow: '\x1b[33m',
|
|
7
|
+
blue: '\x1b[34m',
|
|
8
|
+
magenta: '\x1b[35m',
|
|
9
|
+
cyan: '\x1b[36m',
|
|
10
|
+
gray: '\x1b[90m'
|
|
11
|
+
};
|
|
12
|
+
export const colorize = (text, color) => {
|
|
13
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
14
|
+
};
|
|
15
|
+
export const logInfo = (message) => {
|
|
16
|
+
console.log(colorize(`ℹ ${message}`, 'blue'));
|
|
17
|
+
};
|
|
18
|
+
export const logSuccess = (message) => {
|
|
19
|
+
console.log(colorize(`✓ ${message}`, 'green'));
|
|
20
|
+
};
|
|
21
|
+
export const logWarning = (message) => {
|
|
22
|
+
console.log(colorize(`⚠ ${message}`, 'yellow'));
|
|
23
|
+
};
|
|
24
|
+
export const logError = (message) => {
|
|
25
|
+
console.error(colorize(`✗ ${message}`, 'red'));
|
|
26
|
+
};
|
|
27
|
+
export const logProgress = (current, total, file) => {
|
|
28
|
+
const percentage = Math.round((current / total) * 100);
|
|
29
|
+
const progress = `[${current}/${total}] ${percentage}%`;
|
|
30
|
+
console.log(colorize(`${progress} Reviewing ${file}`, 'gray'));
|
|
31
|
+
};
|
|
32
|
+
export const logResults = (results, verbose = false) => {
|
|
33
|
+
const okCount = results.filter(r => r.status === 'OK').length;
|
|
34
|
+
const warnCount = results.filter(r => r.status === 'WARN').length;
|
|
35
|
+
const blockCount = results.filter(r => r.status === 'BLOCK').length;
|
|
36
|
+
console.log('\n' + colorize('='.repeat(60), 'gray'));
|
|
37
|
+
console.log(colorize('Review Results', 'bright'));
|
|
38
|
+
console.log(colorize('='.repeat(60), 'gray'));
|
|
39
|
+
results.forEach(result => {
|
|
40
|
+
const icon = result.status === 'OK' ? '✓' : result.status === 'WARN' ? '⚠' : '✗';
|
|
41
|
+
const color = result.status === 'OK' ? 'green' : result.status === 'WARN' ? 'yellow' : 'red';
|
|
42
|
+
console.log(colorize(`${icon} ${result.file}: ${result.message}`, color));
|
|
43
|
+
if (verbose && result.details && result.status !== 'OK') {
|
|
44
|
+
console.log(colorize(` Details: ${result.details}`, 'gray'));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
console.log('\n' + colorize('Summary:', 'bright'));
|
|
48
|
+
console.log(colorize(` ✓ Passed: ${okCount}`, 'green'));
|
|
49
|
+
console.log(colorize(` ⚠ Warnings: ${warnCount}`, 'yellow'));
|
|
50
|
+
console.log(colorize(` ✗ Blocked: ${blockCount}`, 'red'));
|
|
51
|
+
console.log(colorize(` Total: ${results.length} files reviewed`, 'gray'));
|
|
52
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging utilities for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
import { PipelineResult } from '../types/pipeline.js';
|
|
5
|
+
export declare const logPipelineStart: (featureId: string, verbose?: boolean) => void;
|
|
6
|
+
export declare const logPhaseResult: (result: PipelineResult, verbose?: boolean) => PipelineResult;
|
|
7
|
+
export declare const logPipelineComplete: (results: readonly PipelineResult[], verbose?: boolean) => readonly PipelineResult[];
|
|
8
|
+
export declare const shouldContinuePipeline: (results: readonly PipelineResult[]) => boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging utilities for pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
// Pipeline execution utilities
|
|
5
|
+
export const logPipelineStart = (featureId, verbose) => {
|
|
6
|
+
if (verbose) {
|
|
7
|
+
console.log(`🚀 Starting complete pipeline for feature: ${featureId}`);
|
|
8
|
+
console.log('📋 Pipeline phases: feature-analysis → technical-design → code-implementation → functional-testing');
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
export const logPhaseResult = (result, verbose) => {
|
|
12
|
+
if (verbose) {
|
|
13
|
+
const statusIcon = result.status === 'success' ? '✅' : '❌';
|
|
14
|
+
console.log(`${statusIcon} ${result.phase}: ${result.message}`);
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
export const logPipelineComplete = (results, verbose) => {
|
|
19
|
+
if (verbose) {
|
|
20
|
+
const lastResult = results[results.length - 1];
|
|
21
|
+
const featureId = lastResult?.featureId;
|
|
22
|
+
if (lastResult?.status === 'success') {
|
|
23
|
+
console.log(`✅ Complete pipeline finished successfully for feature: ${featureId}`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
console.log(`❌ Pipeline failed at ${lastResult?.phase}: ${lastResult?.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return results;
|
|
30
|
+
};
|
|
31
|
+
// Pure function to check if pipeline should continue
|
|
32
|
+
export const shouldContinuePipeline = (results) => {
|
|
33
|
+
const lastResult = results[results.length - 1];
|
|
34
|
+
return lastResult?.status === 'success';
|
|
35
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 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 phase configurations
|
|
9
|
+
export const phaseConfigs = [
|
|
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
|
+
];
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature filtering utilities for workflow processor
|
|
3
|
+
* Pure functions for filtering and selecting features for processing
|
|
4
|
+
*/
|
|
5
|
+
import type { FeatureInfo } from '../../types/features.js';
|
|
6
|
+
import type { FeatureProcessingState } from './state-manager.js';
|
|
7
|
+
export declare const shouldProcessFeature: (maxRetries: number) => (feature: FeatureInfo, states: Map<string, FeatureProcessingState>) => boolean;
|
|
8
|
+
export declare const findNextFeature: (features: readonly FeatureInfo[], states: Map<string, FeatureProcessingState>, maxRetries: number) => FeatureInfo | undefined;
|
|
9
|
+
export declare const isFeatureProcessing: (featureId: string, states: Map<string, FeatureProcessingState>) => boolean;
|
|
10
|
+
export declare const isFeatureCompleted: (featureId: string, states: Map<string, FeatureProcessingState>) => boolean;
|
|
11
|
+
export declare const isFeatureFailed: (featureId: string, states: Map<string, FeatureProcessingState>) => boolean;
|
|
12
|
+
export declare const hasReachedMaxRetries: (featureId: string, states: Map<string, FeatureProcessingState>, maxRetries: number) => boolean;
|
|
13
|
+
export declare const filterProcessingFeatures: (features: readonly FeatureInfo[], states: Map<string, FeatureProcessingState>) => FeatureInfo[];
|
|
14
|
+
export declare const filterCompletedFeatures: (features: readonly FeatureInfo[], states: Map<string, FeatureProcessingState>) => FeatureInfo[];
|
|
15
|
+
export declare const filterFailedFeatures: (features: readonly FeatureInfo[], states: Map<string, FeatureProcessingState>) => FeatureInfo[];
|
|
16
|
+
export declare const filterAvailableFeatures: (features: readonly FeatureInfo[], states: Map<string, FeatureProcessingState>, maxRetries: number) => FeatureInfo[];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature filtering utilities for workflow processor
|
|
3
|
+
* Pure functions for filtering and selecting features for processing
|
|
4
|
+
*/
|
|
5
|
+
// Feature filtering functions (pure)
|
|
6
|
+
export const shouldProcessFeature = (maxRetries) => (feature, states) => {
|
|
7
|
+
const state = states.get(feature.id);
|
|
8
|
+
// If never processed, should process
|
|
9
|
+
if (!state)
|
|
10
|
+
return true;
|
|
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
|
|
13
|
+
if (feature.updated_at) {
|
|
14
|
+
const featureUpdatedTime = new Date(feature.updated_at).getTime();
|
|
15
|
+
const lastAttemptTime = state.lastAttempt.getTime();
|
|
16
|
+
if (featureUpdatedTime > lastAttemptTime) {
|
|
17
|
+
// Feature has been updated since last processing, reprocess it
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// If failed and haven't exceeded retry limit, should retry
|
|
22
|
+
return state.status === 'failed' && state.retryCount < maxRetries;
|
|
23
|
+
};
|
|
24
|
+
export const findNextFeature = (features, states, maxRetries) => features.find((feature) => shouldProcessFeature(maxRetries)(feature, states));
|
|
25
|
+
// Feature status checking functions (pure)
|
|
26
|
+
export const isFeatureProcessing = (featureId, states) => {
|
|
27
|
+
const state = states.get(featureId);
|
|
28
|
+
return state?.status === 'processing';
|
|
29
|
+
};
|
|
30
|
+
export const isFeatureCompleted = (featureId, states) => {
|
|
31
|
+
const state = states.get(featureId);
|
|
32
|
+
return state?.status === 'completed';
|
|
33
|
+
};
|
|
34
|
+
export const isFeatureFailed = (featureId, states) => {
|
|
35
|
+
const state = states.get(featureId);
|
|
36
|
+
return state?.status === 'failed';
|
|
37
|
+
};
|
|
38
|
+
export const hasReachedMaxRetries = (featureId, states, maxRetries) => {
|
|
39
|
+
const state = states.get(featureId);
|
|
40
|
+
return state ? state.retryCount >= maxRetries : false;
|
|
41
|
+
};
|
|
42
|
+
// Feature collection filtering functions (pure)
|
|
43
|
+
export const filterProcessingFeatures = (features, states) => features.filter((feature) => isFeatureProcessing(feature.id, states));
|
|
44
|
+
export const filterCompletedFeatures = (features, states) => features.filter((feature) => isFeatureCompleted(feature.id, states));
|
|
45
|
+
export const filterFailedFeatures = (features, states) => features.filter((feature) => isFeatureFailed(feature.id, states));
|
|
46
|
+
export const filterAvailableFeatures = (features, states, maxRetries) => features.filter((feature) => shouldProcessFeature(maxRetries)(feature, states));
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core workflow processor modules
|
|
3
|
+
* Centralized exports for all core functionality
|
|
4
|
+
*/
|
|
5
|
+
// State management
|
|
6
|
+
export * from './state-manager.js';
|
|
7
|
+
// Feature filtering
|
|
8
|
+
export * from './feature-filter.js';
|
|
9
|
+
// Pipeline evaluation
|
|
10
|
+
export * from './pipeline-evaluator.js';
|
|
11
|
+
// Workflow logging
|
|
12
|
+
export * from './workflow-logger.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline result evaluation utilities for workflow processor
|
|
3
|
+
* Pure functions for evaluating pipeline execution results
|
|
4
|
+
*/
|
|
5
|
+
import type { PipelineResult } from '../../types/pipeline.js';
|
|
6
|
+
export declare const evaluatePipelineResults: (results: readonly PipelineResult[]) => boolean;
|
|
7
|
+
export declare const hasAnyPipelineFailures: (results: readonly PipelineResult[]) => boolean;
|
|
8
|
+
export declare const countSuccessfulPhases: (results: readonly PipelineResult[]) => number;
|
|
9
|
+
export declare const countFailedPhases: (results: readonly PipelineResult[]) => number;
|
|
10
|
+
export declare const getFailedPhases: (results: readonly PipelineResult[]) => PipelineResult[];
|
|
11
|
+
export declare const getSuccessfulPhases: (results: readonly PipelineResult[]) => PipelineResult[];
|
|
12
|
+
export declare const getFirstFailure: (results: readonly PipelineResult[]) => PipelineResult | undefined;
|
|
13
|
+
export declare const getLastPhaseResult: (results: readonly PipelineResult[]) => PipelineResult | undefined;
|
|
14
|
+
export declare const isPipelineFullySuccessful: (results: readonly PipelineResult[]) => boolean;
|
|
15
|
+
export declare const isPipelinePartiallySuccessful: (results: readonly PipelineResult[]) => boolean;
|
|
16
|
+
export declare const isPipelineCompleteFailure: (results: readonly PipelineResult[]) => boolean;
|
|
17
|
+
export declare const isPipelineEmpty: (results: readonly PipelineResult[]) => boolean;
|
|
18
|
+
export interface PipelineStats {
|
|
19
|
+
readonly total: number;
|
|
20
|
+
readonly successful: number;
|
|
21
|
+
readonly failed: number;
|
|
22
|
+
readonly successRate: number;
|
|
23
|
+
}
|
|
24
|
+
export declare const calculatePipelineStats: (results: readonly PipelineResult[]) => PipelineStats;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline result evaluation utilities for workflow processor
|
|
3
|
+
* Pure functions for evaluating pipeline execution results
|
|
4
|
+
*/
|
|
5
|
+
// Pipeline result evaluation (pure)
|
|
6
|
+
export const evaluatePipelineResults = (results) => results.every((result) => result.status === 'success');
|
|
7
|
+
export const hasAnyPipelineFailures = (results) => results.some((result) => result.status !== 'success');
|
|
8
|
+
export const countSuccessfulPhases = (results) => results.filter((result) => result.status === 'success').length;
|
|
9
|
+
export const countFailedPhases = (results) => results.filter((result) => result.status !== 'success').length;
|
|
10
|
+
export const getFailedPhases = (results) => results.filter((result) => result.status !== 'success');
|
|
11
|
+
export const getSuccessfulPhases = (results) => results.filter((result) => result.status === 'success');
|
|
12
|
+
export const getFirstFailure = (results) => results.find((result) => result.status !== 'success');
|
|
13
|
+
export const getLastPhaseResult = (results) => results.length > 0 ? results[results.length - 1] : undefined;
|
|
14
|
+
// Pipeline completion status
|
|
15
|
+
export const isPipelineFullySuccessful = (results) => results.length > 0 && evaluatePipelineResults(results);
|
|
16
|
+
export const isPipelinePartiallySuccessful = (results) => results.length > 0 &&
|
|
17
|
+
countSuccessfulPhases(results) > 0 &&
|
|
18
|
+
hasAnyPipelineFailures(results);
|
|
19
|
+
export const isPipelineCompleteFailure = (results) => results.length > 0 && countSuccessfulPhases(results) === 0;
|
|
20
|
+
export const isPipelineEmpty = (results) => results.length === 0;
|
|
21
|
+
export const calculatePipelineStats = (results) => {
|
|
22
|
+
const total = results.length;
|
|
23
|
+
const successful = countSuccessfulPhases(results);
|
|
24
|
+
const failed = countFailedPhases(results);
|
|
25
|
+
const successRate = total > 0 ? successful / total : 0;
|
|
26
|
+
return {
|
|
27
|
+
total,
|
|
28
|
+
successful,
|
|
29
|
+
failed,
|
|
30
|
+
successRate,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State management utilities for workflow processor
|
|
3
|
+
* Pure functions for handling feature processing states
|
|
4
|
+
*/
|
|
5
|
+
export interface FeatureProcessingState {
|
|
6
|
+
readonly featureId: string;
|
|
7
|
+
readonly retryCount: number;
|
|
8
|
+
readonly lastAttempt: Date;
|
|
9
|
+
readonly status: 'processing' | 'completed' | 'failed';
|
|
10
|
+
readonly featureUpdatedAt?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface WorkflowStats {
|
|
13
|
+
readonly totalProcessed: number;
|
|
14
|
+
readonly completed: number;
|
|
15
|
+
readonly failed: number;
|
|
16
|
+
readonly processing: number;
|
|
17
|
+
readonly isRunning: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const createInitialState: () => Map<string, FeatureProcessingState>;
|
|
20
|
+
export declare const createProcessingState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
|
|
21
|
+
export declare const createCompletedState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
|
|
22
|
+
export declare const createFailedState: (featureId: string, currentState?: FeatureProcessingState) => FeatureProcessingState;
|
|
23
|
+
export declare const updateFeatureState: (states: Map<string, FeatureProcessingState>, featureId: string, updateFn: (currentState?: FeatureProcessingState) => FeatureProcessingState) => Map<string, FeatureProcessingState>;
|
|
24
|
+
export declare const calculateStats: (states: Map<string, FeatureProcessingState>, isRunning: boolean) => WorkflowStats;
|