

























@@ -14,6 +14,8 @@ const mocks = vi.hoisted(() => ({
1414capEntryCount: vi.fn(),
1515updateSessionStore: vi.fn(),
1616enforceSessionDiskBudget: vi.fn(),
17+callGateway: vi.fn(),
18+isGatewayTransportError: vi.fn(),
1719}));
18201921vi.mock("../config/config.js", () => ({
@@ -37,6 +39,11 @@ vi.mock("../config/sessions.js", () => ({
3739enforceSessionDiskBudget: mocks.enforceSessionDiskBudget,
3840}));
394142+vi.mock("../gateway/call.js", () => ({
43+callGateway: mocks.callGateway,
44+isGatewayTransportError: mocks.isGatewayTransportError,
45+}));
46+4047import { sessionsCleanupCommand } from "./sessions-cleanup.js";
41484249function makeRuntime(): { runtime: RuntimeEnv; logs: string[] } {
@@ -97,6 +104,8 @@ describe("sessionsCleanupCommand", () => {
97104);
98105mocks.capEntryCount.mockImplementation(() => 0);
99106mocks.updateSessionStore.mockResolvedValue(0);
107+mocks.callGateway.mockResolvedValue(null);
108+mocks.isGatewayTransportError.mockReturnValue(true);
100109mocks.enforceSessionDiskBudget.mockResolvedValue({
101110totalBytesBefore: 1000,
102111totalBytesAfter: 700,
@@ -110,6 +119,9 @@ describe("sessionsCleanupCommand", () => {
110119});
111120112121it("emits a single JSON object for non-dry runs and applies maintenance", async () => {
122+mocks.callGateway.mockRejectedValue(
123+Object.assign(new Error("closed"), { name: "GatewayTransportError" }),
124+);
113125mocks.loadSessionStore
114126.mockReturnValueOnce({
115127stale: { sessionId: "stale", updatedAt: 1 },
@@ -190,6 +202,43 @@ describe("sessionsCleanupCommand", () => {
190202);
191203});
192204205+it("delegates non-store enforcing cleanup through the Gateway writer when reachable", async () => {
206+mocks.callGateway.mockResolvedValue({
207+agentId: "main",
208+storePath: "/resolved/sessions.json",
209+mode: "enforce",
210+dryRun: false,
211+beforeCount: 3,
212+afterCount: 1,
213+missing: 0,
214+pruned: 2,
215+capped: 0,
216+diskBudget: null,
217+wouldMutate: true,
218+applied: true,
219+appliedCount: 1,
220+});
221+222+const { runtime, logs } = makeRuntime();
223+await sessionsCleanupCommand(
224+{
225+json: true,
226+enforce: true,
227+},
228+runtime,
229+);
230+231+expect(mocks.callGateway).toHaveBeenCalledWith(
232+expect.objectContaining({
233+method: "sessions.cleanup",
234+params: expect.objectContaining({ enforce: true }),
235+requiredMethods: ["sessions.cleanup"],
236+}),
237+);
238+expect(mocks.updateSessionStore).not.toHaveBeenCalled();
239+expect(JSON.parse(logs[0] ?? "{}")).toEqual(expect.objectContaining({ appliedCount: 1 }));
240+});
241+193242it("returns dry-run JSON without mutating the store", async () => {
194243mocks.loadSessionStore.mockReturnValue({
195244stale: { sessionId: "stale", updatedAt: 1 },
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。