Files
oh-my-pi/packages/coding-agent/test/session-manager/title-source-persistence.test.ts
T
oldschoola a2854ba768 fix: migrate coding-agent tests from fs.rm to removeWithRetries
Migrate 203 test files (356 call sites) from fs.rm/fs.rmSync to
removeWithRetries/removeSyncWithRetries to reduce EBUSY test failures
on Windows. removeWithRetries is now exported from @oh-my-pi/pi-utils.

The migration uses a regex-based approach that:
- Replaces fs.rm(path, { recursive, force }) → removeWithRetries(path)
- Replaces fs.rmSync(path, { recursive, force }) → removeSyncWithRetries(path)
- Replaces fs.rm(path) → removeWithRetries(path) (no options)
- Skips fs.rm/fs.rmSync inside template literals (bun --eval scripts)
- Adds imports to existing @oh-my-pi/pi-utils import or creates new one
- Removes unused fs imports where fs.rm was the only fs usage (4 files)
2026-06-23 15:28:05 -07:00

101 lines
3.6 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from "bun:test";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import type { SessionHeader } from "@oh-my-pi/pi-coding-agent/session/session-entries";
import { loadEntriesFromFile } from "@oh-my-pi/pi-coding-agent/session/session-loader";
import { SessionManager } from "@oh-my-pi/pi-coding-agent/session/session-manager";
import { getConfigRootDir, removeSyncWithRetries, setAgentDir } from "@oh-my-pi/pi-utils";
import { makeAssistantMessage } from "./helpers";
function getHeader(entries: unknown[]): SessionHeader | undefined {
return entries.find(
(entry): entry is SessionHeader =>
typeof entry === "object" && entry !== null && "type" in entry && entry.type === "session",
);
}
describe("session title source persistence", () => {
let testAgentDir: string;
let cwd: string;
const originalAgentDir = process.env.PI_CODING_AGENT_DIR;
const fallbackAgentDir = path.join(getConfigRootDir(), "agent");
beforeEach(() => {
testAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "omp-title-source-"));
cwd = path.join(testAgentDir, "cwd");
fs.mkdirSync(cwd, { recursive: true });
setAgentDir(testAgentDir);
});
afterEach(() => {
if (originalAgentDir) {
setAgentDir(originalAgentDir);
} else {
setAgentDir(fallbackAgentDir);
delete process.env.PI_CODING_AGENT_DIR;
}
removeSyncWithRetries(testAgentDir);
});
it("persists auto title source across reopen", async () => {
const session = SessionManager.create(cwd);
session.appendMessage({ role: "user", content: "hello", timestamp: 1 });
await session.setSessionName("Auto title", "auto");
session.appendMessage(makeAssistantMessage());
await session.flush();
const sessionFile = session.getSessionFile();
expect(sessionFile).toBeDefined();
const entries = await loadEntriesFromFile(sessionFile!);
expect(getHeader(entries)?.titleSource).toBe("auto");
const reopened = await SessionManager.open(sessionFile!);
expect(reopened.getSessionName()).toBe("Auto title");
expect(reopened.titleSource).toBe("auto");
});
it("persists user title source across reopen", async () => {
const session = SessionManager.create(cwd);
session.appendMessage({ role: "user", content: "hello", timestamp: 1 });
await session.setSessionName("Manual title", "user");
session.appendMessage(makeAssistantMessage());
await session.flush();
const sessionFile = session.getSessionFile();
expect(sessionFile).toBeDefined();
const entries = await loadEntriesFromFile(sessionFile!);
expect(getHeader(entries)?.titleSource).toBe("user");
const reopened = await SessionManager.open(sessionFile!);
expect(reopened.getSessionName()).toBe("Manual title");
expect(reopened.titleSource).toBe("user");
});
it("notifies name-change subscribers only after successful applied names", async () => {
const session = SessionManager.inMemory(cwd);
const names: Array<string | undefined> = [];
const unsubscribe = session.onSessionNameChanged(() => {
names.push(session.getSessionName());
});
try {
await expect(session.setSessionName(" ", "user")).resolves.toBe(false);
expect(names).toEqual([]);
await expect(session.setSessionName("Manual title", "user")).resolves.toBe(true);
expect(names).toEqual(["Manual title"]);
await expect(session.setSessionName("Ignored auto title", "auto")).resolves.toBe(false);
expect(names).toEqual(["Manual title"]);
} finally {
unsubscribe();
}
await expect(session.setSessionName("Second title", "user")).resolves.toBe(true);
expect(names).toEqual(["Manual title"]);
});
});