Skip to content

Commit 71700c4

Browse files
refactor(context): consolidate bridge and compaction into enhanced modules
- Merge context-bridge.ts into shared-context-layer.ts - Merge compaction-handler.ts into enhanced-rehydration.ts - Update tests to reflect new file structure - Remove 778 lines of duplicate code
1 parent 0a02ec3 commit 71700c4

6 files changed

Lines changed: 1117 additions & 987 deletions

File tree

src/__tests__/integration/helpers/test-environment.ts

Lines changed: 92 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
* Provides isolated test environments for integration testing
44
*/
55

6-
import { SQLiteAdapter, SQLiteConfig } from '../../../core/database/sqlite-adapter.js';
6+
import {
7+
SQLiteAdapter,
8+
SQLiteConfig,
9+
} from '../../../core/database/sqlite-adapter.js';
710
import { FrameManager } from '../../../core/context/index.js';
8-
import { SharedContextLayer } from '../../../core/context/shared-context-layer.js';
9-
import { ContextBridge } from '../../../core/context/context-bridge.js';
11+
import {
12+
SharedContextLayer,
13+
ContextBridge,
14+
} from '../../../core/context/shared-context-layer.js';
1015
import { ContextRetriever } from '../../../core/retrieval/context-retriever.js';
1116
import { QueryRouter } from '../../../core/database/query-router.js';
1217
import { execSync } from 'child_process';
@@ -19,7 +24,7 @@ export interface TestSession {
1924
sharedContext: SharedContextLayer;
2025
contextBridge?: ContextBridge;
2126
retriever: ContextRetriever;
22-
27+
2328
recordActivity(activities: ActivityRecord[]): Promise<string[]>;
2429
saveContext(): Promise<SavedContext>;
2530
generateHandoff(): Promise<string>;
@@ -50,10 +55,18 @@ export class TestEnvironment {
5055

5156
private constructor(projectId: string) {
5257
this.projectId = projectId;
53-
this.tempDir = path.join(os.tmpdir(), `stackmemory-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
54-
this.dbPath = path.join(this.tempDir, '.stackmemory', 'db', 'stackmemory.db');
58+
this.tempDir = path.join(
59+
os.tmpdir(),
60+
`stackmemory-test-${Date.now()}-${Math.random().toString(36).slice(2)}`
61+
);
62+
this.dbPath = path.join(
63+
this.tempDir,
64+
'.stackmemory',
65+
'db',
66+
'stackmemory.db'
67+
);
5568
this.cliPath = path.join(process.cwd(), 'dist', 'cli', 'index.js');
56-
69+
5770
// Adapter will be created after directories are set up
5871
this.adapter = null as any; // Will be initialized in setup()
5972
}
@@ -66,20 +79,26 @@ export class TestEnvironment {
6679

6780
private async setup(): Promise<void> {
6881
// Create directory structure
69-
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'db'), { recursive: true });
70-
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'contexts'), { recursive: true });
71-
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'handoffs'), { recursive: true });
72-
82+
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'db'), {
83+
recursive: true,
84+
});
85+
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'contexts'), {
86+
recursive: true,
87+
});
88+
fs.mkdirSync(path.join(this.tempDir, '.stackmemory', 'handoffs'), {
89+
recursive: true,
90+
});
91+
7392
// Create adapter with test configuration
7493
const config: SQLiteConfig = {
7594
dbPath: this.dbPath,
7695
walMode: false, // Disable for testing
7796
busyTimeout: 5000,
7897
synchronous: 'NORMAL',
7998
};
80-
99+
81100
this.adapter = new SQLiteAdapter(this.projectId, config);
82-
101+
83102
// Initialize database
84103
await this.adapter.connect();
85104
await this.adapter.initializeSchema();
@@ -104,7 +123,7 @@ export class TestEnvironment {
104123
path: this.dbPath,
105124
},
106125
};
107-
126+
108127
fs.writeFileSync(
109128
path.join(this.tempDir, 'stackmemory.json'),
110129
JSON.stringify(config, null, 2)
@@ -114,12 +133,18 @@ export class TestEnvironment {
114133
async createProject(name: string): Promise<{ id: string; path: string }> {
115134
const projectPath = path.join(this.tempDir, name);
116135
fs.mkdirSync(projectPath, { recursive: true });
117-
136+
118137
// Initialize git repo
119138
execSync('git init', { cwd: projectPath, stdio: 'pipe' });
120-
execSync('git config user.email "test@example.com"', { cwd: projectPath, stdio: 'pipe' });
121-
execSync('git config user.name "Test User"', { cwd: projectPath, stdio: 'pipe' });
122-
139+
execSync('git config user.email "test@example.com"', {
140+
cwd: projectPath,
141+
stdio: 'pipe',
142+
});
143+
execSync('git config user.name "Test User"', {
144+
cwd: projectPath,
145+
stdio: 'pipe',
146+
});
147+
123148
return {
124149
id: `${this.projectId}-${name}`,
125150
path: projectPath,
@@ -128,7 +153,7 @@ export class TestEnvironment {
128153

129154
async startSession(sessionId?: string): Promise<TestSession> {
130155
const id = sessionId || `session-${Date.now()}`;
131-
156+
132157
// Create FrameManager without auto-initialization
133158
const frameManager = Object.create(FrameManager.prototype);
134159
Object.assign(frameManager, {
@@ -141,94 +166,97 @@ export class TestEnvironment {
141166
maxDepth: 10,
142167
},
143168
});
144-
169+
145170
const sharedContext = new SharedContextLayer({
146171
projectId: this.projectId,
147172
maxSharedFrames: 100,
148173
syncInterval: 1000,
149174
});
150-
175+
151176
const retriever = new ContextRetriever(this.adapter);
152-
177+
153178
const session: TestSession = {
154179
frameManager,
155180
sharedContext,
156181
retriever,
157-
182+
158183
recordActivity: async (activities: ActivityRecord[]) => {
159184
const frameIds: string[] = [];
160-
185+
161186
for (const activity of activities) {
162187
const frameId = await this.adapter.createFrame({
163188
parent_frame_id: frameIds[frameIds.length - 1] || null,
164189
project_id: this.projectId,
165190
run_id: id,
166191
type: activity.type === 'error' ? 'error' : 'operation',
167192
name: this.getActivityName(activity),
168-
state: activity.type === 'error' || activity.status === 'fail' ? 'error' : 'completed',
193+
state:
194+
activity.type === 'error' || activity.status === 'fail'
195+
? 'error'
196+
: 'completed',
169197
depth: frameIds.length,
170198
digest_text: this.getActivityDigest(activity),
171199
});
172-
200+
173201
frameIds.push(frameId);
174202
}
175-
203+
176204
return frameIds;
177205
},
178-
206+
179207
saveContext: async () => {
180208
const frames = await this.adapter.search({
181209
query: '',
182210
searchType: 'recent',
183211
limit: 100,
184212
});
185-
213+
186214
const context: SavedContext = {
187215
frames,
188216
timestamp: Date.now(),
189217
sessionId: id,
190218
};
191-
219+
192220
// Save to file for persistence testing
193221
fs.writeFileSync(
194222
path.join(this.tempDir, '.stackmemory', 'contexts', `${id}.json`),
195223
JSON.stringify(context, null, 2)
196224
);
197-
225+
198226
return context;
199227
},
200-
228+
201229
generateHandoff: async () => {
202230
const frames = await this.adapter.search({
203231
query: '',
204232
searchType: 'recent',
205233
limit: 50,
206234
});
207-
235+
208236
let handoff = '# Session Handoff\n\n';
209237
handoff += '## Session Summary\n\n';
210238
handoff += `- Session ID: ${id}\n`;
211239
handoff += `- Total Frames: ${frames.length}\n`;
212240
handoff += `- Timestamp: ${new Date().toISOString()}\n\n`;
213-
241+
214242
handoff += '## Activity Log\n\n';
215243
for (const frame of frames) {
216244
handoff += `- [${frame.type}] ${frame.name}\n`;
217245
if (frame.digest_text) {
218246
handoff += ` ${frame.digest_text}\n`;
219247
}
220248
}
221-
249+
222250
// Save handoff
223251
fs.writeFileSync(
224252
path.join(this.tempDir, '.stackmemory', 'handoffs', `${id}.md`),
225253
handoff
226254
);
227-
255+
228256
return handoff;
229257
},
230258
};
231-
259+
232260
this.sessions.set(id, session);
233261
return session;
234262
}
@@ -241,27 +269,39 @@ export class TestEnvironment {
241269
if ((session.frameManager as any).frames) {
242270
(session.frameManager as any).frames.clear();
243271
}
244-
272+
245273
// SharedContextLayer doesn't have a clear method, so we just reset the sessions
246274
// The context is persisted in files/database anyway
247275
}
248276
}
249277

250278
async restoreContext(sessionId?: string): Promise<SavedContext> {
251-
const contextFiles = fs.readdirSync(path.join(this.tempDir, '.stackmemory', 'contexts'));
252-
279+
const contextFiles = fs.readdirSync(
280+
path.join(this.tempDir, '.stackmemory', 'contexts')
281+
);
282+
253283
if (sessionId) {
254-
const contextPath = path.join(this.tempDir, '.stackmemory', 'contexts', `${sessionId}.json`);
284+
const contextPath = path.join(
285+
this.tempDir,
286+
'.stackmemory',
287+
'contexts',
288+
`${sessionId}.json`
289+
);
255290
return JSON.parse(fs.readFileSync(contextPath, 'utf8'));
256291
}
257-
292+
258293
// Return most recent context
259294
if (contextFiles.length > 0) {
260295
const latestFile = contextFiles.sort().pop()!;
261-
const contextPath = path.join(this.tempDir, '.stackmemory', 'contexts', latestFile);
296+
const contextPath = path.join(
297+
this.tempDir,
298+
'.stackmemory',
299+
'contexts',
300+
latestFile
301+
);
262302
return JSON.parse(fs.readFileSync(contextPath, 'utf8'));
263303
}
264-
304+
265305
return {
266306
frames: [],
267307
timestamp: Date.now(),
@@ -280,7 +320,9 @@ export class TestEnvironment {
280320
},
281321
});
282322
} catch (error: any) {
283-
throw new Error(`CLI command failed: ${error.message}\nOutput: ${error.stdout || error.stderr}`);
323+
throw new Error(
324+
`CLI command failed: ${error.message}\nOutput: ${error.stdout || error.stderr}`
325+
);
284326
}
285327
}
286328

@@ -290,7 +332,7 @@ export class TestEnvironment {
290332

291333
async createQueryRouter(): Promise<QueryRouter> {
292334
const router = new QueryRouter();
293-
335+
294336
router.registerTier({
295337
name: 'sqlite',
296338
adapter: this.adapter,
@@ -302,7 +344,7 @@ export class TestEnvironment {
302344
routingRules: [],
303345
},
304346
});
305-
347+
306348
return router;
307349
}
308350

@@ -313,12 +355,12 @@ export class TestEnvironment {
313355
session.contextBridge.stop();
314356
}
315357
}
316-
358+
317359
// Disconnect database
318360
if (this.adapter) {
319361
await this.adapter.disconnect();
320362
}
321-
363+
322364
// Remove temp directory
323365
if (fs.existsSync(this.tempDir)) {
324366
fs.rmSync(this.tempDir, { recursive: true, force: true });
@@ -362,4 +404,4 @@ export class TestEnvironment {
362404
return '';
363405
}
364406
}
365-
}
407+
}

0 commit comments

Comments
 (0)