moving
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { win32 as pathWin32 } from 'node:path';
|
||||
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||
|
||||
import {
|
||||
@@ -16,7 +17,17 @@ import { registerIdentityTools } from '../src/tools/identity.js';
|
||||
import { registerAwarenessTools } from '../src/tools/awareness.js';
|
||||
import { registerWorkspaceTools } from '../src/tools/workspace.js';
|
||||
import { registerHarvestTools } from '../src/tools/harvest.js';
|
||||
import { registerCleanupTools } from '../src/tools/cleanup.js';
|
||||
import {
|
||||
buildClaudeLaunch,
|
||||
registerCleanupTools,
|
||||
resolveConsolidationGop,
|
||||
} from '../src/tools/cleanup.js';
|
||||
import {
|
||||
collectObservations,
|
||||
FrameStore,
|
||||
MindDB,
|
||||
SessionStore,
|
||||
} from '@waggle/core';
|
||||
import { registerEraseTools } from '../src/tools/erase.js';
|
||||
import { registerIngestTools } from '../src/tools/ingest.js';
|
||||
import { registerWikiTools } from '../src/tools/wiki.js';
|
||||
@@ -43,6 +54,122 @@ function registerAll(server: McpServer): void {
|
||||
registerWikiTools(server);
|
||||
}
|
||||
|
||||
describe('Claude consolidation launch boundary', () => {
|
||||
it('uses the canonical npm CLI without a shell or ambient secrets on Windows', () => {
|
||||
const npmRoot = 'C:\\Users\\test\\AppData\\Roaming\\npm';
|
||||
const shim = pathWin32.join(npmRoot, 'claude.cmd');
|
||||
const cli = pathWin32.join(npmRoot, 'node_modules', '@anthropic-ai', 'claude-code', 'cli.js');
|
||||
const files = new Set([shim.toLowerCase(), cli.toLowerCase()]);
|
||||
const launch = buildClaudeLaunch(['-p', '--output-format=text'], {
|
||||
platform: 'win32',
|
||||
env: {
|
||||
PATH: npmRoot,
|
||||
USERPROFILE: 'C:\\Users\\test',
|
||||
APPDATA: 'C:\\Users\\test\\AppData\\Roaming',
|
||||
CLAUDE_CONFIG_DIR: 'C:\\Users\\test\\.claude-profile',
|
||||
ANTHROPIC_API_KEY: 'must-not-reach-claude',
|
||||
OPENAI_API_KEY: 'must-not-reach-claude',
|
||||
WAGGLE_FUTURE_PROVIDER_SECRET: 'must-also-be-denied',
|
||||
},
|
||||
isFile: (candidate) => files.has(pathWin32.normalize(candidate).toLowerCase()),
|
||||
});
|
||||
|
||||
expect(launch.command).toBe(process.execPath);
|
||||
expect(launch.args).toEqual([cli, '-p', '--output-format=text']);
|
||||
expect(launch.options.shell).toBe(false);
|
||||
expect(launch.options.env).toMatchObject({
|
||||
PATH: npmRoot,
|
||||
USERPROFILE: 'C:\\Users\\test',
|
||||
APPDATA: 'C:\\Users\\test\\AppData\\Roaming',
|
||||
CLAUDE_CONFIG_DIR: 'C:\\Users\\test\\.claude-profile',
|
||||
HIVE_MIND_NO_SYNTH: '1',
|
||||
});
|
||||
expect(launch.options.env.ANTHROPIC_API_KEY).toBeUndefined();
|
||||
expect(launch.options.env.OPENAI_API_KEY).toBeUndefined();
|
||||
expect(launch.options.env.WAGGLE_FUTURE_PROVIDER_SECRET).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('consolidation GOP anchor', () => {
|
||||
function fixture(): { db: MindDB; frames: FrameStore; sessions: SessionStore } {
|
||||
const db = new MindDB(':memory:');
|
||||
return { db, frames: new FrameStore(db), sessions: new SessionStore(db) };
|
||||
}
|
||||
|
||||
function setCreatedAt(db: MindDB, id: number, createdAt: string): void {
|
||||
db.getDatabase().prepare('UPDATE memory_frames SET created_at = ? WHERE id = ?')
|
||||
.run(createdAt, id);
|
||||
}
|
||||
|
||||
it('ignores a newer excluded-source frame', () => {
|
||||
const { db, frames, sessions } = fixture();
|
||||
try {
|
||||
const target = sessions.create();
|
||||
const decoy = sessions.create();
|
||||
const first = frames.createIFrame(target.gop_id, 'eligible first', 'normal', 'agent_inferred');
|
||||
const second = frames.createIFrame(target.gop_id, 'eligible second', 'normal', 'agent_inferred');
|
||||
const excluded = frames.createIFrame(decoy.gop_id, 'excluded future', 'normal', 'user_stated');
|
||||
setCreatedAt(db, first.id, '2026-01-01 00:00:00');
|
||||
setCreatedAt(db, second.id, '2026-01-02 00:00:00');
|
||||
setCreatedAt(db, excluded.id, '2026-12-01 00:00:00');
|
||||
const observations = collectObservations(db, { limit: 400 });
|
||||
|
||||
expect(resolveConsolidationGop(frames, observations)).toBe(target.gop_id);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('uses canonical offset chronology instead of textual order', () => {
|
||||
const { db, frames, sessions } = fixture();
|
||||
try {
|
||||
const olderSession = sessions.create();
|
||||
const newerSession = sessions.create();
|
||||
const older = frames.createIFrame(olderSession.gop_id, 'older instant', 'normal', 'agent_inferred');
|
||||
const newer = frames.createIFrame(newerSession.gop_id, 'newer instant', 'normal', 'agent_inferred');
|
||||
setCreatedAt(db, older.id, '2026-01-01 01:00:00+0200');
|
||||
setCreatedAt(db, newer.id, '2026-01-01 00:30:00+0100');
|
||||
const observations = collectObservations(db, { limit: 400 });
|
||||
|
||||
expect(resolveConsolidationGop(frames, observations)).toBe(newerSession.gop_id);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('breaks equal-instant ties with the higher frame id', () => {
|
||||
const { db, frames, sessions } = fixture();
|
||||
try {
|
||||
const lowerSession = sessions.create();
|
||||
const higherSession = sessions.create();
|
||||
const lower = frames.createIFrame(lowerSession.gop_id, 'equal lower id', 'normal', 'agent_inferred');
|
||||
const higher = frames.createIFrame(higherSession.gop_id, 'equal higher id', 'normal', 'agent_inferred');
|
||||
setCreatedAt(db, lower.id, '2026-01-01 13:00:00+0100');
|
||||
setCreatedAt(db, higher.id, '2026-01-01 12:00:00Z');
|
||||
const observations = collectObservations(db, { limit: 400 });
|
||||
|
||||
expect(resolveConsolidationGop(frames, observations)).toBe(higherSession.gop_id);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns no anchor when there are no eligible observations', () => {
|
||||
const { db, frames, sessions } = fixture();
|
||||
try {
|
||||
const session = sessions.create();
|
||||
frames.createIFrame(session.gop_id, 'excluded one', 'normal', 'user_stated');
|
||||
frames.createIFrame(session.gop_id, 'excluded two', 'normal', 'user_stated');
|
||||
const observations = collectObservations(db, { limit: 400 });
|
||||
|
||||
expect(observations).toEqual([]);
|
||||
expect(resolveConsolidationGop(frames, observations)).toBeNull();
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseScopes', () => {
|
||||
it('defaults to full read+write when unset', () => {
|
||||
const s = parseScopes(undefined);
|
||||
|
||||
Reference in New Issue
Block a user