@gotza02/sequential-thinking 2026.1.23 → 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 +5 -0
- package/dist/graph.js +12 -8
- package/dist/graph_repro.test.js +63 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,6 +146,11 @@ npm run build
|
|
|
146
146
|
npm test
|
|
147
147
|
```
|
|
148
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
|
+
|
|
149
154
|
## Recent Updates (v2026.1.22)
|
|
150
155
|
|
|
151
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
|
+
});
|