feat(lib): bundle MCP servers from .common/lib into factory/lib/
Copies source (no node_modules, dist, .tasks, .wiki, __pycache__) for: - projects-meta-mcp v2.25.0 (TypeScript/Node) - wiki-graph v0.3.1 (TypeScript/Node) - interns-mcp v0.3.3 (Python/FastMCP) .gitignore: exclude lib build artefacts (node_modules, dist, .venv, __pycache__, *.pyc) bootstrap.ps1: add MCP build step — npm install+build for TS servers, venv+pip for Python Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
59
lib/wiki-graph/tests/cache.test.ts
Normal file
59
lib/wiki-graph/tests/cache.test.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { mkdtempSync, writeFileSync, rmSync, utimesSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { GraphCache } from '../src/cache.js';
|
||||
|
||||
describe('GraphCache (mtime revalidation)', () => {
|
||||
let dir: string;
|
||||
|
||||
beforeEach(() => {
|
||||
dir = mkdtempSync(join(tmpdir(), 'wiki-graph-cache-'));
|
||||
writeFileSync(join(dir, 'a.md'), '# A\n[[b]]\n');
|
||||
writeFileSync(join(dir, 'b.md'), '# B\n');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test('returns the same graph instance when nothing changed', () => {
|
||||
const cache = new GraphCache();
|
||||
const g1 = cache.load(dir);
|
||||
const g2 = cache.load(dir);
|
||||
expect(g2).toBe(g1);
|
||||
expect(g1.stats().nodes).toBe(2);
|
||||
});
|
||||
|
||||
test('rebuilds when a new file appears', () => {
|
||||
const cache = new GraphCache();
|
||||
const g1 = cache.load(dir);
|
||||
writeFileSync(join(dir, 'c.md'), '# C\n');
|
||||
const g2 = cache.load(dir);
|
||||
expect(g2).not.toBe(g1);
|
||||
expect(g2.stats().nodes).toBe(3);
|
||||
});
|
||||
|
||||
test('rebuilds when a file is modified (mtime bump)', () => {
|
||||
const cache = new GraphCache();
|
||||
const g1 = cache.load(dir);
|
||||
expect(g1.backlinks('c')).toEqual([]);
|
||||
writeFileSync(join(dir, 'a.md'), '# A\n[[b]] [[c]]\n');
|
||||
writeFileSync(join(dir, 'c.md'), '# C\n');
|
||||
const future = new Date(Date.now() + 5000);
|
||||
utimesSync(join(dir, 'a.md'), future, future);
|
||||
const g2 = cache.load(dir);
|
||||
expect(g2).not.toBe(g1);
|
||||
expect(g2.backlinks('c')).toEqual(['a']);
|
||||
});
|
||||
|
||||
test('only changed files are re-read', () => {
|
||||
const cache = new GraphCache();
|
||||
cache.load(dir);
|
||||
writeFileSync(join(dir, 'c.md'), '# C\n');
|
||||
const before = cache.reads;
|
||||
cache.load(dir);
|
||||
// a.md and b.md unchanged → only c.md read on the second build
|
||||
expect(cache.reads - before).toBe(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user