98 lines
3.0 KiB
TypeScript
98 lines
3.0 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 {
|
|
loadEntriesFromFile,
|
|
type SessionHeader,
|
|
SessionManager,
|
|
} from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
|
import { getConfigRootDir, setAgentDir } from "@oh-my-pi/pi-utils";
|
|
|
|
function makeAssistantMessage() {
|
|
return {
|
|
role: "assistant" as const,
|
|
content: [{ type: "text" as const, text: "ok" }],
|
|
api: "anthropic-messages" as const,
|
|
provider: "anthropic" as const,
|
|
model: "claude-sonnet-4-20250514",
|
|
usage: {
|
|
input: 1,
|
|
output: 1,
|
|
cacheRead: 0,
|
|
cacheWrite: 0,
|
|
totalTokens: 2,
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
},
|
|
stopReason: "stop" as const,
|
|
timestamp: Date.now(),
|
|
};
|
|
}
|
|
|
|
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;
|
|
}
|
|
fs.rmSync(testAgentDir, { recursive: true, force: true });
|
|
});
|
|
|
|
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");
|
|
});
|
|
});
|