@gotza02/sequential-thinking 10000.1.7 → 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 (36) hide show
  1. package/dist/analyzers/ComplexityCalculator.d.ts +15 -0
  2. package/dist/analyzers/ComplexityCalculator.js +59 -0
  3. package/dist/analyzers/QualityAnalyzer.d.ts +25 -0
  4. package/dist/analyzers/QualityAnalyzer.js +89 -0
  5. package/dist/analyzers/RefactoringEngine.d.ts +20 -0
  6. package/dist/analyzers/RefactoringEngine.js +107 -0
  7. package/dist/analyzers/SymbolAnalyzer.d.ts +30 -0
  8. package/dist/analyzers/SymbolAnalyzer.js +123 -0
  9. package/dist/analyzers/index.d.ts +8 -0
  10. package/dist/analyzers/index.js +4 -0
  11. package/dist/coding.test.js +4 -0
  12. package/dist/dashboard/index.html +95 -0
  13. package/dist/dashboard/server.js +1 -1
  14. package/dist/graph.d.ts +0 -6
  15. package/dist/graph.js +9 -265
  16. package/dist/intelligent-code.d.ts +2 -68
  17. package/dist/intelligent-code.js +10 -364
  18. package/dist/lib.d.ts +42 -0
  19. package/dist/lib.js +308 -237
  20. package/dist/parsers/GenericParser.d.ts +6 -0
  21. package/dist/parsers/GenericParser.js +52 -0
  22. package/dist/parsers/GoParser.d.ts +6 -0
  23. package/dist/parsers/GoParser.js +36 -0
  24. package/dist/parsers/JavaParser.d.ts +6 -0
  25. package/dist/parsers/JavaParser.js +32 -0
  26. package/dist/parsers/PythonParser.d.ts +6 -0
  27. package/dist/parsers/PythonParser.js +50 -0
  28. package/dist/parsers/RustParser.d.ts +6 -0
  29. package/dist/parsers/RustParser.js +33 -0
  30. package/dist/parsers/TypeScriptParser.d.ts +9 -0
  31. package/dist/parsers/TypeScriptParser.js +85 -0
  32. package/dist/parsers/index.d.ts +7 -0
  33. package/dist/parsers/index.js +6 -0
  34. package/dist/tools/sports/tools/match.js +2 -2
  35. package/dist/tools/web.js +4 -1
  36. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ import ts from 'typescript';
2
+ export interface CodeMetrics {
3
+ complexity: number;
4
+ linesOfCode: number;
5
+ commentRatio: number;
6
+ functionCount: number;
7
+ maxNestingDepth: number;
8
+ duplicateCode: number;
9
+ testCoverage?: number;
10
+ }
11
+ export declare class ComplexityCalculator {
12
+ calculate(sourceFile: ts.SourceFile, content: string): CodeMetrics;
13
+ }
14
+ export declare const complexityCalculator: ComplexityCalculator;
15
+ export default complexityCalculator;
@@ -0,0 +1,59 @@
1
+ import ts from 'typescript';
2
+ export class ComplexityCalculator {
3
+ calculate(sourceFile, content) {
4
+ let complexity = 0;
5
+ let functionCount = 0;
6
+ let maxNestingDepth = 0;
7
+ let currentDepth = 0;
8
+ const visit = (node) => {
9
+ // Cyclomatic complexity
10
+ if (ts.isIfStatement(node) ||
11
+ ts.isConditionalExpression(node) ||
12
+ ts.isWhileStatement(node) ||
13
+ ts.isForStatement(node) ||
14
+ ts.isForInStatement(node) ||
15
+ ts.isForOfStatement(node) ||
16
+ ts.isCaseClause(node) ||
17
+ (ts.isBinaryExpression(node) &&
18
+ (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
19
+ node.operatorToken.kind === ts.SyntaxKind.BarBarToken))) {
20
+ complexity++;
21
+ }
22
+ // Function count
23
+ if (ts.isFunctionDeclaration(node) ||
24
+ ts.isArrowFunction(node) ||
25
+ ts.isMethodDeclaration(node)) {
26
+ functionCount++;
27
+ }
28
+ // Nesting depth
29
+ if (ts.isBlock(node) ||
30
+ ts.isIfStatement(node) ||
31
+ ts.isForStatement(node) ||
32
+ ts.isWhileStatement(node)) {
33
+ currentDepth++;
34
+ maxNestingDepth = Math.max(maxNestingDepth, currentDepth);
35
+ }
36
+ ts.forEachChild(node, visit);
37
+ if (ts.isBlock(node) ||
38
+ ts.isIfStatement(node) ||
39
+ ts.isForStatement(node) ||
40
+ ts.isWhileStatement(node)) {
41
+ currentDepth--;
42
+ }
43
+ };
44
+ visit(sourceFile);
45
+ const lines = content.split('\n');
46
+ const codeLines = lines.filter(l => l.trim().length > 0 && !l.trim().startsWith('//'));
47
+ const commentLines = lines.filter(l => l.trim().startsWith('//') || l.trim().startsWith('/*'));
48
+ return {
49
+ complexity: complexity + 1, // Base complexity is 1
50
+ linesOfCode: codeLines.length,
51
+ commentRatio: codeLines.length > 0 ? commentLines.length / codeLines.length : 0,
52
+ functionCount,
53
+ maxNestingDepth,
54
+ duplicateCode: 0, // Would need cross-file analysis
55
+ };
56
+ }
57
+ }
58
+ export const complexityCalculator = new ComplexityCalculator();
59
+ export default complexityCalculator;
@@ -0,0 +1,25 @@
1
+ import ts from 'typescript';
2
+ import { CodeMetrics } from './ComplexityCalculator.js';
3
+ export interface QualityIssue {
4
+ type: 'error' | 'warning' | 'info';
5
+ category: 'complexity' | 'style' | 'security' | 'performance' | 'maintainability';
6
+ message: string;
7
+ line?: number;
8
+ column?: number;
9
+ severity: number;
10
+ suggestion?: string;
11
+ autoFixable: boolean;
12
+ }
13
+ export interface CodeQualityScore {
14
+ overall: number;
15
+ maintainability: number;
16
+ reliability: number;
17
+ security: number;
18
+ performance: number;
19
+ issues: QualityIssue[];
20
+ }
21
+ export declare class QualityAnalyzer {
22
+ analyze(sourceFile: ts.SourceFile, content: string, metrics: CodeMetrics): Promise<CodeQualityScore>;
23
+ }
24
+ export declare const qualityAnalyzer: QualityAnalyzer;
25
+ export default qualityAnalyzer;
@@ -0,0 +1,89 @@
1
+ import ts from 'typescript';
2
+ export class QualityAnalyzer {
3
+ async analyze(sourceFile, content, metrics) {
4
+ const issues = [];
5
+ // Complexity checks
6
+ if (metrics.complexity > 20) {
7
+ issues.push({
8
+ type: 'warning',
9
+ category: 'complexity',
10
+ message: `High cyclomatic complexity (${metrics.complexity}). Consider refactoring.`,
11
+ severity: 7,
12
+ suggestion: 'Extract smaller functions or simplify conditional logic',
13
+ autoFixable: false,
14
+ });
15
+ }
16
+ if (metrics.maxNestingDepth > 4) {
17
+ issues.push({
18
+ type: 'warning',
19
+ category: 'maintainability',
20
+ message: `Deep nesting detected (${metrics.maxNestingDepth} levels)`,
21
+ severity: 6,
22
+ suggestion: 'Use early returns or extract nested logic into functions',
23
+ autoFixable: false,
24
+ });
25
+ }
26
+ // Comment ratio
27
+ if (metrics.commentRatio < 0.05 && metrics.linesOfCode > 50) {
28
+ issues.push({
29
+ type: 'info',
30
+ category: 'maintainability',
31
+ message: 'Low comment ratio. Consider adding documentation.',
32
+ severity: 3,
33
+ suggestion: 'Add JSDoc comments for public APIs',
34
+ autoFixable: false,
35
+ });
36
+ }
37
+ // Function length
38
+ const visit = (node) => {
39
+ if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {
40
+ const start = node.getStart(sourceFile);
41
+ const end = node.getEnd();
42
+ const functionLines = content.substring(start, end).split('\n').length;
43
+ if (functionLines > 50) {
44
+ issues.push({
45
+ type: 'warning',
46
+ category: 'maintainability',
47
+ message: `Long function detected (${functionLines} lines)`,
48
+ line: ts.getLineAndCharacterOfPosition(sourceFile, node.getStart()).line + 1,
49
+ severity: 6,
50
+ suggestion: 'Extract helper functions to reduce function length',
51
+ autoFixable: false,
52
+ });
53
+ }
54
+ }
55
+ ts.forEachChild(node, visit);
56
+ };
57
+ visit(sourceFile);
58
+ // Check for any types
59
+ const anyTypeRegex = /:\s*any\b/g;
60
+ const anyMatches = content.match(anyTypeRegex);
61
+ if (anyMatches && anyMatches.length > 5) {
62
+ issues.push({
63
+ type: 'warning',
64
+ category: 'maintainability',
65
+ message: `Excessive use of 'any' type (${anyMatches.length} occurrences)`,
66
+ severity: 5,
67
+ suggestion: 'Replace with proper types or use unknown with type guards',
68
+ autoFixable: false,
69
+ });
70
+ }
71
+ // Calculate scores
72
+ const maintainability = Math.max(0, 100 - metrics.complexity * 2 - metrics.maxNestingDepth * 5);
73
+ const reliability = Math.max(0, 100 - (anyMatches?.length || 0) * 5);
74
+ const security = 100; // Would need security-specific checks
75
+ const performance = 100; // Would need performance analysis
76
+ const issuePenalty = issues.reduce((sum, i) => sum + i.severity * 2, 0);
77
+ const overall = Math.max(0, Math.min(100, (maintainability + reliability + security + performance) / 4 - issuePenalty));
78
+ return {
79
+ overall: Math.round(overall),
80
+ maintainability: Math.round(maintainability),
81
+ reliability: Math.round(reliability),
82
+ security,
83
+ performance,
84
+ issues: issues.sort((a, b) => b.severity - a.severity),
85
+ };
86
+ }
87
+ }
88
+ export const qualityAnalyzer = new QualityAnalyzer();
89
+ export default qualityAnalyzer;
@@ -0,0 +1,20 @@
1
+ import ts from 'typescript';
2
+ import { CodeMetrics } from './ComplexityCalculator.js';
3
+ export interface RefactoringSuggestion {
4
+ type: 'extract-method' | 'rename' | 'reorder' | 'simplify' | 'optimize-imports' | 'add-types';
5
+ description: string;
6
+ currentCode: string;
7
+ suggestedCode: string;
8
+ confidence: number;
9
+ impact: 'low' | 'medium' | 'high';
10
+ effort: 'quick' | 'moderate' | 'extensive';
11
+ benefits: string[];
12
+ }
13
+ export declare class RefactoringEngine {
14
+ suggest(ast: ts.SourceFile, metrics: CodeMetrics): RefactoringSuggestion[];
15
+ private findLongFunctions;
16
+ private findNestedConditionals;
17
+ private findAnyUsages;
18
+ }
19
+ export declare const refactoringEngine: RefactoringEngine;
20
+ export default refactoringEngine;
@@ -0,0 +1,107 @@
1
+ import ts from 'typescript';
2
+ export class RefactoringEngine {
3
+ suggest(ast, metrics) {
4
+ const suggestions = [];
5
+ // Suggest extracting long functions
6
+ if (metrics.complexity > 10) {
7
+ const longFunctions = this.findLongFunctions(ast);
8
+ for (const func of longFunctions) {
9
+ suggestions.push({
10
+ type: 'extract-method',
11
+ description: `Extract ${func.name} into smaller functions`,
12
+ currentCode: func.code,
13
+ suggestedCode: `// Suggested: Split into ${Math.ceil(func.lines / 20)} helper functions`,
14
+ confidence: 85,
15
+ impact: 'medium',
16
+ effort: 'moderate',
17
+ benefits: ['Reduced complexity', 'Better testability', 'Easier maintenance'],
18
+ });
19
+ }
20
+ }
21
+ // Simplify nested conditionals
22
+ const nestedConditionals = this.findNestedConditionals(ast);
23
+ for (const nested of nestedConditionals) {
24
+ suggestions.push({
25
+ type: 'simplify',
26
+ description: 'Simplify deeply nested conditionals',
27
+ currentCode: nested.code,
28
+ suggestedCode: '// Use early returns or extract into guard clauses',
29
+ confidence: 90,
30
+ impact: 'low',
31
+ effort: 'quick',
32
+ benefits: ['Improved readability', 'Reduced cognitive load'],
33
+ });
34
+ }
35
+ // Add types for any
36
+ const anyUsages = this.findAnyUsages(ast);
37
+ if (anyUsages.length > 0) {
38
+ suggestions.push({
39
+ type: 'add-types',
40
+ description: `Replace ${anyUsages.length} 'any' types with proper types`,
41
+ currentCode: anyUsages.map(a => a.code).join('\n'),
42
+ suggestedCode: '// Define proper interfaces or use unknown with type guards',
43
+ confidence: 80,
44
+ impact: 'medium',
45
+ effort: 'moderate',
46
+ benefits: ['Type safety', 'Better IDE support', 'Fewer runtime errors'],
47
+ });
48
+ }
49
+ return suggestions.sort((a, b) => b.confidence - a.confidence);
50
+ }
51
+ findLongFunctions(sourceFile) {
52
+ const functions = [];
53
+ const content = sourceFile.getFullText();
54
+ const visit = (node) => {
55
+ if (ts.isFunctionDeclaration(node) && node.name) {
56
+ const start = node.getStart(sourceFile);
57
+ const end = node.getEnd();
58
+ const code = content.substring(start, end);
59
+ const lines = code.split('\n').length;
60
+ if (lines > 30) {
61
+ functions.push({
62
+ name: node.name.text,
63
+ lines,
64
+ code: code.substring(0, 200) + '...',
65
+ });
66
+ }
67
+ }
68
+ ts.forEachChild(node, visit);
69
+ };
70
+ visit(sourceFile);
71
+ return functions;
72
+ }
73
+ findNestedConditionals(sourceFile) {
74
+ const nested = [];
75
+ const content = sourceFile.getFullText();
76
+ const visit = (node, depth = 0) => {
77
+ if (ts.isIfStatement(node)) {
78
+ if (depth > 3) {
79
+ const code = content.substring(node.getStart(sourceFile), node.getEnd());
80
+ nested.push({ depth, code: code.substring(0, 150) + '...' });
81
+ }
82
+ ts.forEachChild(node, n => visit(n, depth + 1));
83
+ }
84
+ else {
85
+ ts.forEachChild(node, n => visit(n, depth));
86
+ }
87
+ };
88
+ visit(sourceFile);
89
+ return nested;
90
+ }
91
+ findAnyUsages(sourceFile) {
92
+ const usages = [];
93
+ const content = sourceFile.getFullText();
94
+ const visit = (node) => {
95
+ if (ts.isTypeReferenceNode(node) && node.typeName.getText(sourceFile) === 'any') {
96
+ usages.push({
97
+ code: content.substring(node.getStart(sourceFile), node.getEnd()),
98
+ });
99
+ }
100
+ ts.forEachChild(node, visit);
101
+ };
102
+ visit(sourceFile);
103
+ return usages;
104
+ }
105
+ }
106
+ export const refactoringEngine = new RefactoringEngine();
107
+ export default refactoringEngine;
@@ -0,0 +1,30 @@
1
+ import ts from 'typescript';
2
+ export interface SymbolAnalysis {
3
+ name: string;
4
+ kind: 'function' | 'class' | 'interface' | 'method' | 'type';
5
+ params?: {
6
+ name: string;
7
+ type: string;
8
+ optional?: boolean;
9
+ }[];
10
+ returnType?: string;
11
+ isAsync?: boolean;
12
+ complexity?: number;
13
+ isExported: boolean;
14
+ documentation?: string;
15
+ methods?: SymbolAnalysis[];
16
+ properties?: {
17
+ name: string;
18
+ type: string;
19
+ optional?: boolean;
20
+ }[];
21
+ }
22
+ export declare class SymbolAnalyzer {
23
+ analyze(sourceFile: ts.SourceFile): SymbolAnalysis[];
24
+ private analyzeFunction;
25
+ private analyzeClass;
26
+ private analyzeInterface;
27
+ private extractJSDoc;
28
+ }
29
+ export declare const symbolAnalyzer: SymbolAnalyzer;
30
+ export default symbolAnalyzer;
@@ -0,0 +1,123 @@
1
+ import ts from 'typescript';
2
+ export class SymbolAnalyzer {
3
+ analyze(sourceFile) {
4
+ const symbols = [];
5
+ const visit = (node) => {
6
+ if (ts.isFunctionDeclaration(node) && node.name) {
7
+ const symbol = this.analyzeFunction(node, sourceFile);
8
+ if (symbol)
9
+ symbols.push(symbol);
10
+ }
11
+ else if (ts.isClassDeclaration(node) && node.name) {
12
+ const symbol = this.analyzeClass(node, sourceFile);
13
+ if (symbol)
14
+ symbols.push(symbol);
15
+ }
16
+ else if (ts.isInterfaceDeclaration(node)) {
17
+ const symbol = this.analyzeInterface(node, sourceFile);
18
+ if (symbol)
19
+ symbols.push(symbol);
20
+ }
21
+ ts.forEachChild(node, visit);
22
+ };
23
+ visit(sourceFile);
24
+ return symbols;
25
+ }
26
+ analyzeFunction(node, sourceFile) {
27
+ if (!node.name)
28
+ return null;
29
+ const params = node.parameters.map(p => ({
30
+ name: p.name.getText(sourceFile),
31
+ type: p.type?.getText(sourceFile) || 'unknown',
32
+ optional: !!p.questionToken,
33
+ }));
34
+ const returnType = node.type?.getText(sourceFile) || 'inferred';
35
+ const isAsync = node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false;
36
+ // Calculate function complexity
37
+ let complexity = 1;
38
+ const countComplexity = (n) => {
39
+ if (ts.isIfStatement(n) ||
40
+ ts.isWhileStatement(n) ||
41
+ ts.isForStatement(n) ||
42
+ ts.isConditionalExpression(n)) {
43
+ complexity++;
44
+ }
45
+ ts.forEachChild(n, countComplexity);
46
+ };
47
+ countComplexity(node);
48
+ return {
49
+ name: node.name.text,
50
+ kind: 'function',
51
+ params,
52
+ returnType,
53
+ isAsync,
54
+ complexity,
55
+ isExported: node.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) || false,
56
+ documentation: this.extractJSDoc(node, sourceFile),
57
+ };
58
+ }
59
+ analyzeClass(node, sourceFile) {
60
+ if (!node.name)
61
+ return null;
62
+ const methods = [];
63
+ const properties = [];
64
+ node.members.forEach(member => {
65
+ if (ts.isMethodDeclaration(member) && member.name) {
66
+ methods.push({
67
+ name: member.name.getText(sourceFile),
68
+ kind: 'method',
69
+ params: member.parameters.map(p => ({
70
+ name: p.name.getText(sourceFile),
71
+ type: p.type?.getText(sourceFile) || 'unknown',
72
+ })),
73
+ returnType: member.type?.getText(sourceFile) || 'void',
74
+ isAsync: member.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false,
75
+ complexity: 1,
76
+ isExported: false,
77
+ });
78
+ }
79
+ else if (ts.isPropertyDeclaration(member) && member.name) {
80
+ properties.push({
81
+ name: member.name.getText(sourceFile),
82
+ type: member.type?.getText(sourceFile) || 'unknown',
83
+ });
84
+ }
85
+ });
86
+ return {
87
+ name: node.name.text,
88
+ kind: 'class',
89
+ methods,
90
+ properties,
91
+ isExported: node.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) || false,
92
+ documentation: this.extractJSDoc(node, sourceFile),
93
+ };
94
+ }
95
+ analyzeInterface(node, sourceFile) {
96
+ const properties = node.members.map(member => {
97
+ if (ts.isPropertySignature(member) && member.name) {
98
+ return {
99
+ name: member.name.getText(sourceFile),
100
+ type: member.type?.getText(sourceFile) || 'unknown',
101
+ optional: !!member.questionToken,
102
+ };
103
+ }
104
+ return null;
105
+ }).filter(p => p !== null);
106
+ return {
107
+ name: node.name.text,
108
+ kind: 'interface',
109
+ properties,
110
+ isExported: node.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) || false,
111
+ documentation: this.extractJSDoc(node, sourceFile),
112
+ };
113
+ }
114
+ extractJSDoc(node, sourceFile) {
115
+ const jsDoc = node.jsDoc;
116
+ if (jsDoc && jsDoc.length > 0) {
117
+ return jsDoc[0].comment?.toString();
118
+ }
119
+ return undefined;
120
+ }
121
+ }
122
+ export const symbolAnalyzer = new SymbolAnalyzer();
123
+ export default symbolAnalyzer;
@@ -0,0 +1,8 @@
1
+ export { ComplexityCalculator, complexityCalculator } from './ComplexityCalculator.js';
2
+ export type { CodeMetrics } from './ComplexityCalculator.js';
3
+ export { QualityAnalyzer, qualityAnalyzer } from './QualityAnalyzer.js';
4
+ export type { QualityIssue, CodeQualityScore } from './QualityAnalyzer.js';
5
+ export { SymbolAnalyzer, symbolAnalyzer } from './SymbolAnalyzer.js';
6
+ export type { SymbolAnalysis } from './SymbolAnalyzer.js';
7
+ export { RefactoringEngine, refactoringEngine } from './RefactoringEngine.js';
8
+ export type { RefactoringSuggestion } from './RefactoringEngine.js';
@@ -0,0 +1,4 @@
1
+ export { ComplexityCalculator, complexityCalculator } from './ComplexityCalculator.js';
2
+ export { QualityAnalyzer, qualityAnalyzer } from './QualityAnalyzer.js';
3
+ export { SymbolAnalyzer, symbolAnalyzer } from './SymbolAnalyzer.js';
4
+ export { RefactoringEngine, refactoringEngine } from './RefactoringEngine.js';
@@ -96,6 +96,10 @@ describe('Deep Coding Tools', () => {
96
96
  });
97
97
  });
98
98
  describe('deep_code_edit', () => {
99
+ beforeEach(() => {
100
+ // Mock fs.stat for file size checks
101
+ fs.stat.mockResolvedValue({ size: 100 });
102
+ });
99
103
  it('should error if target text is not found', async () => {
100
104
  registerCodingTools(mockServer, mockGraph);
101
105
  const handler = registeredTools['deep_code_edit'];
@@ -0,0 +1,95 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Thinking Dashboard</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
8
+ <style>
9
+ body { font-family: sans-serif; padding: 20px; background: #f4f4f4; }
10
+ .container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
11
+ h1 { margin-top: 0; }
12
+ #graph { overflow-x: auto; padding: 20px; }
13
+ #details { margin-top: 20px; padding: 20px; background: #eee; border-radius: 5px; white-space: pre-wrap; font-family: monospace; display: none; }
14
+ .status { float: right; font-weight: bold; color: #666; }
15
+ .error { color: red; }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <div class="container">
20
+ <div class="status" id="status">Connecting...</div>
21
+ <h1>🧠 Thinking Process</h1>
22
+ <div id="graph" class="mermaid">
23
+ graph TD
24
+ A[Loading...]
25
+ </div>
26
+ <div id="details"></div>
27
+ </div>
28
+
29
+ <script>
30
+ mermaid.initialize({ startOnLoad: true, securityLevel: 'loose' });
31
+
32
+ let lastHistoryLength = 0;
33
+
34
+ async function fetchHistory() {
35
+ try {
36
+ const res = await fetch('/api/history');
37
+ const data = await res.json();
38
+ const history = data.thoughtHistory || [];
39
+ const blocks = data.blocks || [];
40
+
41
+ document.getElementById('status').innerText = `Active Block: ${data.currentBlockId || 'None'} | Thoughts: ${history.length}`;
42
+
43
+ if (history.length === lastHistoryLength) return;
44
+ lastHistoryLength = history.length;
45
+
46
+ renderGraph(history);
47
+ } catch (e) {
48
+ document.getElementById('status').innerText = 'Error connecting to server';
49
+ document.getElementById('status').classList.add('error');
50
+ }
51
+ }
52
+
53
+ function renderGraph(history) {
54
+ let graph = 'graph TD\n';
55
+ // Show last 20 thoughts to avoid huge graphs
56
+ const recent = history.slice(-20);
57
+
58
+ recent.forEach((t, i) => {
59
+ const id = `T${t.thoughtNumber}`;
60
+ let label = `${t.thoughtType || 'thought'} #${t.thoughtNumber}`;
61
+ // Escape quotes
62
+ label = label.replace(/"/g, "'");
63
+
64
+ // Style based on type
65
+ let style = '';
66
+ if (t.thoughtType === 'execution') style = 'fill:#f9f,stroke:#333,stroke-width:2px';
67
+ else if (t.thoughtType === 'observation') style = 'fill:#9ff,stroke:#333,stroke-width:2px';
68
+ else if (t.thoughtType === 'solution') style = 'fill:#9f9,stroke:#333,stroke-width:4px';
69
+ else if (t.thoughtType === 'planning') style = 'fill:#ff9,stroke:#333,stroke-width:2px';
70
+ else style = 'fill:#fff,stroke:#333,stroke-width:1px';
71
+
72
+ graph += `${id}("${label}")\n`;
73
+ if (style) graph += `style ${id} ${style}\n`;
74
+
75
+ if (i > 0) {
76
+ const prev = recent[i-1];
77
+ const prevId = `T${prev.thoughtNumber}`;
78
+ graph += `${prevId} --> ${id}\n`;
79
+ }
80
+
81
+ // Click event (not fully supported in raw mermaid string without callback binding, but we visualize primarily)
82
+ });
83
+
84
+ // Re-render
85
+ const element = document.getElementById('graph');
86
+ element.removeAttribute('data-processed');
87
+ element.innerHTML = graph;
88
+ mermaid.init(undefined, element);
89
+ }
90
+
91
+ setInterval(fetchHistory, 2000);
92
+ fetchHistory();
93
+ </script>
94
+ </body>
95
+ </html>
@@ -154,7 +154,7 @@ async function findCodeFiles(dir) {
154
154
  await scan(fullPath);
155
155
  }
156
156
  }
157
- else if (entry.isFile() && /\.(ts|js|tsx|jsx)$/.test(entry.name) && !entry.name.endsWith('.d.ts')) {
157
+ else if (entry.isFile() && /\.(ts|tsx)$/.test(entry.name)) {
158
158
  files.push(fullPath);
159
159
  }
160
160
  }
package/dist/graph.d.ts CHANGED
@@ -41,12 +41,6 @@ export declare class ProjectKnowledgeGraph {
41
41
  private getAllFiles;
42
42
  private isMonorepoRoot;
43
43
  private parseFile;
44
- private parseTypeScript;
45
- private parsePython;
46
- private parseGo;
47
- private parseRust;
48
- private parseJavaLike;
49
- private parseGeneric;
50
44
  private linkFileNodes;
51
45
  private resolvePath;
52
46
  getRelationships(filePath: string): {