Skip to content

Commit d5154d7

Browse files
committed
Fix fetchUrls preview and isolate session-store tests
1 parent 4b9d5c4 commit d5154d7

3 files changed

Lines changed: 153 additions & 17 deletions

File tree

__tests__/session-store.test.ts

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import os from "node:os";
55
import path from "node:path";
66

77
const SESSION_DB_PATH_ENV = "DAEMON_SESSIONS_DB_PATH";
8+
const CONFIG_DIR_ENV = "DAEMON_CONFIG_DIR";
89

910
async function createTempDir(): Promise<string> {
1011
return await fs.mkdtemp(path.join(os.tmpdir(), "daemon-session-store-"));
1112
}
1213

13-
async function loadSessionStore(dbPath: string) {
14+
async function loadSessionStore(dbPath: string, configDir: string) {
1415
process.env[SESSION_DB_PATH_ENV] = dbPath;
16+
process.env[CONFIG_DIR_ENV] = configDir;
1517
const mod = await import(`../src/state/session-store?test=${crypto.randomUUID()}`);
1618
return mod;
1719
}
@@ -23,9 +25,10 @@ async function cleanupTempDir(dir: string): Promise<void> {
2325
describe("session-store", () => {
2426
it("creates a session with a trimmed title and can list it", async () => {
2527
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
28+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
2629
const tmpDir = await createTempDir();
2730
const dbPath = path.join(tmpDir, "sessions.sqlite");
28-
const store = await loadSessionStore(dbPath);
31+
const store = await loadSessionStore(dbPath, tmpDir);
2932

3033
try {
3134
const created = await store.createSession(" My Title ");
@@ -45,15 +48,21 @@ describe("session-store", () => {
4548
} else {
4649
delete process.env[SESSION_DB_PATH_ENV];
4750
}
51+
if (typeof previousConfigDir === "string") {
52+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
53+
} else {
54+
delete process.env[CONFIG_DIR_ENV];
55+
}
4856
await cleanupTempDir(tmpDir);
4957
}
5058
});
5159

5260
it("sorts sessions by updatedAt descending", async () => {
5361
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
62+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
5463
const tmpDir = await createTempDir();
5564
const dbPath = path.join(tmpDir, "sessions.sqlite");
56-
const store = await loadSessionStore(dbPath);
65+
const store = await loadSessionStore(dbPath, tmpDir);
5766

5867
try {
5968
const a = await store.createSession("A");
@@ -69,15 +78,21 @@ describe("session-store", () => {
6978
} else {
7079
delete process.env[SESSION_DB_PATH_ENV];
7180
}
81+
if (typeof previousConfigDir === "string") {
82+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
83+
} else {
84+
delete process.env[CONFIG_DIR_ENV];
85+
}
7286
await cleanupTempDir(tmpDir);
7387
}
7488
});
7589

7690
it("saves and loads snapshots, preserving createdAt across updates", async () => {
7791
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
92+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
7893
const tmpDir = await createTempDir();
7994
const dbPath = path.join(tmpDir, "sessions.sqlite");
80-
const store = await loadSessionStore(dbPath);
95+
const store = await loadSessionStore(dbPath, tmpDir);
8196

8297
try {
8398
const session = await store.createSession("Snapshot Session");
@@ -124,15 +139,21 @@ describe("session-store", () => {
124139
} else {
125140
delete process.env[SESSION_DB_PATH_ENV];
126141
}
142+
if (typeof previousConfigDir === "string") {
143+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
144+
} else {
145+
delete process.env[CONFIG_DIR_ENV];
146+
}
127147
await cleanupTempDir(tmpDir);
128148
}
129149
});
130150

131151
it("updates titles and bumps updatedAt", async () => {
132152
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
153+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
133154
const tmpDir = await createTempDir();
134155
const dbPath = path.join(tmpDir, "sessions.sqlite");
135-
const store = await loadSessionStore(dbPath);
156+
const store = await loadSessionStore(dbPath, tmpDir);
136157

137158
try {
138159
const session = await store.createSession("Initial");
@@ -150,15 +171,21 @@ describe("session-store", () => {
150171
} else {
151172
delete process.env[SESSION_DB_PATH_ENV];
152173
}
174+
if (typeof previousConfigDir === "string") {
175+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
176+
} else {
177+
delete process.env[CONFIG_DIR_ENV];
178+
}
153179
await cleanupTempDir(tmpDir);
154180
}
155181
});
156182

157183
it("falls back to a formatted title when the stored title is blank", async () => {
158184
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
185+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
159186
const tmpDir = await createTempDir();
160187
const dbPath = path.join(tmpDir, "sessions.sqlite");
161-
const store = await loadSessionStore(dbPath);
188+
const store = await loadSessionStore(dbPath, tmpDir);
162189

163190
try {
164191
const session = await store.createSession("Will Clear");
@@ -174,15 +201,21 @@ describe("session-store", () => {
174201
} else {
175202
delete process.env[SESSION_DB_PATH_ENV];
176203
}
204+
if (typeof previousConfigDir === "string") {
205+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
206+
} else {
207+
delete process.env[CONFIG_DIR_ENV];
208+
}
177209
await cleanupTempDir(tmpDir);
178210
}
179211
});
180212

181213
it("returns null for missing sessions and deletes sessions on clear", async () => {
182214
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
215+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
183216
const tmpDir = await createTempDir();
184217
const dbPath = path.join(tmpDir, "sessions.sqlite");
185-
const store = await loadSessionStore(dbPath);
218+
const store = await loadSessionStore(dbPath, tmpDir);
186219

187220
try {
188221
expect(await store.loadSessionSnapshot("missing")).toBeNull();
@@ -203,15 +236,21 @@ describe("session-store", () => {
203236
} else {
204237
delete process.env[SESSION_DB_PATH_ENV];
205238
}
239+
if (typeof previousConfigDir === "string") {
240+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
241+
} else {
242+
delete process.env[CONFIG_DIR_ENV];
243+
}
206244
await cleanupTempDir(tmpDir);
207245
}
208246
});
209247

210248
it("tolerates corrupted history_json and usage_json values", async () => {
211249
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
250+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
212251
const tmpDir = await createTempDir();
213252
const dbPath = path.join(tmpDir, "sessions.sqlite");
214-
const store = await loadSessionStore(dbPath);
253+
const store = await loadSessionStore(dbPath, tmpDir);
215254

216255
try {
217256
const session = await store.createSession("Corrupt");
@@ -223,7 +262,7 @@ describe("session-store", () => {
223262
database.close();
224263

225264
store.closeSessionStore();
226-
const reopened = await loadSessionStore(dbPath);
265+
const reopened = await loadSessionStore(dbPath, tmpDir);
227266
const snapshot = await reopened.loadSessionSnapshot(session.id);
228267
expect(snapshot).not.toBeNull();
229268
expect(snapshot?.conversationHistory).toEqual([]);
@@ -236,15 +275,21 @@ describe("session-store", () => {
236275
} else {
237276
delete process.env[SESSION_DB_PATH_ENV];
238277
}
278+
if (typeof previousConfigDir === "string") {
279+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
280+
} else {
281+
delete process.env[CONFIG_DIR_ENV];
282+
}
239283
await cleanupTempDir(tmpDir);
240284
}
241285
});
242286

243287
it("flattens model messages from the conversation history", async () => {
244288
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
289+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
245290
const tmpDir = await createTempDir();
246291
const dbPath = path.join(tmpDir, "sessions.sqlite");
247-
const store = await loadSessionStore(dbPath);
292+
const store = await loadSessionStore(dbPath, tmpDir);
248293

249294
try {
250295
const result = store.buildModelHistoryFromConversation([
@@ -272,15 +317,21 @@ describe("session-store", () => {
272317
} else {
273318
delete process.env[SESSION_DB_PATH_ENV];
274319
}
320+
if (typeof previousConfigDir === "string") {
321+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
322+
} else {
323+
delete process.env[CONFIG_DIR_ENV];
324+
}
275325
await cleanupTempDir(tmpDir);
276326
}
277327
});
278328

279329
it("saves and retrieves grounding maps", async () => {
280330
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
331+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
281332
const tmpDir = await createTempDir();
282333
const dbPath = path.join(tmpDir, "sessions.sqlite");
283-
const store = await loadSessionStore(dbPath);
334+
const store = await loadSessionStore(dbPath, tmpDir);
284335

285336
try {
286337
const session = await store.createSession("Grounding Test");
@@ -317,15 +368,21 @@ describe("session-store", () => {
317368
} else {
318369
delete process.env[SESSION_DB_PATH_ENV];
319370
}
371+
if (typeof previousConfigDir === "string") {
372+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
373+
} else {
374+
delete process.env[CONFIG_DIR_ENV];
375+
}
320376
await cleanupTempDir(tmpDir);
321377
}
322378
});
323379

324380
it("lists grounding maps for a session in descending order", async () => {
325381
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
382+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
326383
const tmpDir = await createTempDir();
327384
const dbPath = path.join(tmpDir, "sessions.sqlite");
328-
const store = await loadSessionStore(dbPath);
385+
const store = await loadSessionStore(dbPath, tmpDir);
329386

330387
try {
331388
const session = await store.createSession("Grounding List Test");
@@ -347,15 +404,21 @@ describe("session-store", () => {
347404
} else {
348405
delete process.env[SESSION_DB_PATH_ENV];
349406
}
407+
if (typeof previousConfigDir === "string") {
408+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
409+
} else {
410+
delete process.env[CONFIG_DIR_ENV];
411+
}
350412
await cleanupTempDir(tmpDir);
351413
}
352414
});
353415

354416
it("loads the latest grounding map for a session", async () => {
355417
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
418+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
356419
const tmpDir = await createTempDir();
357420
const dbPath = path.join(tmpDir, "sessions.sqlite");
358-
const store = await loadSessionStore(dbPath);
421+
const store = await loadSessionStore(dbPath, tmpDir);
359422

360423
try {
361424
const session = await store.createSession("Latest Grounding Test");
@@ -377,15 +440,21 @@ describe("session-store", () => {
377440
} else {
378441
delete process.env[SESSION_DB_PATH_ENV];
379442
}
443+
if (typeof previousConfigDir === "string") {
444+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
445+
} else {
446+
delete process.env[CONFIG_DIR_ENV];
447+
}
380448
await cleanupTempDir(tmpDir);
381449
}
382450
});
383451

384452
it("returns null when no grounding maps exist for session", async () => {
385453
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
454+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
386455
const tmpDir = await createTempDir();
387456
const dbPath = path.join(tmpDir, "sessions.sqlite");
388-
const store = await loadSessionStore(dbPath);
457+
const store = await loadSessionStore(dbPath, tmpDir);
389458

390459
try {
391460
const session = await store.createSession("Empty Grounding Test");
@@ -401,15 +470,21 @@ describe("session-store", () => {
401470
} else {
402471
delete process.env[SESSION_DB_PATH_ENV];
403472
}
473+
if (typeof previousConfigDir === "string") {
474+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
475+
} else {
476+
delete process.env[CONFIG_DIR_ENV];
477+
}
404478
await cleanupTempDir(tmpDir);
405479
}
406480
});
407481

408482
it("tolerates corrupted items_json in grounding maps", async () => {
409483
const previousDbPath = process.env[SESSION_DB_PATH_ENV];
484+
const previousConfigDir = process.env[CONFIG_DIR_ENV];
410485
const tmpDir = await createTempDir();
411486
const dbPath = path.join(tmpDir, "sessions.sqlite");
412-
const store = await loadSessionStore(dbPath);
487+
const store = await loadSessionStore(dbPath, tmpDir);
413488

414489
try {
415490
const session = await store.createSession("Corrupt Grounding");
@@ -424,7 +499,7 @@ describe("session-store", () => {
424499
database.close();
425500

426501
store.closeSessionStore();
427-
const reopened = await loadSessionStore(dbPath);
502+
const reopened = await loadSessionStore(dbPath, tmpDir);
428503
const latest = await reopened.loadLatestGroundingMap(session.id);
429504
expect(latest).not.toBeNull();
430505
expect(latest?.items).toEqual([]);
@@ -436,6 +511,11 @@ describe("session-store", () => {
436511
} else {
437512
delete process.env[SESSION_DB_PATH_ENV];
438513
}
514+
if (typeof previousConfigDir === "string") {
515+
process.env[CONFIG_DIR_ENV] = previousConfigDir;
516+
} else {
517+
delete process.env[CONFIG_DIR_ENV];
518+
}
439519
await cleanupTempDir(tmpDir);
440520
}
441521
});

src/utils/preferences.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const PREFERENCES_VERSION = 1;
1212
const APP_DIR_NAME = "daemon";
1313
const PREFERENCES_FILE = "preferences.json";
1414
const CREDENTIALS_FILE = "credentials.json";
15+
const CONFIG_DIR_ENV = "DAEMON_CONFIG_DIR";
1516

1617
/** Keys that belong in credentials.json (secrets) vs preferences.json (settings) */
1718
const CREDENTIAL_KEYS = ["openRouterApiKey", "openAiApiKey", "exaApiKey"] as const;
@@ -32,6 +33,8 @@ function getBaseConfigDir(): string {
3233
}
3334

3435
export function getAppConfigDir(): string {
36+
const override = process.env[CONFIG_DIR_ENV]?.trim();
37+
if (override) return override;
3538
return path.join(getBaseConfigDir(), APP_DIR_NAME);
3639
}
3740

0 commit comments

Comments
 (0)