erosolar-cli 2.0.5 → 2.1.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/agents/erosolar-security.rules.json +147 -0
- package/dist/capabilities/enhancedAnalysisCapability.d.ts +13 -0
- package/dist/capabilities/enhancedAnalysisCapability.d.ts.map +1 -0
- package/dist/capabilities/enhancedAnalysisCapability.js +20 -0
- package/dist/capabilities/enhancedAnalysisCapability.js.map +1 -0
- package/dist/capabilities/offsecOpsCapability.d.ts +6 -0
- package/dist/capabilities/offsecOpsCapability.d.ts.map +1 -0
- package/dist/capabilities/offsecOpsCapability.js +20 -0
- package/dist/capabilities/offsecOpsCapability.js.map +1 -0
- package/dist/capabilities/offsecSearchCapability.d.ts +12 -0
- package/dist/capabilities/offsecSearchCapability.d.ts.map +1 -0
- package/dist/capabilities/offsecSearchCapability.js +27 -0
- package/dist/capabilities/offsecSearchCapability.js.map +1 -0
- package/dist/capabilities/taoCapability.d.ts +6 -0
- package/dist/capabilities/taoCapability.d.ts.map +1 -0
- package/dist/capabilities/taoCapability.js +20 -0
- package/dist/capabilities/taoCapability.js.map +1 -0
- package/dist/capabilities/toolRegistry.d.ts +2 -1
- package/dist/capabilities/toolRegistry.d.ts.map +1 -1
- package/dist/capabilities/toolRegistry.js +6 -1
- package/dist/capabilities/toolRegistry.js.map +1 -1
- package/dist/contracts/agent-schemas.json +18 -19
- package/dist/contracts/tools.schema.json +38 -8
- package/dist/core/agent.js +4 -4
- package/dist/core/agent.js.map +1 -1
- package/dist/core/alphaZeroEngine.js +1 -1
- package/dist/core/alphaZeroEngine.js.map +1 -1
- package/dist/core/alphaZeroModular.js +2 -2
- package/dist/core/alphaZeroModular.js.map +1 -1
- package/dist/core/contextManager.d.ts +8 -2
- package/dist/core/contextManager.d.ts.map +1 -1
- package/dist/core/contextManager.js +15 -2
- package/dist/core/contextManager.js.map +1 -1
- package/dist/core/costTracker.js +1 -1
- package/dist/core/costTracker.js.map +1 -1
- package/dist/core/deepBugAnalyzer.d.ts +128 -0
- package/dist/core/deepBugAnalyzer.d.ts.map +1 -0
- package/dist/core/deepBugAnalyzer.js +406 -0
- package/dist/core/deepBugAnalyzer.js.map +1 -0
- package/dist/core/hypothesisEngine.d.ts +113 -0
- package/dist/core/hypothesisEngine.d.ts.map +1 -0
- package/dist/core/hypothesisEngine.js +264 -0
- package/dist/core/hypothesisEngine.js.map +1 -0
- package/dist/core/intelligentSummarizer.d.ts +79 -0
- package/dist/core/intelligentSummarizer.d.ts.map +1 -0
- package/dist/core/intelligentSummarizer.js +273 -0
- package/dist/core/intelligentSummarizer.js.map +1 -0
- package/dist/core/memorySystem.js +2 -2
- package/dist/core/memorySystem.js.map +1 -1
- package/dist/core/offsecAlphaZero.d.ts +3 -0
- package/dist/core/offsecAlphaZero.d.ts.map +1 -1
- package/dist/core/offsecAlphaZero.js +166 -5
- package/dist/core/offsecAlphaZero.js.map +1 -1
- package/dist/core/productTestHarness.d.ts +113 -0
- package/dist/core/productTestHarness.d.ts.map +1 -0
- package/dist/core/productTestHarness.js +345 -0
- package/dist/core/productTestHarness.js.map +1 -0
- package/dist/core/securityAssessment.js +1 -1
- package/dist/core/securityAssessment.js.map +1 -1
- package/dist/core/toolPatternAnalyzer.d.ts +87 -0
- package/dist/core/toolPatternAnalyzer.d.ts.map +1 -0
- package/dist/core/toolPatternAnalyzer.js +272 -0
- package/dist/core/toolPatternAnalyzer.js.map +1 -0
- package/dist/core/updateChecker.js +3 -3
- package/dist/core/updateChecker.js.map +1 -1
- package/dist/mcp/sseClient.js +1 -1
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.d.ts +3 -0
- package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.js +14 -0
- package/dist/plugins/tools/enhancedAnalysis/enhancedAnalysisPlugin.js.map +1 -0
- package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.d.ts +3 -0
- package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.d.ts.map +1 -0
- package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.js +12 -0
- package/dist/plugins/tools/enhancedCodeIntelligence/enhancedCodeIntelligencePlugin.js.map +1 -0
- package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.d.ts +3 -0
- package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.js +12 -0
- package/dist/plugins/tools/enhancedDevWorkflow/enhancedDevWorkflowPlugin.js.map +1 -0
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +12 -0
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/plugins/tools/offsec/offsecOpsPlugin.d.ts +3 -0
- package/dist/plugins/tools/offsec/offsecOpsPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/offsec/offsecOpsPlugin.js +10 -0
- package/dist/plugins/tools/offsec/offsecOpsPlugin.js.map +1 -0
- package/dist/plugins/tools/offsec/offsecSearchPlugin.d.ts +3 -0
- package/dist/plugins/tools/offsec/offsecSearchPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/offsec/offsecSearchPlugin.js +12 -0
- package/dist/plugins/tools/offsec/offsecSearchPlugin.js.map +1 -0
- package/dist/plugins/tools/tao/taoPlugin.d.ts +3 -0
- package/dist/plugins/tools/tao/taoPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/tao/taoPlugin.js +10 -0
- package/dist/plugins/tools/tao/taoPlugin.js.map +1 -0
- package/dist/shell/composableMessage.js +2 -2
- package/dist/shell/composableMessage.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +6 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +50 -15
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.js +1 -1
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +3 -0
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/tools/buildTools.js +1 -1
- package/dist/tools/buildTools.js.map +1 -1
- package/dist/tools/diffUtils.js +6 -6
- package/dist/tools/diffUtils.js.map +1 -1
- package/dist/tools/editTools.js +1 -1
- package/dist/tools/editTools.js.map +1 -1
- package/dist/tools/enhancedAnalysisTools.d.ts +9 -0
- package/dist/tools/enhancedAnalysisTools.d.ts.map +1 -0
- package/dist/tools/enhancedAnalysisTools.js +382 -0
- package/dist/tools/enhancedAnalysisTools.js.map +1 -0
- package/dist/tools/enhancedCodeIntelligenceTools.d.ts +1 -21
- package/dist/tools/enhancedCodeIntelligenceTools.d.ts.map +1 -1
- package/dist/tools/enhancedCodeIntelligenceTools.js +378 -256
- package/dist/tools/enhancedCodeIntelligenceTools.js.map +1 -1
- package/dist/tools/enhancedDevWorkflowTools.d.ts +2 -10
- package/dist/tools/enhancedDevWorkflowTools.d.ts.map +1 -1
- package/dist/tools/enhancedDevWorkflowTools.js +293 -165
- package/dist/tools/enhancedDevWorkflowTools.js.map +1 -1
- package/dist/tools/interactionTools.d.ts.map +1 -1
- package/dist/tools/interactionTools.js +55 -0
- package/dist/tools/interactionTools.js.map +1 -1
- package/dist/tools/learnTools.js +1 -1
- package/dist/tools/learnTools.js.map +1 -1
- package/dist/tools/offsec/offsecOperationsTools.d.ts +3 -0
- package/dist/tools/offsec/offsecOperationsTools.d.ts.map +1 -0
- package/dist/tools/offsec/offsecOperationsTools.js +333 -0
- package/dist/tools/offsec/offsecOperationsTools.js.map +1 -0
- package/dist/tools/offsecSearchTools.d.ts +3 -0
- package/dist/tools/offsecSearchTools.d.ts.map +1 -0
- package/dist/tools/offsecSearchTools.js +330 -0
- package/dist/tools/offsecSearchTools.js.map +1 -0
- package/dist/tools/taoOperations.d.ts +7 -0
- package/dist/tools/taoOperations.d.ts.map +1 -0
- package/dist/tools/taoOperations.js +744 -0
- package/dist/tools/taoOperations.js.map +1 -0
- package/dist/ui/ClaudeCodeRenderer.js +1 -1
- package/dist/ui/ClaudeCodeRenderer.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +10 -6
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +69 -67
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/UnifiedUIRenderer.d.ts +2 -0
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
- package/dist/ui/UnifiedUIRenderer.js +64 -13
- package/dist/ui/UnifiedUIRenderer.js.map +1 -1
- package/dist/ui/globalWriteLock.d.ts.map +1 -1
- package/dist/ui/globalWriteLock.js +6 -0
- package/dist/ui/globalWriteLock.js.map +1 -1
- package/dist/ui/inPlaceUpdater.js +1 -1
- package/dist/ui/inPlaceUpdater.js.map +1 -1
- package/dist/ui/outputMode.d.ts.map +1 -1
- package/dist/ui/outputMode.js +1 -2
- package/dist/ui/outputMode.js.map +1 -1
- package/dist/ui/richText.js +4 -4
- package/dist/ui/richText.js.map +1 -1
- package/dist/ui/streamingFormatter.d.ts +11 -0
- package/dist/ui/streamingFormatter.d.ts.map +1 -1
- package/dist/ui/streamingFormatter.js +27 -1
- package/dist/ui/streamingFormatter.js.map +1 -1
- package/dist/ui/toolDisplay.js +1 -1
- package/dist/ui/toolDisplay.js.map +1 -1
- package/package.json +4 -13
|
@@ -1,31 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Enhanced Development Workflow Tools
|
|
3
|
-
*
|
|
3
|
+
* Real workflow runners that measure build/test/lint quality gates and scaffold CI.
|
|
4
4
|
*/
|
|
5
|
-
|
|
5
|
+
import { exec } from 'node:child_process';
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { promisify } from 'node:util';
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
const DEFAULT_TIMEOUT_MS = 300_000; // 5 minutes per step
|
|
11
|
+
export function createEnhancedDevWorkflowTools(workingDir) {
|
|
6
12
|
return [
|
|
7
13
|
{
|
|
8
14
|
name: 'run_comprehensive_workflow',
|
|
9
|
-
description: 'Run
|
|
15
|
+
description: 'Run build, test, lint, and quality gates with timing + output summaries.',
|
|
10
16
|
parameters: {
|
|
11
17
|
type: 'object',
|
|
12
18
|
properties: {
|
|
13
|
-
includeBuild: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
includeTests: {
|
|
18
|
-
type: 'boolean',
|
|
19
|
-
description: 'Include test execution (default: true).',
|
|
20
|
-
},
|
|
21
|
-
includeLint: {
|
|
22
|
-
type: 'boolean',
|
|
23
|
-
description: 'Include linting (default: true).',
|
|
24
|
-
},
|
|
25
|
-
includeQuality: {
|
|
26
|
-
type: 'boolean',
|
|
27
|
-
description: 'Include quality checks (default: true).',
|
|
28
|
-
},
|
|
19
|
+
includeBuild: { type: 'boolean', description: 'Run build script if present (default: true).' },
|
|
20
|
+
includeTests: { type: 'boolean', description: 'Run test script if present (default: true).' },
|
|
21
|
+
includeLint: { type: 'boolean', description: 'Run lint script if present (default: true).' },
|
|
22
|
+
includeQuality: { type: 'boolean', description: 'Run quality gate script if present (default: true).' },
|
|
29
23
|
timeout: {
|
|
30
24
|
type: 'number',
|
|
31
25
|
description: 'Timeout per step in milliseconds (default: 300000).',
|
|
@@ -34,72 +28,65 @@ export function createEnhancedDevWorkflowTools(_workingDir) {
|
|
|
34
28
|
additionalProperties: false,
|
|
35
29
|
},
|
|
36
30
|
handler: async (args) => {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
includeBuild,
|
|
44
|
-
includeTests,
|
|
45
|
-
includeLint,
|
|
46
|
-
includeQuality,
|
|
47
|
-
timeout,
|
|
31
|
+
const timeout = args['timeout'] ?? DEFAULT_TIMEOUT_MS;
|
|
32
|
+
const steps = collectWorkflowSteps(workingDir, {
|
|
33
|
+
includeBuild: args['includeBuild'] !== false,
|
|
34
|
+
includeTests: args['includeTests'] !== false,
|
|
35
|
+
includeLint: args['includeLint'] !== false,
|
|
36
|
+
includeQuality: args['includeQuality'] !== false,
|
|
48
37
|
});
|
|
38
|
+
return runWorkflowSteps(steps, workingDir, timeout);
|
|
49
39
|
},
|
|
50
40
|
},
|
|
51
41
|
{
|
|
52
42
|
name: 'analyze_workflow_performance',
|
|
53
|
-
description: '
|
|
43
|
+
description: 'Measure workflow step durations to identify bottlenecks.',
|
|
54
44
|
parameters: {
|
|
55
45
|
type: 'object',
|
|
56
46
|
properties: {
|
|
57
47
|
iterations: {
|
|
58
48
|
type: 'number',
|
|
59
|
-
description: 'Number of
|
|
49
|
+
description: 'Number of runs to average (max 3, default: 1).',
|
|
60
50
|
},
|
|
61
51
|
},
|
|
62
52
|
additionalProperties: false,
|
|
63
53
|
},
|
|
64
54
|
handler: async (args) => {
|
|
65
|
-
const iterations = args['iterations'] ??
|
|
66
|
-
return analyzeWorkflowPerformance(iterations);
|
|
55
|
+
const iterations = Math.min(3, Math.max(1, Number(args['iterations'] ?? 1)));
|
|
56
|
+
return analyzeWorkflowPerformance(workingDir, iterations);
|
|
67
57
|
},
|
|
68
58
|
},
|
|
69
59
|
{
|
|
70
60
|
name: 'optimize_development_workflow',
|
|
71
|
-
description: '
|
|
61
|
+
description: 'Generate optimization recommendations; optionally write them to .intelligence.',
|
|
72
62
|
parameters: {
|
|
73
63
|
type: 'object',
|
|
74
64
|
properties: {
|
|
75
65
|
strategy: {
|
|
76
66
|
type: 'string',
|
|
77
67
|
enum: ['caching', 'parallel', 'incremental', 'all'],
|
|
78
|
-
description: 'Optimization strategy (default: all).',
|
|
68
|
+
description: 'Optimization strategy focus (default: all).',
|
|
79
69
|
},
|
|
80
70
|
preview: {
|
|
81
71
|
type: 'boolean',
|
|
82
|
-
description: '
|
|
72
|
+
description: 'If false, writes recommendations to .intelligence/workflow-optimizations.md.',
|
|
83
73
|
},
|
|
84
74
|
},
|
|
85
75
|
additionalProperties: false,
|
|
86
76
|
},
|
|
87
77
|
handler: async (args) => {
|
|
88
78
|
const strategy = args['strategy'] ?? 'all';
|
|
89
|
-
const preview = args['preview']
|
|
90
|
-
return optimizeDevelopmentWorkflow(strategy, preview);
|
|
79
|
+
const preview = args['preview'] !== false;
|
|
80
|
+
return optimizeDevelopmentWorkflow(workingDir, strategy, preview);
|
|
91
81
|
},
|
|
92
82
|
},
|
|
93
83
|
{
|
|
94
84
|
name: 'generate_workflow_report',
|
|
95
|
-
description: '
|
|
85
|
+
description: 'Summarize available scripts, lockfiles, CI config, and quick recommendations.',
|
|
96
86
|
parameters: {
|
|
97
87
|
type: 'object',
|
|
98
88
|
properties: {
|
|
99
|
-
includeMetrics: {
|
|
100
|
-
type: 'boolean',
|
|
101
|
-
description: 'Include performance metrics (default: true).',
|
|
102
|
-
},
|
|
89
|
+
includeMetrics: { type: 'boolean', description: 'Include script availability and lockfile info (default: true).' },
|
|
103
90
|
includeRecommendations: {
|
|
104
91
|
type: 'boolean',
|
|
105
92
|
description: 'Include optimization recommendations (default: true).',
|
|
@@ -108,14 +95,14 @@ export function createEnhancedDevWorkflowTools(_workingDir) {
|
|
|
108
95
|
additionalProperties: false,
|
|
109
96
|
},
|
|
110
97
|
handler: async (args) => {
|
|
111
|
-
const includeMetrics = args['includeMetrics']
|
|
112
|
-
const includeRecommendations = args['includeRecommendations']
|
|
113
|
-
return generateWorkflowReport(includeMetrics, includeRecommendations);
|
|
98
|
+
const includeMetrics = args['includeMetrics'] !== false;
|
|
99
|
+
const includeRecommendations = args['includeRecommendations'] !== false;
|
|
100
|
+
return generateWorkflowReport(workingDir, includeMetrics, includeRecommendations);
|
|
114
101
|
},
|
|
115
102
|
},
|
|
116
103
|
{
|
|
117
104
|
name: 'setup_ci_cd_workflow',
|
|
118
|
-
description: '
|
|
105
|
+
description: 'Scaffold CI/CD workflow (GitHub Actions/GitLab/Azure/CircleCI).',
|
|
119
106
|
parameters: {
|
|
120
107
|
type: 'object',
|
|
121
108
|
properties: {
|
|
@@ -126,178 +113,319 @@ export function createEnhancedDevWorkflowTools(_workingDir) {
|
|
|
126
113
|
},
|
|
127
114
|
includeQualityGates: {
|
|
128
115
|
type: 'boolean',
|
|
129
|
-
description: 'Include quality
|
|
116
|
+
description: 'Include quality gate steps when scripts exist (default: true).',
|
|
130
117
|
},
|
|
131
118
|
includeDeployment: {
|
|
132
119
|
type: 'boolean',
|
|
133
|
-
description: 'Include
|
|
120
|
+
description: 'Include deploy placeholder step (default: false).',
|
|
134
121
|
},
|
|
135
122
|
preview: {
|
|
136
123
|
type: 'boolean',
|
|
137
|
-
description: 'Show
|
|
124
|
+
description: 'Show workflow yaml instead of writing it (default: true).',
|
|
138
125
|
},
|
|
139
126
|
},
|
|
140
127
|
additionalProperties: false,
|
|
141
128
|
},
|
|
142
129
|
handler: async (args) => {
|
|
143
130
|
const platform = args['platform'] ?? 'github';
|
|
144
|
-
const includeQualityGates = args['includeQualityGates']
|
|
145
|
-
const includeDeployment = args['includeDeployment']
|
|
146
|
-
const preview = args['preview']
|
|
147
|
-
return setupCiCdWorkflow(
|
|
131
|
+
const includeQualityGates = args['includeQualityGates'] !== false;
|
|
132
|
+
const includeDeployment = args['includeDeployment'] === true;
|
|
133
|
+
const preview = args['preview'] !== false;
|
|
134
|
+
return setupCiCdWorkflow({
|
|
135
|
+
workingDir,
|
|
136
|
+
platform,
|
|
137
|
+
includeQualityGates,
|
|
138
|
+
includeDeployment,
|
|
139
|
+
preview,
|
|
140
|
+
});
|
|
148
141
|
},
|
|
149
142
|
},
|
|
150
143
|
];
|
|
151
144
|
}
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
145
|
+
function readPackageJson(workingDir) {
|
|
146
|
+
const packageJsonPath = join(workingDir, 'package.json');
|
|
147
|
+
if (!existsSync(packageJsonPath)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
return JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function collectWorkflowSteps(workingDir, options) {
|
|
158
|
+
const pkg = readPackageJson(workingDir);
|
|
159
|
+
const scripts = pkg?.['scripts'] ?? {};
|
|
162
160
|
const steps = [];
|
|
163
161
|
if (options.includeBuild) {
|
|
164
|
-
|
|
162
|
+
if (scripts['build']) {
|
|
163
|
+
steps.push({ name: 'build', command: 'npm run build' });
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
steps.push({ name: 'build', skipReason: 'package.json lacks a build script' });
|
|
167
|
+
}
|
|
165
168
|
}
|
|
166
169
|
if (options.includeTests) {
|
|
167
|
-
|
|
170
|
+
if (scripts['test']) {
|
|
171
|
+
steps.push({ name: 'test', command: 'npm test' });
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
steps.push({ name: 'test', skipReason: 'package.json lacks a test script' });
|
|
175
|
+
}
|
|
168
176
|
}
|
|
169
177
|
if (options.includeLint) {
|
|
170
|
-
|
|
178
|
+
if (scripts['lint']) {
|
|
179
|
+
steps.push({ name: 'lint', command: 'npm run lint' });
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
steps.push({ name: 'lint', skipReason: 'package.json lacks a lint script' });
|
|
183
|
+
}
|
|
171
184
|
}
|
|
172
185
|
if (options.includeQuality) {
|
|
173
|
-
|
|
186
|
+
const qualityScript = scripts['quality-gate'] || scripts['quality'] || scripts['quality-check'] || scripts['quality:check'];
|
|
187
|
+
if (qualityScript) {
|
|
188
|
+
steps.push({ name: 'quality', command: `npm run ${qualityScript.includes('quality') ? qualityScript : 'quality-gate'}` });
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
steps.push({ name: 'quality', skipReason: 'No quality gate script (quality-gate|quality|quality-check)' });
|
|
192
|
+
}
|
|
174
193
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
194
|
+
return steps;
|
|
195
|
+
}
|
|
196
|
+
async function runWorkflowSteps(steps, workingDir, timeoutMs) {
|
|
197
|
+
const results = [];
|
|
198
|
+
for (const step of steps) {
|
|
199
|
+
if (!step.command) {
|
|
200
|
+
results.push({ name: step.name, status: 'skipped', error: step.skipReason });
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const start = Date.now();
|
|
204
|
+
try {
|
|
205
|
+
const { stdout, stderr } = await execAsync(step.command, {
|
|
206
|
+
cwd: workingDir,
|
|
207
|
+
timeout: timeoutMs,
|
|
208
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
209
|
+
});
|
|
210
|
+
results.push({
|
|
211
|
+
name: step.name,
|
|
212
|
+
status: 'passed',
|
|
213
|
+
durationMs: Date.now() - start,
|
|
214
|
+
output: [stdout, stderr].filter(Boolean).join('\n').trim(),
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
results.push({
|
|
219
|
+
name: step.name,
|
|
220
|
+
status: 'failed',
|
|
221
|
+
durationMs: Date.now() - start,
|
|
222
|
+
output: [error?.stdout, error?.stderr].filter(Boolean).join('\n').trim(),
|
|
223
|
+
error: error?.message || 'Unknown error',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return formatWorkflowResults(results);
|
|
228
|
+
}
|
|
229
|
+
function formatWorkflowResults(results) {
|
|
230
|
+
const output = [];
|
|
231
|
+
output.push('# Workflow Results');
|
|
232
|
+
const summary = { passed: 0, failed: 0, skipped: 0 };
|
|
233
|
+
results.forEach((result) => {
|
|
234
|
+
summary[result.status]++;
|
|
235
|
+
const duration = result.durationMs ? ` (${renderDuration(result.durationMs)})` : '';
|
|
236
|
+
output.push(`- ${result.name}: ${result.status}${duration}`);
|
|
237
|
+
if (result.error) {
|
|
238
|
+
output.push(` Error: ${result.error}`);
|
|
239
|
+
}
|
|
178
240
|
});
|
|
179
241
|
output.push('');
|
|
180
|
-
output.push(
|
|
242
|
+
output.push(`Summary: passed ${summary.passed}, failed ${summary.failed}, skipped ${summary.skipped}`);
|
|
181
243
|
return output.join('\n');
|
|
182
244
|
}
|
|
183
|
-
async function analyzeWorkflowPerformance(iterations) {
|
|
245
|
+
async function analyzeWorkflowPerformance(workingDir, iterations) {
|
|
246
|
+
const runnableSteps = collectWorkflowSteps(workingDir, {
|
|
247
|
+
includeBuild: true,
|
|
248
|
+
includeTests: true,
|
|
249
|
+
includeLint: true,
|
|
250
|
+
includeQuality: false,
|
|
251
|
+
}).filter((step) => Boolean(step.command));
|
|
252
|
+
if (runnableSteps.length === 0) {
|
|
253
|
+
return 'No runnable workflow steps found (build/test/lint scripts missing).';
|
|
254
|
+
}
|
|
255
|
+
const durations = Object.fromEntries(runnableSteps.map((s) => [s.name, []]));
|
|
256
|
+
for (let i = 0; i < iterations; i++) {
|
|
257
|
+
for (const step of runnableSteps) {
|
|
258
|
+
const start = Date.now();
|
|
259
|
+
try {
|
|
260
|
+
await execAsync(step.command, {
|
|
261
|
+
cwd: workingDir,
|
|
262
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
263
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
264
|
+
});
|
|
265
|
+
durations[step.name]?.push(Date.now() - start);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
durations[step.name]?.push(Date.now() - start);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
184
272
|
const output = [];
|
|
185
|
-
output.push('# Workflow Performance
|
|
186
|
-
output.push(
|
|
187
|
-
output.push(`📊 Analyzing ${iterations} iterations of development workflow`);
|
|
273
|
+
output.push('# Workflow Performance');
|
|
274
|
+
output.push(`Iterations: ${iterations}`);
|
|
188
275
|
output.push('');
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
output.push('- CPU utilization');
|
|
195
|
-
output.push('- I/O bottlenecks');
|
|
276
|
+
Object.entries(durations).forEach(([name, times]) => {
|
|
277
|
+
const avg = times.reduce((a, b) => a + b, 0) / times.length;
|
|
278
|
+
const worst = Math.max(...times);
|
|
279
|
+
output.push(`${name}: avg ${renderDuration(avg)}, worst ${renderDuration(worst)} across ${times.length} run(s)`);
|
|
280
|
+
});
|
|
196
281
|
output.push('');
|
|
197
|
-
output.push('
|
|
198
|
-
output.push('- Parallel test execution');
|
|
199
|
-
output.push('- Build caching strategies');
|
|
200
|
-
output.push('- Incremental compilation');
|
|
201
|
-
output.push('- Dependency optimization');
|
|
282
|
+
output.push('Use `run_comprehensive_workflow` to see full output and failures.');
|
|
202
283
|
return output.join('\n');
|
|
203
284
|
}
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
output.push(`👁️ Preview mode: ${preview ? 'ON' : 'OFF'}`);
|
|
210
|
-
output.push('');
|
|
211
|
-
output.push('## Optimization Features');
|
|
285
|
+
function optimizeDevelopmentWorkflow(workingDir, strategy, preview) {
|
|
286
|
+
const pkg = readPackageJson(workingDir);
|
|
287
|
+
const scripts = pkg?.['scripts'] ?? {};
|
|
288
|
+
const lockFile = detectLockfile(workingDir);
|
|
289
|
+
const suggestions = [];
|
|
212
290
|
if (strategy === 'caching' || strategy === 'all') {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
output.push('- Dependency caching');
|
|
217
|
-
output.push('- Cache invalidation strategies');
|
|
291
|
+
suggestions.push(lockFile ? `Use ${lockFile} with CI cache (cache node_modules + ${lockFile}).` : 'Add a lockfile (npm ci) for repeatable installs.');
|
|
292
|
+
suggestions.push('Enable Jest/TS incremental caches with persistent cache directories in CI.');
|
|
293
|
+
suggestions.push('Reuse build artifacts between lint/test when possible (e.g., tsc --incremental).');
|
|
218
294
|
}
|
|
219
295
|
if (strategy === 'parallel' || strategy === 'all') {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
output.push('- Concurrent build steps');
|
|
223
|
-
output.push('- Worker pool optimization');
|
|
224
|
-
output.push('- Resource allocation');
|
|
296
|
+
suggestions.push('Run lint and tests in parallel jobs (matrix or background runs).');
|
|
297
|
+
suggestions.push('Prefer --maxWorkers for Jest/ts-jest to fully utilize CPUs.');
|
|
225
298
|
}
|
|
226
299
|
if (strategy === 'incremental' || strategy === 'all') {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
output.push('- Partial test execution');
|
|
300
|
+
suggestions.push('Use incremental TypeScript builds (tsc --incremental) and cache .tsbuildinfo.');
|
|
301
|
+
if (scripts['build']?.includes('--watch') || scripts['dev']?.includes('--watch')) {
|
|
302
|
+
suggestions.push('Adopt watch-mode for local dev to avoid full rebuilds.');
|
|
303
|
+
}
|
|
232
304
|
}
|
|
233
|
-
|
|
305
|
+
const output = [];
|
|
306
|
+
output.push('# Workflow Optimization Recommendations');
|
|
307
|
+
suggestions.forEach((s, idx) => output.push(`${idx + 1}. ${s}`));
|
|
308
|
+
if (!preview) {
|
|
309
|
+
const outDir = join(workingDir, '.intelligence');
|
|
310
|
+
mkdirSync(outDir, { recursive: true });
|
|
311
|
+
const outFile = join(outDir, 'workflow-optimizations.md');
|
|
312
|
+
writeFileSync(outFile, output.join('\n'), 'utf-8');
|
|
234
313
|
output.push('');
|
|
235
|
-
output.push(
|
|
314
|
+
output.push(`Recommendations saved to ${outFile}`);
|
|
236
315
|
}
|
|
237
316
|
return output.join('\n');
|
|
238
317
|
}
|
|
239
|
-
|
|
318
|
+
function generateWorkflowReport(workingDir, includeMetrics, includeRecommendations) {
|
|
319
|
+
const pkg = readPackageJson(workingDir);
|
|
320
|
+
const scripts = pkg?.['scripts'] ?? {};
|
|
321
|
+
const lockFile = detectLockfile(workingDir);
|
|
322
|
+
const hasCi = existsSync(join(workingDir, '.github', 'workflows')) || existsSync(join(workingDir, '.gitlab-ci.yml'));
|
|
240
323
|
const output = [];
|
|
241
324
|
output.push('# Development Workflow Report');
|
|
242
|
-
output.push('');
|
|
243
325
|
if (includeMetrics) {
|
|
244
|
-
output.push('##
|
|
245
|
-
output.push(
|
|
246
|
-
output.push(
|
|
247
|
-
output.push(
|
|
248
|
-
output.push('-
|
|
249
|
-
output.push('
|
|
326
|
+
output.push('## Script availability');
|
|
327
|
+
output.push(`- build: ${scripts['build'] ? 'present' : 'missing'}`);
|
|
328
|
+
output.push(`- test: ${scripts['test'] ? 'present' : 'missing'}`);
|
|
329
|
+
output.push(`- lint: ${scripts['lint'] ? 'present' : 'missing'}`);
|
|
330
|
+
output.push(`- quality: ${scripts['quality-gate'] || scripts['quality'] || scripts['quality-check'] || scripts['quality:check'] ? 'present' : 'missing'}`);
|
|
331
|
+
output.push('');
|
|
332
|
+
output.push(`Lockfile: ${lockFile ?? 'none detected'}`);
|
|
333
|
+
output.push(`CI config present: ${hasCi ? 'yes' : 'no'}`);
|
|
250
334
|
output.push('');
|
|
251
335
|
}
|
|
252
336
|
if (includeRecommendations) {
|
|
253
|
-
output.push('##
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
337
|
+
output.push('## Recommendations');
|
|
338
|
+
if (!scripts['build'])
|
|
339
|
+
output.push('- Add a build script to enforce consistent artifacts.');
|
|
340
|
+
if (!scripts['test'])
|
|
341
|
+
output.push('- Add a test script to unblock automation.');
|
|
342
|
+
if (!scripts['lint'])
|
|
343
|
+
output.push('- Add a lint script with ESLint/biome for static checks.');
|
|
344
|
+
if (!lockFile)
|
|
345
|
+
output.push('- Commit a lockfile and use npm ci/pnpm i --frozen-lockfile in CI.');
|
|
346
|
+
if (!hasCi)
|
|
347
|
+
output.push('- Add CI (see setup_ci_cd_workflow) for automated gates.');
|
|
260
348
|
}
|
|
261
|
-
output.push('## Quality Metrics');
|
|
262
|
-
output.push('- Code coverage: [percentage]');
|
|
263
|
-
output.push('- Complexity score: [score]');
|
|
264
|
-
output.push('- Lint warnings: [count]');
|
|
265
|
-
output.push('- Type safety: [score]');
|
|
266
|
-
output.push('- Maintainability: [score]');
|
|
267
349
|
return output.join('\n');
|
|
268
350
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
output.push('- Security vulnerability checks');
|
|
351
|
+
function detectLockfile(workingDir) {
|
|
352
|
+
if (existsSync(join(workingDir, 'package-lock.json')))
|
|
353
|
+
return 'package-lock.json';
|
|
354
|
+
if (existsSync(join(workingDir, 'pnpm-lock.yaml')))
|
|
355
|
+
return 'pnpm-lock.yaml';
|
|
356
|
+
if (existsSync(join(workingDir, 'yarn.lock')))
|
|
357
|
+
return 'yarn.lock';
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
function renderDuration(ms) {
|
|
361
|
+
return `${Math.round(ms)}ms`;
|
|
362
|
+
}
|
|
363
|
+
async function setupCiCdWorkflow(options) {
|
|
364
|
+
const pkg = readPackageJson(options.workingDir);
|
|
365
|
+
const scripts = pkg?.['scripts'] ?? {};
|
|
366
|
+
const lockFile = detectLockfile(options.workingDir);
|
|
367
|
+
// Currently generate GitHub Actions YAML; other platforms return guidance.
|
|
368
|
+
if (options.platform !== 'github') {
|
|
369
|
+
return `Only GitHub Actions scaffolding is implemented. For ${options.platform}, create equivalent jobs for install/build/test/lint.`;
|
|
289
370
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
371
|
+
const yaml = buildGithubWorkflowYaml({
|
|
372
|
+
scripts,
|
|
373
|
+
lockFile,
|
|
374
|
+
includeQualityGates: options.includeQualityGates,
|
|
375
|
+
includeDeployment: options.includeDeployment,
|
|
376
|
+
});
|
|
377
|
+
if (options.preview) {
|
|
378
|
+
return ['# GitHub Actions workflow (preview)', yaml].join('\n');
|
|
296
379
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
380
|
+
const workflowDir = join(options.workingDir, '.github', 'workflows');
|
|
381
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
382
|
+
const workflowPath = join(workflowDir, 'erosolar-ci.yml');
|
|
383
|
+
writeFileSync(workflowPath, yaml, 'utf-8');
|
|
384
|
+
return `Workflow written to ${workflowPath}`;
|
|
385
|
+
}
|
|
386
|
+
function buildGithubWorkflowYaml(options) {
|
|
387
|
+
const runInstall = options.lockFile === 'pnpm-lock.yaml'
|
|
388
|
+
? 'pnpm install --frozen-lockfile'
|
|
389
|
+
: options.lockFile === 'yarn.lock'
|
|
390
|
+
? 'yarn install --frozen-lockfile'
|
|
391
|
+
: 'npm ci';
|
|
392
|
+
const steps = [
|
|
393
|
+
'name: Erosolar CI',
|
|
394
|
+
'on:',
|
|
395
|
+
' push:',
|
|
396
|
+
' branches: [ main, master ]',
|
|
397
|
+
' pull_request:',
|
|
398
|
+
' branches: [ main, master ]',
|
|
399
|
+
'jobs:',
|
|
400
|
+
' build-test:',
|
|
401
|
+
' runs-on: ubuntu-latest',
|
|
402
|
+
' steps:',
|
|
403
|
+
' - uses: actions/checkout@v4',
|
|
404
|
+
' - uses: actions/setup-node@v4',
|
|
405
|
+
' with:',
|
|
406
|
+
' node-version: 20',
|
|
407
|
+
' cache: npm',
|
|
408
|
+
` - name: Install dependencies`,
|
|
409
|
+
` run: ${runInstall}`,
|
|
410
|
+
];
|
|
411
|
+
if (options.scripts['build']) {
|
|
412
|
+
steps.push(' - name: Build', ' run: npm run build');
|
|
300
413
|
}
|
|
301
|
-
|
|
414
|
+
if (options.scripts['test']) {
|
|
415
|
+
steps.push(' - name: Test', ' run: npm test');
|
|
416
|
+
}
|
|
417
|
+
if (options.scripts['lint']) {
|
|
418
|
+
steps.push(' - name: Lint', ' run: npm run lint');
|
|
419
|
+
}
|
|
420
|
+
if (options.includeQualityGates) {
|
|
421
|
+
const qualityScript = options.scripts['quality-gate'] || options.scripts['quality'] || options.scripts['quality-check'] || options.scripts['quality:check'];
|
|
422
|
+
if (qualityScript) {
|
|
423
|
+
steps.push(' - name: Quality Gate', ` run: npm run ${qualityScript}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (options.includeDeployment) {
|
|
427
|
+
steps.push(' - name: Deploy', ' run: echo "Add deployment steps here"');
|
|
428
|
+
}
|
|
429
|
+
return steps.join('\n');
|
|
302
430
|
}
|
|
303
431
|
//# sourceMappingURL=enhancedDevWorkflowTools.js.map
|