@gotza02/sequential-thinking 10000.1.6 → 10000.1.8

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.
Files changed (41) hide show
  1. package/CLAUDE.md +31 -6
  2. package/README.md +20 -1
  3. package/dist/analyzers/ComplexityCalculator.d.ts +15 -0
  4. package/dist/analyzers/ComplexityCalculator.js +59 -0
  5. package/dist/analyzers/QualityAnalyzer.d.ts +25 -0
  6. package/dist/analyzers/QualityAnalyzer.js +89 -0
  7. package/dist/analyzers/RefactoringEngine.d.ts +20 -0
  8. package/dist/analyzers/RefactoringEngine.js +107 -0
  9. package/dist/analyzers/SymbolAnalyzer.d.ts +30 -0
  10. package/dist/analyzers/SymbolAnalyzer.js +123 -0
  11. package/dist/analyzers/index.d.ts +8 -0
  12. package/dist/analyzers/index.js +4 -0
  13. package/dist/coding.test.js +4 -0
  14. package/dist/dashboard/index.html +95 -0
  15. package/dist/dashboard/server.js +97 -0
  16. package/dist/graph.d.ts +0 -6
  17. package/dist/graph.js +9 -265
  18. package/dist/index.js +2 -0
  19. package/dist/intelligent-code.d.ts +91 -0
  20. package/dist/intelligent-code.js +425 -0
  21. package/dist/lib.d.ts +42 -0
  22. package/dist/lib.js +308 -237
  23. package/dist/parsers/GenericParser.d.ts +6 -0
  24. package/dist/parsers/GenericParser.js +52 -0
  25. package/dist/parsers/GoParser.d.ts +6 -0
  26. package/dist/parsers/GoParser.js +36 -0
  27. package/dist/parsers/JavaParser.d.ts +6 -0
  28. package/dist/parsers/JavaParser.js +32 -0
  29. package/dist/parsers/PythonParser.d.ts +6 -0
  30. package/dist/parsers/PythonParser.js +50 -0
  31. package/dist/parsers/RustParser.d.ts +6 -0
  32. package/dist/parsers/RustParser.js +33 -0
  33. package/dist/parsers/TypeScriptParser.d.ts +9 -0
  34. package/dist/parsers/TypeScriptParser.js +85 -0
  35. package/dist/parsers/index.d.ts +7 -0
  36. package/dist/parsers/index.js +6 -0
  37. package/dist/tools/intelligent-code.d.ts +7 -0
  38. package/dist/tools/intelligent-code.js +387 -0
  39. package/dist/tools/sports/tools/match.js +221 -166
  40. package/dist/tools/web.js +4 -1
  41. package/package.json +1 -1
@@ -0,0 +1,425 @@
1
+ /**
2
+ * INTELLIGENT CODE MODULE
3
+ * AI-powered code analysis, semantic search, and smart refactoring
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import ts from 'typescript';
10
+ import { validatePath } from './utils.js';
11
+ import { complexityCalculator, qualityAnalyzer, symbolAnalyzer, refactoringEngine } from './analyzers/index.js';
12
+ const execAsync = promisify(exec);
13
+ // ============= Intelligent Code Analyzer =============
14
+ export class IntelligentCodeAnalyzer {
15
+ graph;
16
+ program;
17
+ typeChecker;
18
+ constructor(graph) {
19
+ this.graph = graph;
20
+ }
21
+ /**
22
+ * Comprehensive code analysis with metrics and quality scoring
23
+ */
24
+ async analyzeFile(filePath) {
25
+ const absolutePath = validatePath(filePath);
26
+ const content = await fs.readFile(absolutePath, 'utf-8');
27
+ // Parse AST
28
+ const sourceFile = ts.createSourceFile(absolutePath, content, ts.ScriptTarget.Latest, true);
29
+ // Calculate metrics using extracted analyzer
30
+ const metrics = complexityCalculator.calculate(sourceFile, content);
31
+ // Analyze quality using extracted analyzer
32
+ const quality = await qualityAnalyzer.analyze(sourceFile, content, metrics);
33
+ // Extract symbols with analysis using extracted analyzer
34
+ const symbols = symbolAnalyzer.analyze(sourceFile);
35
+ return { metrics, quality, ast: sourceFile, symbols };
36
+ }
37
+ /**
38
+ * Smart impact analysis - predicts what will be affected by changes
39
+ */
40
+ async analyzeImpact(filePath, changeDescription) {
41
+ const absolutePath = validatePath(filePath);
42
+ // Get graph relationships
43
+ const context = this.graph.getDeepContext(filePath);
44
+ if (!context) {
45
+ await this.graph.build(process.cwd());
46
+ }
47
+ const relationships = this.graph.getRelationships(filePath);
48
+ if (!relationships) {
49
+ return {
50
+ filePath,
51
+ directImpacts: [],
52
+ indirectImpacts: [],
53
+ testFiles: [],
54
+ riskScore: 0,
55
+ breakingChanges: false,
56
+ estimatedReviewTime: 0,
57
+ };
58
+ }
59
+ // Direct impacts: files that import this file
60
+ const directImpacts = relationships.importedBy;
61
+ // Find indirect impacts (files that import the direct impacts)
62
+ const indirectImpacts = [];
63
+ for (const directFile of directImpacts) {
64
+ const directRel = this.graph.getRelationships(directFile);
65
+ if (directRel) {
66
+ for (const indirect of directRel.importedBy) {
67
+ if (indirect !== filePath && !directImpacts.includes(indirect)) {
68
+ indirectImpacts.push(indirect);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ // Find related test files
74
+ const testFiles = await this.findRelatedTests(filePath);
75
+ // Calculate risk score
76
+ let riskScore = 0;
77
+ // Base risk from number of dependents
78
+ riskScore += directImpacts.length * 10;
79
+ riskScore += indirectImpacts.length * 5;
80
+ // Higher risk if changing public API
81
+ if (relationships.symbols.some(s => s.includes('export'))) {
82
+ riskScore += 20;
83
+ }
84
+ // Check change description for risky keywords
85
+ if (changeDescription) {
86
+ const riskyKeywords = ['delete', 'remove', 'rename', 'breaking', 'api'];
87
+ if (riskyKeywords.some(k => changeDescription.toLowerCase().includes(k))) {
88
+ riskScore += 15;
89
+ }
90
+ }
91
+ const breakingChanges = riskScore > 50;
92
+ const estimatedReviewTime = Math.min(120, 5 + directImpacts.length * 2 + indirectImpacts.length + testFiles.length * 3);
93
+ return {
94
+ filePath,
95
+ directImpacts,
96
+ indirectImpacts: [...new Set(indirectImpacts)],
97
+ testFiles,
98
+ riskScore: Math.min(100, riskScore),
99
+ breakingChanges,
100
+ estimatedReviewTime,
101
+ };
102
+ }
103
+ async findRelatedTests(filePath) {
104
+ const testFiles = [];
105
+ const baseName = path.basename(filePath, path.extname(filePath));
106
+ const dir = path.dirname(filePath);
107
+ // Common test file patterns
108
+ const patterns = [
109
+ `${baseName}.test.ts`,
110
+ `${baseName}.spec.ts`,
111
+ `${baseName}.test.js`,
112
+ `${baseName}.spec.js`,
113
+ ];
114
+ for (const pattern of patterns) {
115
+ const testPath = path.join(dir, pattern);
116
+ try {
117
+ await fs.access(testPath);
118
+ testFiles.push(testPath);
119
+ }
120
+ catch {
121
+ // File doesn't exist
122
+ }
123
+ }
124
+ // Check for __tests__ directory
125
+ const testsDir = path.join(dir, '__tests__');
126
+ try {
127
+ const files = await fs.readdir(testsDir);
128
+ files.forEach(f => {
129
+ if (f.includes(baseName) && (f.endsWith('.test.ts') || f.endsWith('.spec.ts'))) {
130
+ testFiles.push(path.join(testsDir, f));
131
+ }
132
+ });
133
+ }
134
+ catch {
135
+ // Directory doesn't exist
136
+ }
137
+ return testFiles;
138
+ }
139
+ /**
140
+ * Generate intelligent refactoring suggestions
141
+ */
142
+ async suggestRefactoring(filePath) {
143
+ const { ast, metrics } = await this.analyzeFile(filePath);
144
+ if (!ast)
145
+ return [];
146
+ // Use refactoring engine to generate suggestions
147
+ return refactoringEngine.suggest(ast, metrics);
148
+ }
149
+ /**
150
+ * Semantic code search - find code by concept, not just text
151
+ */
152
+ async semanticSearch(query, options = {}) {
153
+ const { filePattern = '*', maxResults = 10 } = options;
154
+ // Build query concepts
155
+ const concepts = this.extractConcepts(query);
156
+ // Search through codebase
157
+ const files = await this.getMatchingFiles(filePattern);
158
+ const results = [];
159
+ for (const filePath of files) {
160
+ try {
161
+ const content = await fs.readFile(filePath, 'utf-8');
162
+ const relevance = this.calculateRelevance(content, concepts, query);
163
+ if (relevance > 0.3) {
164
+ const snippet = this.extractRelevantSnippet(content, concepts);
165
+ results.push({
166
+ filePath,
167
+ relevance,
168
+ context: this.extractContext(content, snippet),
169
+ matchedConcepts: concepts.filter(c => content.toLowerCase().includes(c.toLowerCase())),
170
+ codeSnippet: snippet,
171
+ });
172
+ }
173
+ }
174
+ catch {
175
+ // Skip files that can't be read
176
+ }
177
+ }
178
+ return results
179
+ .sort((a, b) => b.relevance - a.relevance)
180
+ .slice(0, maxResults);
181
+ }
182
+ extractConcepts(query) {
183
+ // Extract key concepts from query
184
+ const stopWords = new Set(['the', 'a', 'an', 'in', 'on', 'at', 'to', 'for', 'of', 'and', 'or']);
185
+ return query
186
+ .toLowerCase()
187
+ .split(/\s+/)
188
+ .filter(w => w.length > 2 && !stopWords.has(w))
189
+ .map(w => w.replace(/[^a-z0-9]/g, ''));
190
+ }
191
+ calculateRelevance(content, concepts, originalQuery) {
192
+ const lowerContent = content.toLowerCase();
193
+ let score = 0;
194
+ // Concept matching
195
+ for (const concept of concepts) {
196
+ const count = (lowerContent.match(new RegExp(concept, 'g')) || []).length;
197
+ score += Math.min(count * 0.1, 0.5);
198
+ }
199
+ // Check for function/variable names matching query
200
+ const camelCaseQuery = originalQuery.replace(/\s+(.)/g, (_, c) => c.toUpperCase());
201
+ const snakeCaseQuery = originalQuery.replace(/\s+/g, '_');
202
+ if (content.includes(camelCaseQuery) || content.includes(snakeCaseQuery)) {
203
+ score += 0.3;
204
+ }
205
+ // Boost for TypeScript/JavaScript files
206
+ if (content.includes('function') || content.includes('const') || content.includes('export')) {
207
+ score += 0.1;
208
+ }
209
+ return Math.min(1, score);
210
+ }
211
+ extractRelevantSnippet(content, concepts) {
212
+ const lines = content.split('\n');
213
+ let bestStart = 0;
214
+ let bestScore = 0;
215
+ // Find window with highest concept density
216
+ for (let i = 0; i < lines.length - 10; i++) {
217
+ const window = lines.slice(i, i + 10).join('\n').toLowerCase();
218
+ const score = concepts.filter(c => window.includes(c)).length;
219
+ if (score > bestScore) {
220
+ bestScore = score;
221
+ bestStart = i;
222
+ }
223
+ }
224
+ return lines.slice(bestStart, bestStart + 15).join('\n');
225
+ }
226
+ extractContext(content, snippet) {
227
+ const lines = content.split('\n');
228
+ const snippetLines = snippet.split('\n');
229
+ const firstLine = snippetLines[0];
230
+ // Try to find class/function name
231
+ for (let i = 0; i < lines.length; i++) {
232
+ if (lines[i] === firstLine) {
233
+ // Look backwards for function/class declaration
234
+ for (let j = Math.max(0, i - 5); j < i; j++) {
235
+ const match = lines[j].match(/(?:export\s+)?(?:class|function|interface)\s+(\w+)/);
236
+ if (match) {
237
+ return `${match[0]} (line ${j + 1})`;
238
+ }
239
+ }
240
+ }
241
+ }
242
+ return 'Global scope';
243
+ }
244
+ async getMatchingFiles(pattern) {
245
+ // Simple glob-like matching
246
+ const files = [];
247
+ try {
248
+ const { stdout } = await execAsync(`find . -type f -name "${pattern}" ! -path "*/node_modules/*" ! -path "*/.git/*" | head -100`, { cwd: process.cwd() });
249
+ return stdout.trim().split('\n').filter(Boolean);
250
+ }
251
+ catch {
252
+ return [];
253
+ }
254
+ }
255
+ /**
256
+ * Auto-fix common code issues
257
+ */
258
+ async autoFix(filePath, options = {}) {
259
+ const absolutePath = validatePath(filePath);
260
+ const content = await fs.readFile(absolutePath, 'utf-8');
261
+ const lines = content.split('\n');
262
+ const fixes = [];
263
+ let modifiedContent = content;
264
+ // Fix 1: Remove trailing whitespace
265
+ if (options.fixTrailingWhitespace !== false) {
266
+ for (let i = 0; i < lines.length; i++) {
267
+ const line = lines[i];
268
+ const trimmed = line.replace(/\s+$/, '');
269
+ if (line !== trimmed) {
270
+ fixes.push({
271
+ type: 'trailing-whitespace',
272
+ line: i + 1,
273
+ original: line,
274
+ fixed: trimmed,
275
+ });
276
+ lines[i] = trimmed;
277
+ }
278
+ }
279
+ modifiedContent = lines.join('\n');
280
+ }
281
+ // Fix 2: Add missing semicolons (simple heuristic)
282
+ if (options.fixMissingSemicolons) {
283
+ const semicolonPattern = /^(\s*)(.+?)(?<!;)(\s*)$/;
284
+ for (let i = 0; i < lines.length; i++) {
285
+ const line = lines[i];
286
+ // Skip comments, strings, imports, exports, function declarations, etc.
287
+ if (line.trim().startsWith('//') ||
288
+ line.trim().startsWith('/*') ||
289
+ line.trim().startsWith('*') ||
290
+ line.trim().startsWith('import') ||
291
+ line.trim().startsWith('export') ||
292
+ line.trim().startsWith('function') ||
293
+ line.trim().startsWith('async function') ||
294
+ line.trim().startsWith('class') ||
295
+ line.trim().startsWith('interface') ||
296
+ line.trim().startsWith('type') ||
297
+ line.trim().startsWith('if') ||
298
+ line.trim().startsWith('for') ||
299
+ line.trim().startsWith('while') ||
300
+ line.trim().startsWith('switch') ||
301
+ line.trim().startsWith('try') ||
302
+ line.trim().startsWith('catch') ||
303
+ line.trim().startsWith('finally') ||
304
+ line.trim().startsWith('{') ||
305
+ line.trim().startsWith('}') ||
306
+ line.trim().endsWith('{') ||
307
+ line.trim().endsWith('}') ||
308
+ line.trim().endsWith(';') ||
309
+ line.trim() === '') {
310
+ continue;
311
+ }
312
+ // Add semicolon if line looks like a statement
313
+ if (/[a-zA-Z0-9_)\]]\s*$/.test(line) && !line.trim().endsWith(';')) {
314
+ fixes.push({
315
+ type: 'missing-semicolon',
316
+ line: i + 1,
317
+ original: line,
318
+ fixed: line + ';',
319
+ });
320
+ lines[i] = line + ';';
321
+ }
322
+ }
323
+ modifiedContent = lines.join('\n');
324
+ }
325
+ // Fix 3: Optimize imports
326
+ if (options.optimizeImports) {
327
+ const importRegex = /^(import\s+(?:{[^}]*}|\*\s+as\s+\w+|\w+)\s+from\s+['"][^'"]+['"];?)$/gm;
328
+ const imports = [];
329
+ let match;
330
+ while ((match = importRegex.exec(content)) !== null) {
331
+ imports.push(match[1]);
332
+ }
333
+ if (imports.length > 0) {
334
+ // Sort imports
335
+ imports.sort((a, b) => {
336
+ const aIsRelative = a.includes("from '.'") || a.includes("from '..");
337
+ const bIsRelative = b.includes("from '.'") || b.includes("from '..");
338
+ if (aIsRelative && !bIsRelative)
339
+ return 1;
340
+ if (!aIsRelative && bIsRelative)
341
+ return -1;
342
+ return a.localeCompare(b);
343
+ });
344
+ // Remove duplicates
345
+ const uniqueImports = [...new Set(imports)];
346
+ if (uniqueImports.length !== imports.length || imports.join('\n') !== uniqueImports.join('\n')) {
347
+ fixes.push({
348
+ type: 'optimize-imports',
349
+ line: 1,
350
+ original: `Found ${imports.length} imports`,
351
+ fixed: `Optimized to ${uniqueImports.length} imports`,
352
+ });
353
+ }
354
+ }
355
+ }
356
+ // Apply fixes if not dry run
357
+ const applied = !options.dryRun && fixes.length > 0;
358
+ if (applied) {
359
+ await fs.writeFile(absolutePath, modifiedContent, 'utf-8');
360
+ }
361
+ return { fixes, applied };
362
+ }
363
+ /**
364
+ * Detect code patterns and anti-patterns
365
+ */
366
+ detectPatterns(filePath, sourceFile) {
367
+ const patterns = [];
368
+ const content = sourceFile.getFullText();
369
+ // Pattern: Singleton
370
+ const singletonPattern = /class\s+(\w+).*?private\s+static\s+instance|getInstance/s;
371
+ if (singletonPattern.test(content)) {
372
+ patterns.push({
373
+ name: 'Singleton Pattern',
374
+ description: 'Ensures a class has only one instance',
375
+ examples: ['Database connection', 'Logger', 'Configuration'],
376
+ antiPattern: 'Can make testing difficult, consider dependency injection',
377
+ solution: 'Use factory functions or dependency injection instead',
378
+ confidence: 85,
379
+ });
380
+ }
381
+ // Pattern: Factory
382
+ const factoryPattern = /create[A-Z]\w+\s*\(|make[A-Z]\w+\s*\(/;
383
+ if (factoryPattern.test(content)) {
384
+ patterns.push({
385
+ name: 'Factory Pattern',
386
+ description: 'Creates objects without specifying exact class',
387
+ examples: ['createUser()', 'makeRequest()'],
388
+ solution: 'Use dependency injection container or factory pattern',
389
+ confidence: 70,
390
+ });
391
+ }
392
+ // Anti-pattern: Callback hell
393
+ const callbackHell = /\)\s*\{[\s\S]*?\)\s*\{[\s\S]*?\)\s*\{/;
394
+ if (callbackHell.test(content)) {
395
+ patterns.push({
396
+ name: 'Callback Hell (Anti-pattern)',
397
+ description: 'Deeply nested callbacks',
398
+ examples: [],
399
+ antiPattern: 'Makes code hard to read and maintain',
400
+ solution: 'Use async/await or Promise chains',
401
+ confidence: 90,
402
+ });
403
+ }
404
+ // Pattern: Dependency Injection
405
+ const diPattern = /constructor\s*\([^)]*(?:private|public|protected)[^)]*\)/;
406
+ if (diPattern.test(content)) {
407
+ patterns.push({
408
+ name: 'Dependency Injection',
409
+ description: 'Dependencies provided through constructor',
410
+ examples: ['constructor(private db: Database)'],
411
+ solution: 'Good practice for testability and modularity',
412
+ confidence: 80,
413
+ });
414
+ }
415
+ return patterns;
416
+ }
417
+ }
418
+ // ============= Export singleton =============
419
+ let analyzerInstance = null;
420
+ export function getIntelligentAnalyzer(graph) {
421
+ if (!analyzerInstance) {
422
+ analyzerInstance = new IntelligentCodeAnalyzer(graph);
423
+ }
424
+ return analyzerInstance;
425
+ }
package/dist/lib.d.ts CHANGED
@@ -41,6 +41,12 @@ export declare class SequentialThinkingServer {
41
41
  private contextManager;
42
42
  private ruleManager;
43
43
  private maxHistorySize;
44
+ private static readonly MAX_HISTORY_SIZE;
45
+ private static readonly AUTO_PRUNE_THRESHOLD;
46
+ private static readonly CONFIDENCE_CRITICAL_THRESHOLD;
47
+ private static readonly MAX_NESTING_DEPTH;
48
+ private static readonly STALLING_THRESHOLD;
49
+ private static readonly EXECUTION_STRUGGLE_THRESHOLD;
44
50
  constructor(storagePath?: string, delayMs?: number, maxHistorySize?: number);
45
51
  private loadHistory;
46
52
  private attemptRecovery;
@@ -58,6 +64,42 @@ export declare class SequentialThinkingServer {
58
64
  searchHistory(query: string): Promise<ThoughtData[]>;
59
65
  private addToMemory;
60
66
  private formatThought;
67
+ /**
68
+ * Handle block management - create new blocks or switch context
69
+ */
70
+ private handleBlockManagement;
71
+ /**
72
+ * Detect loops, stalling, and other thinking pattern issues
73
+ */
74
+ private detectLoopsAndStalling;
75
+ /**
76
+ * Validate solution before accepting
77
+ */
78
+ private validateSolution;
79
+ /**
80
+ * Update confidence score based on thought type and warnings
81
+ */
82
+ private updateConfidenceScore;
83
+ /**
84
+ * Get block history for current input
85
+ */
86
+ private getBlockHistory;
87
+ /**
88
+ * Check for smart branching - reset confidence on pivot
89
+ */
90
+ private checkSmartBranching;
91
+ /**
92
+ * Check semantic thought recall for analysis type
93
+ */
94
+ private checkSemanticRecall;
95
+ /**
96
+ * Check anti-insanity - prevent repeating failed executions
97
+ */
98
+ private checkAntiInsanity;
99
+ /**
100
+ * Check if confidence is critical and return critical stop response if needed
101
+ */
102
+ private checkConfidenceCritical;
61
103
  processThought(input: ThoughtData): Promise<{
62
104
  content: any[];
63
105
  isError?: boolean;