@gotza02/sequential-thinking 2026.1.22 → 2026.1.24
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 +13 -2
- package/dist/graph.js +12 -8
- package/dist/graph_repro.test.js +63 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ The Sequential Thinking tool is designed for:
|
|
|
103
103
|
|
|
104
104
|
### Usage with Claude Desktop
|
|
105
105
|
|
|
106
|
-
Add this to your `claude_desktop_config.json
|
|
106
|
+
Add this to your `claude_desktop_config.json`. You can configure API keys directly here:
|
|
107
107
|
|
|
108
108
|
#### npx
|
|
109
109
|
|
|
@@ -115,7 +115,13 @@ Add this to your `claude_desktop_config.json`:
|
|
|
115
115
|
"args": [
|
|
116
116
|
"-y",
|
|
117
117
|
"@gotza02/sequential-thinking"
|
|
118
|
-
]
|
|
118
|
+
],
|
|
119
|
+
"env": {
|
|
120
|
+
"BRAVE_API_KEY": "YOUR_BRAVE_API_KEY",
|
|
121
|
+
"EXA_API_KEY": "YOUR_EXA_API_KEY",
|
|
122
|
+
"GOOGLE_SEARCH_API_KEY": "YOUR_GOOGLE_SEARCH_API_KEY",
|
|
123
|
+
"GOOGLE_SEARCH_CX": "YOUR_GOOGLE_SEARCH_CX"
|
|
124
|
+
}
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
}
|
|
@@ -140,6 +146,11 @@ npm run build
|
|
|
140
146
|
npm test
|
|
141
147
|
```
|
|
142
148
|
|
|
149
|
+
## Recent Updates (v2026.1.24)
|
|
150
|
+
|
|
151
|
+
- **Bug Fixes**:
|
|
152
|
+
- Fixed `get_file_relationships` to correctly resolve absolute imports and imports from project root (e.g., `src/utils`), ensuring the dependency graph is complete for projects using path aliases or absolute paths.
|
|
153
|
+
|
|
143
154
|
## Recent Updates (v2026.1.22)
|
|
144
155
|
|
|
145
156
|
- **Environment Variables**:
|
package/dist/graph.js
CHANGED
|
@@ -79,15 +79,19 @@ export class ProjectKnowledgeGraph {
|
|
|
79
79
|
if (!currentNode)
|
|
80
80
|
return;
|
|
81
81
|
for (const importPath of imports) {
|
|
82
|
+
let resolvedPath = null;
|
|
82
83
|
if (importPath.startsWith('.')) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
84
|
+
resolvedPath = await this.resolvePath(path.dirname(filePath), importPath);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
resolvedPath = await this.resolvePath(this.rootDir, importPath);
|
|
88
|
+
}
|
|
89
|
+
if (resolvedPath && this.nodes.has(resolvedPath)) {
|
|
90
|
+
if (!currentNode.imports.includes(resolvedPath)) {
|
|
91
|
+
currentNode.imports.push(resolvedPath);
|
|
92
|
+
}
|
|
93
|
+
if (!this.nodes.get(resolvedPath)?.importedBy.includes(filePath)) {
|
|
94
|
+
this.nodes.get(resolvedPath)?.importedBy.push(filePath);
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
import { ProjectKnowledgeGraph } from './graph.js';
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
vi.mock('fs/promises');
|
|
5
|
+
describe('ProjectKnowledgeGraph Reproduction', () => {
|
|
6
|
+
let graph;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
graph = new ProjectKnowledgeGraph();
|
|
9
|
+
vi.resetAllMocks();
|
|
10
|
+
});
|
|
11
|
+
it('should resolve absolute imports from project root', async () => {
|
|
12
|
+
// Scenario: /app/src/feature/a.ts imports 'src/shared/b.ts'
|
|
13
|
+
const mockContentA = `import { b } from 'src/shared/b';`;
|
|
14
|
+
fs.readdir.mockResolvedValue([
|
|
15
|
+
{ name: 'src', isDirectory: () => true },
|
|
16
|
+
{ name: 'feature', isDirectory: () => true },
|
|
17
|
+
{ name: 'shared', isDirectory: () => true },
|
|
18
|
+
{ name: 'a.ts', isDirectory: () => false },
|
|
19
|
+
{ name: 'b.ts', isDirectory: () => false }
|
|
20
|
+
]);
|
|
21
|
+
// Mock getAllFiles behavior by manually setting up the file system structure conceptually
|
|
22
|
+
// Since getAllFiles is recursive and hard to mock perfectly with just readdir,
|
|
23
|
+
// we'll focus on the result of getAllFiles which populates the graph.
|
|
24
|
+
// Wait, the test uses the REAL getAllFiles, so we must mock readdir correctly.
|
|
25
|
+
// Let's simplify: Flat structure for test.
|
|
26
|
+
// Root: /app
|
|
27
|
+
// Files: /app/a.ts, /app/b.ts
|
|
28
|
+
// a.ts content: "import ... from 'b'" (no dot)
|
|
29
|
+
// OR
|
|
30
|
+
// a.ts content: "import ... from 'app/b'" (if root is /)
|
|
31
|
+
// Let's try the 'src/...' pattern which is common.
|
|
32
|
+
// Root: /root
|
|
33
|
+
// File: /root/src/index.ts -> imports 'src/utils'
|
|
34
|
+
// File: /root/src/utils.ts
|
|
35
|
+
const rootDir = '/root';
|
|
36
|
+
const indexFile = '/root/src/index.ts';
|
|
37
|
+
const utilsFile = '/root/src/utils.ts';
|
|
38
|
+
// Mock readdir to simulate:
|
|
39
|
+
// /root -> [src]
|
|
40
|
+
// /root/src -> [index.ts, utils.ts]
|
|
41
|
+
fs.readdir.mockImplementation(async (dir) => {
|
|
42
|
+
if (dir === '/root')
|
|
43
|
+
return [{ name: 'src', isDirectory: () => true }];
|
|
44
|
+
if (dir === '/root/src')
|
|
45
|
+
return [
|
|
46
|
+
{ name: 'index.ts', isDirectory: () => false },
|
|
47
|
+
{ name: 'utils.ts', isDirectory: () => false }
|
|
48
|
+
];
|
|
49
|
+
return [];
|
|
50
|
+
});
|
|
51
|
+
fs.readFile.mockImplementation(async (filePath) => {
|
|
52
|
+
if (filePath === indexFile)
|
|
53
|
+
return `import { u } from 'src/utils';`;
|
|
54
|
+
return '';
|
|
55
|
+
});
|
|
56
|
+
await graph.build(rootDir);
|
|
57
|
+
const relationships = graph.getRelationships(indexFile);
|
|
58
|
+
// We expect 'src/utils.ts' to be in imports.
|
|
59
|
+
// Note: graph.getRelationships returns relative paths.
|
|
60
|
+
// relative('/root', '/root/src/utils.ts') -> 'src/utils.ts'
|
|
61
|
+
expect(relationships?.imports).toContain('src/utils.ts');
|
|
62
|
+
});
|
|
63
|
+
});
|