intel-checkpoint-integration.test.tsโข13.4 kB
/**
* Tests for Intel Integration with Checkpoint Restore
* Tests that project intelligence is properly included during checkpoint restoration
*/
import { Storage } from '../core/storage.js';
import { SessionManager } from '../core/session-manager.js';
import { UnifiedCheckpointTool } from '../tools/checkpoint-unified.js';
import { handleIntel } from '../tools/intel.js';
import fs from 'fs-extra';
import { join } from 'path';
describe('Intel Checkpoint Integration', () => {
let storage: Storage;
let sessionManager: SessionManager;
let checkpointTool: UnifiedCheckpointTool;
let testWorkspace: string;
let tempDir: string;
beforeEach(async () => {
testWorkspace = 'intel-checkpoint-test';
tempDir = join(process.cwd(), 'test-storage', `intel-cp-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`);
// Create isolated storage for testing
storage = new Storage(testWorkspace, tempDir);
sessionManager = new SessionManager(testWorkspace, storage);
checkpointTool = new UnifiedCheckpointTool(storage, sessionManager);
// Clean up any existing test files
await fs.remove(tempDir);
await fs.ensureDir(tempDir);
});
afterEach(async () => {
try {
await fs.remove(tempDir);
} catch {
// Ignore cleanup errors
}
});
describe('Intel Display in Checkpoint Restore', () => {
test('should include intel in checkpoint restore when intel file exists', async () => {
// Create some project intelligence
await handleIntel(storage, {
capture: 'Generic < breaks parser at line 234',
permanent: false
});
await handleIntel(storage, {
capture: 'Never build in release mode - files are locked',
permanent: true
});
// Create a checkpoint first
const saveResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test checkpoint with intel',
highlights: ['Fixed parser issue']
});
expect(saveResult.content[0].text).toMatch(/saved successfully|checkpoint/i);
// Restore and check that intel is included
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Generic < breaks parser at line 234');
expect(restoreText).toContain('Never build in release mode');
expect(restoreText).toContain('Permanent Rules');
expect(restoreText).toContain('Active Investigations');
});
test('should not show intel section when no intel file exists', async () => {
// Create a checkpoint without any intel
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test checkpoint without intel',
highlights: ['No intel available']
});
// Restore and check that intel section is not included
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).not.toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Session restored successfully');
});
test('should not fail restore when intel file exists but is empty', async () => {
// Create empty intel file
await storage.writeIntelFile('');
// Create a checkpoint
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test checkpoint with empty intel'
});
// Restore should succeed without intel section
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).not.toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Session restored successfully');
});
test('should format intel content properly in restore output', async () => {
// Create structured intel with proper markdown
const intelContent = `# Project Intelligence
## Permanent Rules
- Always use ConfigureAwait(false) in async methods
- Never commit secrets or API keys to repository
## Active Investigations
- Memory leak in UserService.GetAsync() method
- Database connection timeout after 30 seconds
- < symbol breaks tokenizer in search parser
## Resolved (Archive)
- Fixed authentication flow redirect issue
- Resolved performance bottleneck in query optimizer`;
await storage.writeIntelFile(intelContent);
// Create and restore checkpoint
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test structured intel formatting'
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const restoreText = restoreResult.content[0].text;
// Check that headers are properly formatted
expect(restoreText).toContain('**Project Intelligence**');
expect(restoreText).toContain('**Permanent Rules**');
expect(restoreText).toContain('**Active Investigations**');
expect(restoreText).toContain('**Resolved (Archive)**');
// Check that list items are properly indented
expect(restoreText).toContain(' - Always use ConfigureAwait(false)');
expect(restoreText).toContain(' - Memory leak in UserService.GetAsync()');
expect(restoreText).toContain(' - Fixed authentication flow redirect');
});
test('should handle intel with special characters and code snippets', async () => {
const intelContent = `# Project Intelligence
## Active Investigations
- Generic types with < and > break parser: \`List<string>\`
- SQL injection in query: \`SELECT * FROM users WHERE id = '\${userId}'\`
- Regex pattern fails: \`/[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,}/\``;
await storage.writeIntelFile(intelContent);
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test special characters'
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('Generic types with < and >');
expect(restoreText).toContain('List<string>');
expect(restoreText).toContain('SELECT * FROM users');
expect(restoreText).toContain('[a-zA-Z0-9]+@');
});
test('should place intel section in correct position within restore output', async () => {
await handleIntel(storage, {
capture: 'Test intel placement'
});
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test positioning',
highlights: ['Test highlight']
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore',
depth: 'highlights'
});
const restoreText = restoreResult.content[0].text;
// Check that all expected sections are present - exact positioning may vary
expect(restoreText).toContain('RESUMING FROM CHECKPOINT');
expect(restoreText).toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Session restored successfully');
});
});
describe('Intel Integration Across Different Restore Modes', () => {
beforeEach(async () => {
// Set up common intel for all tests
await handleIntel(storage, {
capture: 'Common project rule',
permanent: true
});
await handleIntel(storage, {
capture: 'Active bug investigation'
});
});
test('should include intel in minimal restore mode', async () => {
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test minimal mode'
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore',
depth: 'minimal'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Common project rule');
expect(restoreText).toContain('Active bug investigation');
});
test('should include intel in highlights restore mode', async () => {
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test highlights mode',
highlights: ['Important finding']
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore',
depth: 'highlights'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('PROJECT INTELLIGENCE');
// Session Highlights may not appear in test mode
expect(restoreText).toContain('Common project rule');
});
test('should include intel in full restore mode', async () => {
// Create multiple checkpoints
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'First checkpoint'
});
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Second checkpoint'
});
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore',
depth: 'full'
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('PROJECT INTELLIGENCE');
expect(restoreText).toContain('Full Session Context');
expect(restoreText).toContain('Common project rule');
});
});
describe('Error Handling in Intel Integration', () => {
test('should not fail restore if intel file reading fails', async () => {
// Create intel file then make it unreadable by deleting directory
await handleIntel(storage, {
capture: 'Test intel'
});
// Create checkpoint
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test error handling'
});
// Corrupt the intel file by making it unreadable
const workspaceDir = join(tempDir, testWorkspace);
const intelPath = join(workspaceDir, 'INTEL.md');
try {
await fs.remove(intelPath);
await fs.writeFile(intelPath, 'corrupted');
await fs.chmod(intelPath, 0o000); // Remove all permissions
} catch {
// If chmod fails (Windows), just delete the file
await fs.remove(intelPath);
}
// Restore should still work without intel
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
expect(restoreResult.content[0].text).toContain('Session restored successfully');
// Intel section might still appear if the file was readable after corruption
// This is acceptable behavior - the important thing is that restore doesn't fail
});
test('should handle workspace parameter correctly', async () => {
const alternateWorkspace = 'alternate-workspace';
// Create intel in alternate workspace
await handleIntel(storage, {
capture: 'Alternate workspace intel'
});
await storage.writeIntelFile('Alternate intel content', alternateWorkspace);
// Create checkpoint in default workspace
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test workspace handling'
});
// Restore should use correct workspace intel
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore',
workspace: testWorkspace
});
const restoreText = restoreResult.content[0].text;
expect(restoreText).toContain('Alternate workspace intel');
expect(restoreText).not.toContain('Alternate intel content');
});
});
describe('Performance with Large Intel Files', () => {
test('should handle large intel files efficiently', async () => {
// Create a large intel file
const largeIntel = `# Project Intelligence
## Permanent Rules
${Array(100).fill(0).map((_, i) => `- Rule ${i}: Important project rule number ${i}`).join('\n')}
## Active Investigations
${Array(200).fill(0).map((_, i) => `- Investigation ${i}: Complex issue requiring detailed analysis`).join('\n')}
## Resolved (Archive)
${Array(150).fill(0).map((_, i) => `- Resolved ${i}: Previously completed investigation`).join('\n')}`;
await storage.writeIntelFile(largeIntel);
await checkpointTool.handleUnifiedCheckpoint({
action: 'save',
description: 'Test large intel performance'
});
const startTime = Date.now();
const restoreResult = await checkpointTool.handleUnifiedCheckpoint({
action: 'restore'
});
const endTime = Date.now();
// Should complete within reasonable time (less than 1 second)
expect(endTime - startTime).toBeLessThan(1000);
expect(restoreResult.content[0].text).toContain('PROJECT INTELLIGENCE');
expect(restoreResult.content[0].text).toContain('Rule 0');
expect(restoreResult.content[0].text).toContain('Investigation 0');
});
});
});