@gotza02/sequential-thinking 2026.2.19 → 2026.2.20
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/README.md +1 -1
- package/dist/coding.test.js +11 -1
- package/dist/tools/coding.js +40 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Add this to your MCP settings (`~/.gemini/settings.json` or `claude_desktop_conf
|
|
|
62
62
|
|
|
63
63
|
## 🛠️ Tools Summary
|
|
64
64
|
- **Thinking:** `sequentialthinking`, `summarize_history`, `clear_thought_history`
|
|
65
|
-
- **Code:** `build_project_graph`, `deep_code_analyze
|
|
65
|
+
- **Code:** `build_project_graph`, `deep_code_analyze` (Context+Usages), `deep_code_edit`, `search_code` (Regex/Line Numbers)
|
|
66
66
|
- **Memory:** `add_code_snippet`, `search_code_db`, `manage_notes`
|
|
67
67
|
- **Web:** `web_search`, `read_webpage`, `fetch`
|
|
68
68
|
- **System:** `read_file`, `write_file`, `edit_file`, `shell_execute`
|
package/dist/coding.test.js
CHANGED
|
@@ -65,7 +65,14 @@ describe('Deep Coding Tools', () => {
|
|
|
65
65
|
dependencies: [{ path: 'src/dep.ts', symbols: ['Helper'] }],
|
|
66
66
|
dependents: [{ path: 'src/usage.ts', symbols: ['App'] }]
|
|
67
67
|
});
|
|
68
|
-
fs.readFile
|
|
68
|
+
// Mock fs.readFile to return specific content for usage analysis
|
|
69
|
+
fs.readFile.mockImplementation((fpath) => {
|
|
70
|
+
if (fpath.includes('target.ts'))
|
|
71
|
+
return Promise.resolve('export class MyClass {}');
|
|
72
|
+
if (fpath.includes('usage.ts'))
|
|
73
|
+
return Promise.resolve('import { MyClass } from "./target";\nconst app = new MyClass();');
|
|
74
|
+
return Promise.resolve('');
|
|
75
|
+
});
|
|
69
76
|
const result = await handler({ filePath: 'src/target.ts', taskDescription: 'Analyze this' });
|
|
70
77
|
expect(result.isError).toBeUndefined();
|
|
71
78
|
const text = result.content[0].text;
|
|
@@ -74,6 +81,9 @@ describe('Deep Coding Tools', () => {
|
|
|
74
81
|
expect(text).toContain('MyClass'); // Symbol
|
|
75
82
|
expect(text).toContain('src/dep.ts'); // Dependency
|
|
76
83
|
expect(text).toContain('src/usage.ts'); // Dependent
|
|
84
|
+
// Verify usage finding
|
|
85
|
+
expect(text).toContain('Line 1: import { MyClass } from "./target";');
|
|
86
|
+
expect(text).toContain('Line 2: const app = new MyClass();');
|
|
77
87
|
});
|
|
78
88
|
it('should handle fs errors gracefully', async () => {
|
|
79
89
|
registerCodingTools(mockServer, mockGraph);
|
package/dist/tools/coding.js
CHANGED
|
@@ -31,9 +31,46 @@ export function registerCodingTools(server, graph) {
|
|
|
31
31
|
doc += `- ${d.path} (Symbols: ${d.symbols.join(', ')})\n`;
|
|
32
32
|
});
|
|
33
33
|
doc += `\nDEPENDENTS (Files that use this file):\n`;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
// Helper to find usages (defined inline to capture context/scope)
|
|
35
|
+
const findUsages = async (fileToSearch, targetPath, symbols) => {
|
|
36
|
+
try {
|
|
37
|
+
const content = await fs.readFile(fileToSearch, 'utf-8');
|
|
38
|
+
const lines = content.split('\n');
|
|
39
|
+
const matches = [];
|
|
40
|
+
const baseName = path.basename(targetPath, path.extname(targetPath));
|
|
41
|
+
// Escape regex special chars
|
|
42
|
+
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
43
|
+
const symbolRegexes = symbols.map(s => new RegExp(`\\b${escapeRegExp(s)}\\b`));
|
|
44
|
+
lines.forEach((line, index) => {
|
|
45
|
+
// Check for import of the file itself (simple heuristic)
|
|
46
|
+
if ((line.includes('import') || line.includes('require')) && line.includes(baseName)) {
|
|
47
|
+
matches.push(`Line ${index + 1}: ${line.trim()}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Check for symbols
|
|
51
|
+
for (const regex of symbolRegexes) {
|
|
52
|
+
if (regex.test(line)) {
|
|
53
|
+
matches.push(`Line ${index + 1}: ${line.trim()}`);
|
|
54
|
+
break; // One match per line is enough
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return matches;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
for (const d of context.dependents) {
|
|
65
|
+
doc += `- ${d.path}\n`;
|
|
66
|
+
const usages = await findUsages(d.path, filePath, context.targetFile.symbols);
|
|
67
|
+
if (usages.length > 0) {
|
|
68
|
+
// Limit to top 3 to save context
|
|
69
|
+
usages.slice(0, 3).forEach(u => doc += ` ${u}\n`);
|
|
70
|
+
if (usages.length > 3)
|
|
71
|
+
doc += ` ... (${usages.length - 3} more references)\n`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
37
74
|
doc += `\n--- END OF CONTEXT ---`;
|
|
38
75
|
return {
|
|
39
76
|
content: [{ type: "text", text: doc }]
|