@gotza02/sequential-thinking 2026.1.28 → 2026.2.0
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 +118 -176
- package/dist/graph.js +25 -0
- package/dist/graph.test.js +0 -0
- package/dist/graph_repro.test.js +0 -0
- package/dist/index.js +13 -431
- package/dist/lib.js +0 -0
- package/dist/notes.js +77 -0
- package/dist/repro_search.test.js +79 -0
- package/dist/server.test.js +0 -0
- package/dist/tools/filesystem.js +152 -0
- package/dist/tools/graph.js +79 -0
- package/dist/tools/notes.js +55 -0
- package/dist/tools/thinking.js +113 -0
- package/dist/tools/web.js +134 -0
- package/dist/utils.js +35 -0
- package/dist/verify_edit.test.js +66 -0
- package/dist/verify_notes.test.js +36 -0
- package/dist/verify_viz.test.js +25 -0
- package/package.json +4 -3
- package/dist/verify_new_tools.test.js +0 -67
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { NotesManager } from './notes.js';
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
describe('Notes Manager', () => {
|
|
6
|
+
const testFile = path.join(__dirname, 'test_notes.json');
|
|
7
|
+
let manager;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
manager = new NotesManager(testFile);
|
|
10
|
+
});
|
|
11
|
+
afterEach(async () => {
|
|
12
|
+
try {
|
|
13
|
+
await fs.unlink(testFile);
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
});
|
|
17
|
+
it('should add and list notes', async () => {
|
|
18
|
+
await manager.addNote("My Note", "Content", ["tag1"]);
|
|
19
|
+
const notes = await manager.listNotes();
|
|
20
|
+
expect(notes.length).toBe(1);
|
|
21
|
+
expect(notes[0].title).toBe("My Note");
|
|
22
|
+
});
|
|
23
|
+
it('should search notes', async () => {
|
|
24
|
+
await manager.addNote("React Tips", "Use hooks", ["react"]);
|
|
25
|
+
await manager.addNote("Vue Tips", "Use composition", ["vue"]);
|
|
26
|
+
const results = await manager.searchNotes("hooks");
|
|
27
|
+
expect(results.length).toBe(1);
|
|
28
|
+
expect(results[0].title).toBe("React Tips");
|
|
29
|
+
});
|
|
30
|
+
it('should delete note', async () => {
|
|
31
|
+
const note = await manager.addNote("To Delete", "...");
|
|
32
|
+
await manager.deleteNote(note.id);
|
|
33
|
+
const notes = await manager.listNotes();
|
|
34
|
+
expect(notes.length).toBe(0);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { ProjectKnowledgeGraph } from './graph.js';
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
describe('Graph Visualization', () => {
|
|
6
|
+
const testDir = path.join(__dirname, 'test_viz_env');
|
|
7
|
+
const graph = new ProjectKnowledgeGraph();
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await fs.mkdir(testDir, { recursive: true });
|
|
10
|
+
await fs.writeFile(path.join(testDir, 'a.ts'), 'import { b } from "./b";');
|
|
11
|
+
await fs.writeFile(path.join(testDir, 'b.ts'), 'export const b = 1;');
|
|
12
|
+
});
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await fs.rm(testDir, { recursive: true, force: true });
|
|
15
|
+
});
|
|
16
|
+
it('should generate mermaid diagram', async () => {
|
|
17
|
+
await graph.build(testDir);
|
|
18
|
+
const mermaid = graph.toMermaid();
|
|
19
|
+
console.log("Generated Mermaid:", mermaid);
|
|
20
|
+
expect(mermaid).toContain('graph TD');
|
|
21
|
+
expect(mermaid).toMatch(/N\d+\["a\.ts"\]/);
|
|
22
|
+
expect(mermaid).toMatch(/N\d+\["b\.ts"\]/);
|
|
23
|
+
expect(mermaid).toContain('-->');
|
|
24
|
+
});
|
|
25
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gotza02/sequential-thinking",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
|
-
"build": "tsc
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/index.js",
|
|
26
27
|
"prepare": "npm run build",
|
|
27
28
|
"watch": "tsc --watch",
|
|
28
29
|
"test": "vitest run --coverage"
|
|
@@ -45,4 +46,4 @@
|
|
|
45
46
|
"shx": "^0.3.4",
|
|
46
47
|
"vitest": "^2.1.8"
|
|
47
48
|
}
|
|
48
|
-
}
|
|
49
|
+
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import * as fs from 'fs/promises';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import { SequentialThinkingServer } from './lib';
|
|
5
|
-
// Mock dependencies for read_webpage if needed,
|
|
6
|
-
// but for now let's test the logic we can control.
|
|
7
|
-
describe('New Tools Verification', () => {
|
|
8
|
-
const testDir = path.resolve('test_sandbox');
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await fs.mkdir(testDir, { recursive: true });
|
|
11
|
-
});
|
|
12
|
-
afterEach(async () => {
|
|
13
|
-
await fs.rm(testDir, { recursive: true, force: true });
|
|
14
|
-
});
|
|
15
|
-
it('search_code should find patterns and ignore node_modules', async () => {
|
|
16
|
-
// Setup files
|
|
17
|
-
await fs.writeFile(path.join(testDir, 'target.ts'), 'const x = "FIND_ME";');
|
|
18
|
-
await fs.writeFile(path.join(testDir, 'other.ts'), 'const y = "nope";');
|
|
19
|
-
const modulesDir = path.join(testDir, 'node_modules');
|
|
20
|
-
await fs.mkdir(modulesDir);
|
|
21
|
-
await fs.writeFile(path.join(modulesDir, 'ignored.ts'), 'const z = "FIND_ME";');
|
|
22
|
-
// Logic from search_code (replicated here for unit testing the logic itself,
|
|
23
|
-
// effectively testing the implementation I wrote in index.ts)
|
|
24
|
-
async function searchDir(dir, pattern) {
|
|
25
|
-
const results = [];
|
|
26
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
27
|
-
for (const entry of entries) {
|
|
28
|
-
const fullPath = path.join(dir, entry.name);
|
|
29
|
-
if (entry.isDirectory()) {
|
|
30
|
-
if (['node_modules', '.git', 'dist', 'coverage', '.gemini'].includes(entry.name))
|
|
31
|
-
continue;
|
|
32
|
-
results.push(...await searchDir(fullPath, pattern));
|
|
33
|
-
}
|
|
34
|
-
else if (/\.(ts|js|json|md|txt|html|css|py|java|c|cpp|h|rs|go)$/.test(entry.name)) {
|
|
35
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
36
|
-
if (content.includes(pattern)) {
|
|
37
|
-
results.push(fullPath);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return results;
|
|
42
|
-
}
|
|
43
|
-
const results = await searchDir(testDir, 'FIND_ME');
|
|
44
|
-
expect(results).toHaveLength(1);
|
|
45
|
-
expect(results[0]).toContain('target.ts');
|
|
46
|
-
expect(results[0]).not.toContain('node_modules');
|
|
47
|
-
});
|
|
48
|
-
it('SequentialThinkingServer should clear history', async () => {
|
|
49
|
-
const historyFile = path.join(testDir, 'test_history.json');
|
|
50
|
-
const server = new SequentialThinkingServer(historyFile);
|
|
51
|
-
// Add a thought
|
|
52
|
-
await server.processThought({
|
|
53
|
-
thought: "Test thought",
|
|
54
|
-
thoughtNumber: 1,
|
|
55
|
-
totalThoughts: 1,
|
|
56
|
-
nextThoughtNeeded: false
|
|
57
|
-
});
|
|
58
|
-
// Verify it was written
|
|
59
|
-
const contentBefore = JSON.parse(await fs.readFile(historyFile, 'utf-8'));
|
|
60
|
-
expect(contentBefore).toHaveLength(1);
|
|
61
|
-
// Clear history
|
|
62
|
-
await server.clearHistory();
|
|
63
|
-
// Verify it is empty
|
|
64
|
-
const contentAfter = JSON.parse(await fs.readFile(historyFile, 'utf-8'));
|
|
65
|
-
expect(contentAfter).toHaveLength(0);
|
|
66
|
-
});
|
|
67
|
-
});
|