erosolar-cli 2.1.204 → 2.1.206
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/core/agent.js +1 -1
- package/dist/core/agent.js.map +1 -1
- package/dist/core/agentOrchestrator.d.ts +2 -2
- package/dist/core/agentOrchestrator.d.ts.map +1 -1
- package/dist/core/agentOrchestrator.js +32 -70
- package/dist/core/agentOrchestrator.js.map +1 -1
- package/dist/core/errors/errorTypes.d.ts +6 -0
- package/dist/core/errors/errorTypes.d.ts.map +1 -1
- package/dist/core/errors/errorTypes.js +18 -0
- package/dist/core/errors/errorTypes.js.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +0 -2
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +0 -4
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +2 -155
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/tools/editTools.js +8 -2
- package/dist/tools/editTools.js.map +1 -1
- package/dist/tools/repoChecksTools.d.ts.map +1 -1
- package/dist/tools/repoChecksTools.js +95 -27
- package/dist/tools/repoChecksTools.js.map +1 -1
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
- package/dist/ui/UnifiedUIRenderer.js +6 -3
- package/dist/ui/UnifiedUIRenderer.js.map +1 -1
- package/package.json +1 -1
- package/dist/capabilities/taoCapability.d.ts +0 -6
- package/dist/capabilities/taoCapability.d.ts.map +0 -1
- package/dist/capabilities/taoCapability.js +0 -20
- package/dist/capabilities/taoCapability.js.map +0 -1
- package/dist/core/alphaZeroModular.d.ts +0 -186
- package/dist/core/alphaZeroModular.d.ts.map +0 -1
- package/dist/core/alphaZeroModular.js +0 -755
- package/dist/core/alphaZeroModular.js.map +0 -1
- package/dist/plugins/tools/tao/taoPlugin.d.ts +0 -3
- package/dist/plugins/tools/tao/taoPlugin.d.ts.map +0 -1
- package/dist/plugins/tools/tao/taoPlugin.js +0 -10
- package/dist/plugins/tools/tao/taoPlugin.js.map +0 -1
- package/dist/tools/softwareEngineeringTools.d.ts +0 -7
- package/dist/tools/softwareEngineeringTools.d.ts.map +0 -1
- package/dist/tools/softwareEngineeringTools.js +0 -338
- package/dist/tools/softwareEngineeringTools.js.map +0 -1
- package/dist/tools/taoOperations.d.ts +0 -7
- package/dist/tools/taoOperations.d.ts.map +0 -1
- package/dist/tools/taoOperations.js +0 -744
- package/dist/tools/taoOperations.js.map +0 -1
|
@@ -1,755 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AlphaZero Modular Optimization System
|
|
3
|
-
*
|
|
4
|
-
* Enables self-improvement through modular targeting of:
|
|
5
|
-
* - Token count minimization
|
|
6
|
-
* - Context window optimization
|
|
7
|
-
* - Tool management (create/edit/delete)
|
|
8
|
-
* - Guideline and guardrail management
|
|
9
|
-
* - System prompt optimization
|
|
10
|
-
*
|
|
11
|
-
* Principal Investigator: Bo Shang
|
|
12
|
-
*/
|
|
13
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlinkSync } from 'node:fs';
|
|
14
|
-
import { join, relative, basename } from 'node:path';
|
|
15
|
-
import { homedir } from 'node:os';
|
|
16
|
-
// ============================================================================
|
|
17
|
-
// CONSTANTS
|
|
18
|
-
// ============================================================================
|
|
19
|
-
const MODULAR_STATE_FILE = join(homedir(), '.erosolar', 'modular-state.json');
|
|
20
|
-
const MODULAR_ACTIONS_FILE = join(homedir(), '.erosolar', 'modular-actions.json');
|
|
21
|
-
const TOOLS_DIR = 'src/tools';
|
|
22
|
-
const CAPABILITIES_DIR = 'src/capabilities';
|
|
23
|
-
const CORE_DIR = 'src/core';
|
|
24
|
-
const CONTRACTS_DIR = 'src/contracts';
|
|
25
|
-
// Token estimation (rough approximation: 1 token ≈ 4 chars for code)
|
|
26
|
-
const CHARS_PER_TOKEN = 4;
|
|
27
|
-
// Priority scores for different component types
|
|
28
|
-
const TYPE_PRIORITY = {
|
|
29
|
-
'guardrail': 100,
|
|
30
|
-
'system-prompt': 95,
|
|
31
|
-
'tool': 90,
|
|
32
|
-
'capability': 85,
|
|
33
|
-
'guideline': 80,
|
|
34
|
-
'schema': 70,
|
|
35
|
-
};
|
|
36
|
-
// ============================================================================
|
|
37
|
-
// TOKEN ANALYSIS
|
|
38
|
-
// ============================================================================
|
|
39
|
-
/**
|
|
40
|
-
* Estimate token count for a string
|
|
41
|
-
*/
|
|
42
|
-
export function estimateTokens(content) {
|
|
43
|
-
return Math.ceil(content.length / CHARS_PER_TOKEN);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Analyze token usage across the codebase
|
|
47
|
-
*/
|
|
48
|
-
export function analyzeTokenUsage(workingDir) {
|
|
49
|
-
const analysis = {
|
|
50
|
-
totalTokens: 0,
|
|
51
|
-
byCategory: {},
|
|
52
|
-
topConsumers: [],
|
|
53
|
-
optimizationOpportunities: [],
|
|
54
|
-
};
|
|
55
|
-
const categories = [
|
|
56
|
-
{ name: 'tools', dir: join(workingDir, TOOLS_DIR) },
|
|
57
|
-
{ name: 'capabilities', dir: join(workingDir, CAPABILITIES_DIR) },
|
|
58
|
-
{ name: 'core', dir: join(workingDir, CORE_DIR) },
|
|
59
|
-
{ name: 'contracts', dir: join(workingDir, CONTRACTS_DIR) },
|
|
60
|
-
];
|
|
61
|
-
const allFiles = [];
|
|
62
|
-
for (const category of categories) {
|
|
63
|
-
if (!existsSync(category.dir))
|
|
64
|
-
continue;
|
|
65
|
-
let categoryTokens = 0;
|
|
66
|
-
const files = findFilesRecursive(category.dir, ['.ts', '.json']);
|
|
67
|
-
for (const file of files) {
|
|
68
|
-
try {
|
|
69
|
-
const content = readFileSync(file, 'utf-8');
|
|
70
|
-
const tokens = estimateTokens(content);
|
|
71
|
-
categoryTokens += tokens;
|
|
72
|
-
allFiles.push({
|
|
73
|
-
name: basename(file),
|
|
74
|
-
tokens,
|
|
75
|
-
path: relative(workingDir, file),
|
|
76
|
-
category: category.name,
|
|
77
|
-
});
|
|
78
|
-
// Check for optimization opportunities
|
|
79
|
-
const opportunities = findOptimizationOpportunities(file, content, tokens);
|
|
80
|
-
analysis.optimizationOpportunities.push(...opportunities);
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// Skip unreadable files
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
analysis.byCategory[category.name] = categoryTokens;
|
|
87
|
-
analysis.totalTokens += categoryTokens;
|
|
88
|
-
}
|
|
89
|
-
// Sort by token count and get top consumers
|
|
90
|
-
allFiles.sort((a, b) => b.tokens - a.tokens);
|
|
91
|
-
analysis.topConsumers = allFiles.slice(0, 20);
|
|
92
|
-
// Sort opportunities by savings
|
|
93
|
-
analysis.optimizationOpportunities.sort((a, b) => b.savings - a.savings);
|
|
94
|
-
return analysis;
|
|
95
|
-
}
|
|
96
|
-
function findOptimizationOpportunities(filePath, content, tokens) {
|
|
97
|
-
const opportunities = [];
|
|
98
|
-
const fileName = basename(filePath);
|
|
99
|
-
// Check for verbose comments
|
|
100
|
-
const commentMatches = content.match(/\/\*\*[\s\S]*?\*\//g) || [];
|
|
101
|
-
const commentChars = commentMatches.reduce((sum, c) => sum + c.length, 0);
|
|
102
|
-
if (commentChars > content.length * 0.3) {
|
|
103
|
-
const savings = Math.floor(commentChars * 0.5 / CHARS_PER_TOKEN);
|
|
104
|
-
opportunities.push({
|
|
105
|
-
target: fileName,
|
|
106
|
-
currentTokens: tokens,
|
|
107
|
-
estimatedOptimized: tokens - savings,
|
|
108
|
-
savings,
|
|
109
|
-
savingsPercent: Math.round((savings / tokens) * 100),
|
|
110
|
-
strategy: 'Reduce verbose JSDoc comments - keep essential docs only',
|
|
111
|
-
autoFixable: false,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
// Check for duplicate code patterns
|
|
115
|
-
const lines = content.split('\n');
|
|
116
|
-
const lineSet = new Set();
|
|
117
|
-
let duplicates = 0;
|
|
118
|
-
for (const line of lines) {
|
|
119
|
-
const trimmed = line.trim();
|
|
120
|
-
if (trimmed.length > 20 && lineSet.has(trimmed)) {
|
|
121
|
-
duplicates++;
|
|
122
|
-
}
|
|
123
|
-
lineSet.add(trimmed);
|
|
124
|
-
}
|
|
125
|
-
if (duplicates > 10) {
|
|
126
|
-
const savings = Math.floor(duplicates * 15 / CHARS_PER_TOKEN);
|
|
127
|
-
opportunities.push({
|
|
128
|
-
target: fileName,
|
|
129
|
-
currentTokens: tokens,
|
|
130
|
-
estimatedOptimized: tokens - savings,
|
|
131
|
-
savings,
|
|
132
|
-
savingsPercent: Math.round((savings / tokens) * 100),
|
|
133
|
-
strategy: 'Extract duplicate code into shared utilities',
|
|
134
|
-
autoFixable: false,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
// Check for long string literals
|
|
138
|
-
const stringMatches = content.match(/'[^']{100,}'|"[^"]{100,}"|`[^`]{200,}`/g) || [];
|
|
139
|
-
if (stringMatches.length > 0) {
|
|
140
|
-
const stringChars = stringMatches.reduce((sum, s) => sum + s.length, 0);
|
|
141
|
-
const savings = Math.floor(stringChars * 0.3 / CHARS_PER_TOKEN);
|
|
142
|
-
if (savings > 50) {
|
|
143
|
-
opportunities.push({
|
|
144
|
-
target: fileName,
|
|
145
|
-
currentTokens: tokens,
|
|
146
|
-
estimatedOptimized: tokens - savings,
|
|
147
|
-
savings,
|
|
148
|
-
savingsPercent: Math.round((savings / tokens) * 100),
|
|
149
|
-
strategy: 'Move long strings to external files or templates',
|
|
150
|
-
autoFixable: false,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// Check for unused imports (simple heuristic)
|
|
155
|
-
const importMatches = content.match(/import\s+\{([^}]+)\}/g) || [];
|
|
156
|
-
for (const imp of importMatches) {
|
|
157
|
-
const imports = imp.match(/\{([^}]+)\}/)?.[1]?.split(',') || [];
|
|
158
|
-
for (const item of imports) {
|
|
159
|
-
const name = item.trim().split(/\s+as\s+/)[0]?.trim();
|
|
160
|
-
if (name && !content.includes(`${name}(`) && !content.includes(`${name}.`) &&
|
|
161
|
-
!content.includes(`: ${name}`) && !content.includes(`<${name}`)) {
|
|
162
|
-
// Potentially unused
|
|
163
|
-
opportunities.push({
|
|
164
|
-
target: fileName,
|
|
165
|
-
currentTokens: tokens,
|
|
166
|
-
estimatedOptimized: tokens - 5,
|
|
167
|
-
savings: 5,
|
|
168
|
-
savingsPercent: 0,
|
|
169
|
-
strategy: `Remove potentially unused import: ${name}`,
|
|
170
|
-
autoFixable: true,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return opportunities;
|
|
176
|
-
}
|
|
177
|
-
// ============================================================================
|
|
178
|
-
// MODULAR TARGET DISCOVERY
|
|
179
|
-
// ============================================================================
|
|
180
|
-
/**
|
|
181
|
-
* Discover all modular targets in the codebase
|
|
182
|
-
*/
|
|
183
|
-
export function discoverModularTargets(workingDir) {
|
|
184
|
-
const targets = [];
|
|
185
|
-
// Discover tools
|
|
186
|
-
const toolsDir = join(workingDir, TOOLS_DIR);
|
|
187
|
-
if (existsSync(toolsDir)) {
|
|
188
|
-
const toolFiles = findFilesRecursive(toolsDir, ['.ts']);
|
|
189
|
-
for (const file of toolFiles) {
|
|
190
|
-
const target = analyzeModularTarget(file, 'tool', workingDir);
|
|
191
|
-
if (target)
|
|
192
|
-
targets.push(target);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// Discover capabilities
|
|
196
|
-
const capsDir = join(workingDir, CAPABILITIES_DIR);
|
|
197
|
-
if (existsSync(capsDir)) {
|
|
198
|
-
const capFiles = findFilesRecursive(capsDir, ['.ts']);
|
|
199
|
-
for (const file of capFiles) {
|
|
200
|
-
const target = analyzeModularTarget(file, 'capability', workingDir);
|
|
201
|
-
if (target)
|
|
202
|
-
targets.push(target);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
// Discover schemas (guardrails, guidelines)
|
|
206
|
-
const contractsDir = join(workingDir, CONTRACTS_DIR);
|
|
207
|
-
if (existsSync(contractsDir)) {
|
|
208
|
-
const schemaFiles = findFilesRecursive(contractsDir, ['.json']);
|
|
209
|
-
for (const file of schemaFiles) {
|
|
210
|
-
const target = analyzeModularTarget(file, 'schema', workingDir);
|
|
211
|
-
if (target)
|
|
212
|
-
targets.push(target);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
// Discover agent rules (guardrails)
|
|
216
|
-
const agentsDir = join(workingDir, 'agents');
|
|
217
|
-
if (existsSync(agentsDir)) {
|
|
218
|
-
const ruleFiles = findFilesRecursive(agentsDir, ['.json']);
|
|
219
|
-
for (const file of ruleFiles) {
|
|
220
|
-
const target = analyzeModularTarget(file, 'guardrail', workingDir);
|
|
221
|
-
if (target)
|
|
222
|
-
targets.push(target);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
// Sort by priority
|
|
226
|
-
targets.sort((a, b) => b.priority - a.priority);
|
|
227
|
-
return targets;
|
|
228
|
-
}
|
|
229
|
-
function analyzeModularTarget(filePath, type, workingDir) {
|
|
230
|
-
try {
|
|
231
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
232
|
-
const stats = require('fs').statSync(filePath);
|
|
233
|
-
const tokens = estimateTokens(content);
|
|
234
|
-
const relativePath = relative(workingDir, filePath);
|
|
235
|
-
const name = basename(filePath, '.ts').replace('.json', '');
|
|
236
|
-
const issues = findModularIssues(content, type, name);
|
|
237
|
-
return {
|
|
238
|
-
id: relativePath.replace(/[/\\]/g, '_'),
|
|
239
|
-
type,
|
|
240
|
-
name,
|
|
241
|
-
path: relativePath,
|
|
242
|
-
tokenCount: tokens,
|
|
243
|
-
priority: TYPE_PRIORITY[type] || 50,
|
|
244
|
-
lastModified: stats.mtime.toISOString(),
|
|
245
|
-
issues,
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
catch {
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function findModularIssues(content, type, name) {
|
|
253
|
-
const issues = [];
|
|
254
|
-
const tokens = estimateTokens(content);
|
|
255
|
-
// Token bloat detection
|
|
256
|
-
if (type === 'tool' && tokens > 500) {
|
|
257
|
-
issues.push({
|
|
258
|
-
type: 'token-bloat',
|
|
259
|
-
severity: tokens > 1000 ? 'high' : 'medium',
|
|
260
|
-
description: `Tool has ${tokens} tokens, consider splitting`,
|
|
261
|
-
suggestedAction: 'Split into smaller focused tools',
|
|
262
|
-
potentialSavings: Math.floor(tokens * 0.3),
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
// Redundancy detection (similar patterns)
|
|
266
|
-
if (content.includes('// TODO') || content.includes('// FIXME')) {
|
|
267
|
-
issues.push({
|
|
268
|
-
type: 'outdated',
|
|
269
|
-
severity: 'low',
|
|
270
|
-
description: 'Contains TODO/FIXME markers',
|
|
271
|
-
suggestedAction: 'Address or remove TODO markers',
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
// Check for deprecated patterns
|
|
275
|
-
if (content.includes('@deprecated') || content.includes('DEPRECATED')) {
|
|
276
|
-
issues.push({
|
|
277
|
-
type: 'outdated',
|
|
278
|
-
severity: 'high',
|
|
279
|
-
description: 'Contains deprecated code',
|
|
280
|
-
suggestedAction: 'Remove or update deprecated code',
|
|
281
|
-
potentialSavings: 50,
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
// Check for overly complex schemas
|
|
285
|
-
if (type === 'schema' && tokens > 2000) {
|
|
286
|
-
issues.push({
|
|
287
|
-
type: 'token-bloat',
|
|
288
|
-
severity: 'high',
|
|
289
|
-
description: `Schema has ${tokens} tokens - very large`,
|
|
290
|
-
suggestedAction: 'Split schema into smaller modules',
|
|
291
|
-
potentialSavings: Math.floor(tokens * 0.4),
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
// Check for missing documentation
|
|
295
|
-
if (type === 'tool' && !content.includes('description:') && !content.includes('@description')) {
|
|
296
|
-
issues.push({
|
|
297
|
-
type: 'missing',
|
|
298
|
-
severity: 'medium',
|
|
299
|
-
description: 'Tool lacks description',
|
|
300
|
-
suggestedAction: 'Add clear description for tool',
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
return issues;
|
|
304
|
-
}
|
|
305
|
-
// ============================================================================
|
|
306
|
-
// TOOL MANAGEMENT
|
|
307
|
-
// ============================================================================
|
|
308
|
-
/**
|
|
309
|
-
* Create a new tool
|
|
310
|
-
*/
|
|
311
|
-
export function createTool(workingDir, definition) {
|
|
312
|
-
const toolsDir = join(workingDir, TOOLS_DIR);
|
|
313
|
-
if (!existsSync(toolsDir)) {
|
|
314
|
-
return { success: false, error: 'Tools directory not found' };
|
|
315
|
-
}
|
|
316
|
-
const fileName = `${definition.name.replace(/Tool$/, '')}Tools.ts`;
|
|
317
|
-
const filePath = join(toolsDir, fileName);
|
|
318
|
-
if (existsSync(filePath)) {
|
|
319
|
-
return { success: false, error: `Tool file already exists: ${fileName}` };
|
|
320
|
-
}
|
|
321
|
-
const toolCode = generateToolCode(definition);
|
|
322
|
-
try {
|
|
323
|
-
writeFileSync(filePath, toolCode);
|
|
324
|
-
return { success: true, path: filePath };
|
|
325
|
-
}
|
|
326
|
-
catch (error) {
|
|
327
|
-
return { success: false, error: String(error) };
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
function generateToolCode(def) {
|
|
331
|
-
return `/**
|
|
332
|
-
* ${def.name}
|
|
333
|
-
* ${def.description}
|
|
334
|
-
*
|
|
335
|
-
* Auto-generated by AlphaZero Modular System
|
|
336
|
-
*/
|
|
337
|
-
|
|
338
|
-
import type { ToolDefinition } from '../core/toolRuntime.js';
|
|
339
|
-
|
|
340
|
-
export const ${def.name}: ToolDefinition = {
|
|
341
|
-
name: '${def.name}',
|
|
342
|
-
description: '${def.description}',
|
|
343
|
-
inputSchema: ${JSON.stringify(def.inputSchema, null, 2)},
|
|
344
|
-
handler: async (input, context) => {
|
|
345
|
-
// TODO: Implement tool logic
|
|
346
|
-
return {
|
|
347
|
-
success: true,
|
|
348
|
-
result: 'Tool executed successfully',
|
|
349
|
-
};
|
|
350
|
-
},
|
|
351
|
-
};
|
|
352
|
-
`;
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Edit an existing tool
|
|
356
|
-
*/
|
|
357
|
-
export function editTool(workingDir, toolPath, changes) {
|
|
358
|
-
const fullPath = join(workingDir, toolPath);
|
|
359
|
-
if (!existsSync(fullPath)) {
|
|
360
|
-
return { success: false, error: 'Tool file not found' };
|
|
361
|
-
}
|
|
362
|
-
try {
|
|
363
|
-
let content = readFileSync(fullPath, 'utf-8');
|
|
364
|
-
if (changes.description) {
|
|
365
|
-
content = content.replace(/description:\s*['"`][^'"`]*['"`]/, `description: '${changes.description}'`);
|
|
366
|
-
}
|
|
367
|
-
if (changes.inputSchema) {
|
|
368
|
-
// More complex - need to find and replace the schema
|
|
369
|
-
const schemaStr = JSON.stringify(changes.inputSchema, null, 2);
|
|
370
|
-
content = content.replace(/inputSchema:\s*\{[\s\S]*?\n\s*\}/, `inputSchema: ${schemaStr}`);
|
|
371
|
-
}
|
|
372
|
-
writeFileSync(fullPath, content);
|
|
373
|
-
return { success: true };
|
|
374
|
-
}
|
|
375
|
-
catch (error) {
|
|
376
|
-
return { success: false, error: String(error) };
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Delete a tool
|
|
381
|
-
*/
|
|
382
|
-
export function deleteTool(workingDir, toolPath) {
|
|
383
|
-
const fullPath = join(workingDir, toolPath);
|
|
384
|
-
if (!existsSync(fullPath)) {
|
|
385
|
-
return { success: false, error: 'Tool file not found' };
|
|
386
|
-
}
|
|
387
|
-
try {
|
|
388
|
-
const rollbackData = readFileSync(fullPath, 'utf-8');
|
|
389
|
-
unlinkSync(fullPath);
|
|
390
|
-
return { success: true, rollbackData };
|
|
391
|
-
}
|
|
392
|
-
catch (error) {
|
|
393
|
-
return { success: false, error: String(error) };
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
// ============================================================================
|
|
397
|
-
// GUIDELINE MANAGEMENT
|
|
398
|
-
// ============================================================================
|
|
399
|
-
const GUIDELINES_FILE = join(homedir(), '.erosolar', 'guidelines.json');
|
|
400
|
-
/**
|
|
401
|
-
* Get all guidelines
|
|
402
|
-
*/
|
|
403
|
-
export function getGuidelines() {
|
|
404
|
-
try {
|
|
405
|
-
if (existsSync(GUIDELINES_FILE)) {
|
|
406
|
-
return JSON.parse(readFileSync(GUIDELINES_FILE, 'utf-8'));
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
catch {
|
|
410
|
-
// Ignore
|
|
411
|
-
}
|
|
412
|
-
return getDefaultGuidelines();
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Add a new guideline
|
|
416
|
-
*/
|
|
417
|
-
export function addGuideline(guideline) {
|
|
418
|
-
try {
|
|
419
|
-
const guidelines = getGuidelines();
|
|
420
|
-
if (guidelines.some(g => g.id === guideline.id)) {
|
|
421
|
-
return { success: false, error: 'Guideline with this ID already exists' };
|
|
422
|
-
}
|
|
423
|
-
guidelines.push(guideline);
|
|
424
|
-
saveGuidelines(guidelines);
|
|
425
|
-
return { success: true };
|
|
426
|
-
}
|
|
427
|
-
catch (error) {
|
|
428
|
-
return { success: false, error: String(error) };
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Update a guideline
|
|
433
|
-
*/
|
|
434
|
-
export function updateGuideline(id, updates) {
|
|
435
|
-
try {
|
|
436
|
-
const guidelines = getGuidelines();
|
|
437
|
-
const index = guidelines.findIndex(g => g.id === id);
|
|
438
|
-
if (index === -1) {
|
|
439
|
-
return { success: false, error: 'Guideline not found' };
|
|
440
|
-
}
|
|
441
|
-
guidelines[index] = { ...guidelines[index], ...updates };
|
|
442
|
-
saveGuidelines(guidelines);
|
|
443
|
-
return { success: true };
|
|
444
|
-
}
|
|
445
|
-
catch (error) {
|
|
446
|
-
return { success: false, error: String(error) };
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* Delete a guideline
|
|
451
|
-
*/
|
|
452
|
-
export function deleteGuideline(id) {
|
|
453
|
-
try {
|
|
454
|
-
const guidelines = getGuidelines();
|
|
455
|
-
const filtered = guidelines.filter(g => g.id !== id);
|
|
456
|
-
if (filtered.length === guidelines.length) {
|
|
457
|
-
return { success: false, error: 'Guideline not found' };
|
|
458
|
-
}
|
|
459
|
-
saveGuidelines(filtered);
|
|
460
|
-
return { success: true };
|
|
461
|
-
}
|
|
462
|
-
catch (error) {
|
|
463
|
-
return { success: false, error: String(error) };
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
function saveGuidelines(guidelines) {
|
|
467
|
-
const dir = join(homedir(), '.erosolar');
|
|
468
|
-
if (!existsSync(dir)) {
|
|
469
|
-
mkdirSync(dir, { recursive: true });
|
|
470
|
-
}
|
|
471
|
-
writeFileSync(GUIDELINES_FILE, JSON.stringify(guidelines, null, 2));
|
|
472
|
-
}
|
|
473
|
-
function getDefaultGuidelines() {
|
|
474
|
-
return [
|
|
475
|
-
{
|
|
476
|
-
id: 'token-efficiency',
|
|
477
|
-
category: 'performance',
|
|
478
|
-
rule: 'Minimize token usage while maintaining clarity',
|
|
479
|
-
rationale: 'Reduces costs and improves response times',
|
|
480
|
-
severity: 'should',
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
id: 'modular-design',
|
|
484
|
-
category: 'quality',
|
|
485
|
-
rule: 'Keep tools and capabilities small and focused',
|
|
486
|
-
rationale: 'Improves maintainability and reusability',
|
|
487
|
-
severity: 'should',
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
id: 'safety-first',
|
|
491
|
-
category: 'safety',
|
|
492
|
-
rule: 'Always validate inputs and handle errors gracefully',
|
|
493
|
-
rationale: 'Prevents security issues and crashes',
|
|
494
|
-
severity: 'must',
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
id: 'documentation',
|
|
498
|
-
category: 'quality',
|
|
499
|
-
rule: 'Document public APIs and complex logic',
|
|
500
|
-
rationale: 'Helps with maintenance and onboarding',
|
|
501
|
-
severity: 'should',
|
|
502
|
-
},
|
|
503
|
-
];
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Generate context optimization strategies
|
|
507
|
-
*/
|
|
508
|
-
export function generateContextOptimizations(workingDir) {
|
|
509
|
-
const optimizations = [];
|
|
510
|
-
const analysis = analyzeTokenUsage(workingDir);
|
|
511
|
-
// Strategy 1: Lazy loading for large tools
|
|
512
|
-
const largeTools = analysis.topConsumers.filter(t => t.tokens > 500 && t.path.includes('tools'));
|
|
513
|
-
if (largeTools.length > 0) {
|
|
514
|
-
const savings = largeTools.reduce((sum, t) => sum + Math.floor(t.tokens * 0.7), 0);
|
|
515
|
-
optimizations.push({
|
|
516
|
-
strategy: 'lazy-loading',
|
|
517
|
-
description: `Lazy load ${largeTools.length} large tools`,
|
|
518
|
-
impact: 'high',
|
|
519
|
-
tokensSaved: savings,
|
|
520
|
-
implementation: 'Load tools on-demand instead of at startup',
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
// Strategy 2: Schema compression
|
|
524
|
-
const schemas = analysis.topConsumers.filter(t => t.path.includes('.json'));
|
|
525
|
-
if (schemas.length > 0) {
|
|
526
|
-
const savings = schemas.reduce((sum, s) => sum + Math.floor(s.tokens * 0.3), 0);
|
|
527
|
-
optimizations.push({
|
|
528
|
-
strategy: 'schema-compression',
|
|
529
|
-
description: 'Compress JSON schemas by removing optional fields',
|
|
530
|
-
impact: 'medium',
|
|
531
|
-
tokensSaved: savings,
|
|
532
|
-
implementation: 'Minimize schemas to required fields only',
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
// Strategy 3: Comment stripping for production
|
|
536
|
-
const totalCommentSavings = Math.floor(analysis.totalTokens * 0.1);
|
|
537
|
-
optimizations.push({
|
|
538
|
-
strategy: 'comment-stripping',
|
|
539
|
-
description: 'Strip non-essential comments in production',
|
|
540
|
-
impact: 'medium',
|
|
541
|
-
tokensSaved: totalCommentSavings,
|
|
542
|
-
implementation: 'Build step to remove verbose comments',
|
|
543
|
-
});
|
|
544
|
-
// Strategy 4: Code deduplication
|
|
545
|
-
optimizations.push({
|
|
546
|
-
strategy: 'deduplication',
|
|
547
|
-
description: 'Extract common patterns into shared utilities',
|
|
548
|
-
impact: 'medium',
|
|
549
|
-
tokensSaved: Math.floor(analysis.totalTokens * 0.05),
|
|
550
|
-
implementation: 'Create shared utils for repeated patterns',
|
|
551
|
-
});
|
|
552
|
-
// Strategy 5: Dynamic import chunking
|
|
553
|
-
optimizations.push({
|
|
554
|
-
strategy: 'dynamic-imports',
|
|
555
|
-
description: 'Split rarely-used features into dynamic imports',
|
|
556
|
-
impact: 'high',
|
|
557
|
-
tokensSaved: Math.floor(analysis.totalTokens * 0.15),
|
|
558
|
-
implementation: 'Use import() for optional features',
|
|
559
|
-
});
|
|
560
|
-
// Sort by impact
|
|
561
|
-
optimizations.sort((a, b) => {
|
|
562
|
-
const impactOrder = { high: 0, medium: 1, low: 2 };
|
|
563
|
-
return impactOrder[a.impact] - impactOrder[b.impact];
|
|
564
|
-
});
|
|
565
|
-
return optimizations;
|
|
566
|
-
}
|
|
567
|
-
// ============================================================================
|
|
568
|
-
// MODULAR ACTIONS
|
|
569
|
-
// ============================================================================
|
|
570
|
-
let pendingActions = [];
|
|
571
|
-
/**
|
|
572
|
-
* Queue a modular action for execution
|
|
573
|
-
*/
|
|
574
|
-
export function queueModularAction(action) {
|
|
575
|
-
pendingActions.push({
|
|
576
|
-
...action,
|
|
577
|
-
approved: false,
|
|
578
|
-
executed: false,
|
|
579
|
-
});
|
|
580
|
-
savePendingActions();
|
|
581
|
-
}
|
|
582
|
-
/**
|
|
583
|
-
* Get pending actions
|
|
584
|
-
*/
|
|
585
|
-
export function getPendingActions() {
|
|
586
|
-
try {
|
|
587
|
-
if (existsSync(MODULAR_ACTIONS_FILE)) {
|
|
588
|
-
pendingActions = JSON.parse(readFileSync(MODULAR_ACTIONS_FILE, 'utf-8'));
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
catch {
|
|
592
|
-
// Ignore
|
|
593
|
-
}
|
|
594
|
-
return pendingActions.filter(a => !a.executed);
|
|
595
|
-
}
|
|
596
|
-
/**
|
|
597
|
-
* Approve and execute a pending action
|
|
598
|
-
*/
|
|
599
|
-
export function executeModularAction(actionIndex, workingDir) {
|
|
600
|
-
const actions = getPendingActions();
|
|
601
|
-
const action = actions[actionIndex];
|
|
602
|
-
if (!action) {
|
|
603
|
-
return { success: false, error: 'Action not found' };
|
|
604
|
-
}
|
|
605
|
-
action.approved = true;
|
|
606
|
-
try {
|
|
607
|
-
switch (action.type) {
|
|
608
|
-
case 'delete':
|
|
609
|
-
const deleteResult = deleteTool(workingDir, action.target.path);
|
|
610
|
-
if (!deleteResult.success)
|
|
611
|
-
return deleteResult;
|
|
612
|
-
action.rollbackData = deleteResult.rollbackData;
|
|
613
|
-
break;
|
|
614
|
-
case 'optimize':
|
|
615
|
-
// Optimization would require more complex logic
|
|
616
|
-
break;
|
|
617
|
-
case 'merge':
|
|
618
|
-
// Merge logic
|
|
619
|
-
break;
|
|
620
|
-
default:
|
|
621
|
-
break;
|
|
622
|
-
}
|
|
623
|
-
action.executed = true;
|
|
624
|
-
savePendingActions();
|
|
625
|
-
return { success: true };
|
|
626
|
-
}
|
|
627
|
-
catch (error) {
|
|
628
|
-
return { success: false, error: String(error) };
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Rollback an executed action
|
|
633
|
-
*/
|
|
634
|
-
export function rollbackModularAction(actionIndex, workingDir) {
|
|
635
|
-
const actions = pendingActions;
|
|
636
|
-
const action = actions[actionIndex];
|
|
637
|
-
if (!action || !action.executed) {
|
|
638
|
-
return { success: false, error: 'Action not found or not executed' };
|
|
639
|
-
}
|
|
640
|
-
if (!action.rollbackData) {
|
|
641
|
-
return { success: false, error: 'No rollback data available' };
|
|
642
|
-
}
|
|
643
|
-
try {
|
|
644
|
-
if (action.type === 'delete') {
|
|
645
|
-
writeFileSync(join(workingDir, action.target.path), action.rollbackData);
|
|
646
|
-
}
|
|
647
|
-
action.executed = false;
|
|
648
|
-
savePendingActions();
|
|
649
|
-
return { success: true };
|
|
650
|
-
}
|
|
651
|
-
catch (error) {
|
|
652
|
-
return { success: false, error: String(error) };
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
function savePendingActions() {
|
|
656
|
-
const dir = join(homedir(), '.erosolar');
|
|
657
|
-
if (!existsSync(dir)) {
|
|
658
|
-
mkdirSync(dir, { recursive: true });
|
|
659
|
-
}
|
|
660
|
-
writeFileSync(MODULAR_ACTIONS_FILE, JSON.stringify(pendingActions, null, 2));
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Get overall modular system status
|
|
664
|
-
*/
|
|
665
|
-
export function getModularStatus(workingDir) {
|
|
666
|
-
const targets = discoverModularTargets(workingDir);
|
|
667
|
-
const analysis = analyzeTokenUsage(workingDir);
|
|
668
|
-
const guidelines = getGuidelines();
|
|
669
|
-
const actions = getPendingActions();
|
|
670
|
-
const issuesByType = {};
|
|
671
|
-
for (const target of targets) {
|
|
672
|
-
for (const issue of target.issues) {
|
|
673
|
-
issuesByType[issue.type] = (issuesByType[issue.type] || 0) + 1;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
const optimizationPotential = analysis.optimizationOpportunities.reduce((sum, o) => sum + o.savings, 0);
|
|
677
|
-
return {
|
|
678
|
-
totalTargets: targets.length,
|
|
679
|
-
totalTokens: analysis.totalTokens,
|
|
680
|
-
issuesByType,
|
|
681
|
-
optimizationPotential,
|
|
682
|
-
pendingActions: actions.length,
|
|
683
|
-
guidelines: guidelines.length,
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Get formatted status display
|
|
688
|
-
*/
|
|
689
|
-
export function getModularStatusDisplay(workingDir) {
|
|
690
|
-
const status = getModularStatus(workingDir);
|
|
691
|
-
const analysis = analyzeTokenUsage(workingDir);
|
|
692
|
-
const lines = [];
|
|
693
|
-
lines.push('═══════════════════════════════════════════════════════════');
|
|
694
|
-
lines.push(' 🧩 AlphaZero Modular Optimization System');
|
|
695
|
-
lines.push('═══════════════════════════════════════════════════════════');
|
|
696
|
-
lines.push('');
|
|
697
|
-
lines.push(`Total Modular Targets: ${status.totalTargets}`);
|
|
698
|
-
lines.push(`Total Tokens: ${status.totalTokens.toLocaleString()}`);
|
|
699
|
-
lines.push(`Optimization Potential: ${status.optimizationPotential.toLocaleString()} tokens`);
|
|
700
|
-
lines.push('');
|
|
701
|
-
lines.push('Token Usage by Category:');
|
|
702
|
-
for (const [category, tokens] of Object.entries(analysis.byCategory)) {
|
|
703
|
-
const pct = ((tokens / status.totalTokens) * 100).toFixed(1);
|
|
704
|
-
lines.push(` ${category}: ${tokens.toLocaleString()} (${pct}%)`);
|
|
705
|
-
}
|
|
706
|
-
lines.push('');
|
|
707
|
-
if (Object.keys(status.issuesByType).length > 0) {
|
|
708
|
-
lines.push('Issues Found:');
|
|
709
|
-
for (const [type, count] of Object.entries(status.issuesByType)) {
|
|
710
|
-
lines.push(` ${type}: ${count}`);
|
|
711
|
-
}
|
|
712
|
-
lines.push('');
|
|
713
|
-
}
|
|
714
|
-
lines.push(`Pending Actions: ${status.pendingActions}`);
|
|
715
|
-
lines.push(`Active Guidelines: ${status.guidelines}`);
|
|
716
|
-
lines.push('');
|
|
717
|
-
lines.push('Top Token Consumers:');
|
|
718
|
-
for (const consumer of analysis.topConsumers.slice(0, 5)) {
|
|
719
|
-
lines.push(` ${consumer.tokens.toLocaleString().padStart(6)} | ${consumer.path}`);
|
|
720
|
-
}
|
|
721
|
-
lines.push('');
|
|
722
|
-
lines.push('Commands:');
|
|
723
|
-
lines.push(' /modular status - Show this status');
|
|
724
|
-
lines.push(' /modular analyze - Analyze optimization opportunities');
|
|
725
|
-
lines.push(' /modular targets - List all modular targets');
|
|
726
|
-
lines.push(' /modular guidelines - Manage guidelines');
|
|
727
|
-
lines.push(' /modular optimize - Apply optimizations');
|
|
728
|
-
lines.push('');
|
|
729
|
-
lines.push('═══════════════════════════════════════════════════════════');
|
|
730
|
-
return lines.join('\n');
|
|
731
|
-
}
|
|
732
|
-
// ============================================================================
|
|
733
|
-
// HELPERS
|
|
734
|
-
// ============================================================================
|
|
735
|
-
function findFilesRecursive(dir, extensions) {
|
|
736
|
-
const files = [];
|
|
737
|
-
try {
|
|
738
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
739
|
-
for (const entry of entries) {
|
|
740
|
-
const fullPath = join(dir, entry.name);
|
|
741
|
-
if (entry.isDirectory() && !entry.name.startsWith('.') &&
|
|
742
|
-
entry.name !== 'node_modules' && entry.name !== 'dist') {
|
|
743
|
-
files.push(...findFilesRecursive(fullPath, extensions));
|
|
744
|
-
}
|
|
745
|
-
else if (entry.isFile() && extensions.some(ext => entry.name.endsWith(ext))) {
|
|
746
|
-
files.push(fullPath);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
catch {
|
|
751
|
-
// Ignore
|
|
752
|
-
}
|
|
753
|
-
return files;
|
|
754
|
-
}
|
|
755
|
-
//# sourceMappingURL=alphaZeroModular.js.map
|