diff --git a/extensions/cli/package-lock.json b/extensions/cli/package-lock.json index 5ee422523d2..e645f43949d 100644 --- a/extensions/cli/package-lock.json +++ b/extensions/cli/package-lock.json @@ -184,6 +184,7 @@ "system-ca": "^1.0.3", "tar": "^7.4.3", "tree-sitter-wasms": "^0.1.11", + "untildify": "^6.0.0", "uuid": "^9.0.1", "vectordb": "^0.4.20", "web-tree-sitter": "^0.21.0", @@ -274,7 +275,7 @@ "@aws-sdk/credential-providers": "^3.840.0", "@continuedev/config-types": "^1.0.14", "@continuedev/config-yaml": "^1.14.0", - "@continuedev/fetch": "^1.1.0", + "@continuedev/fetch": "^1.5.0", "dotenv": "^16.5.0", "google-auth-library": "^10.1.0", "json-schema": "^0.4.0", diff --git a/extensions/cli/src/session.test.ts b/extensions/cli/src/session.test.ts index 0fb5f452537..9ca3b4bd597 100644 --- a/extensions/cli/src/session.test.ts +++ b/extensions/cli/src/session.test.ts @@ -360,7 +360,7 @@ describe("SessionManager", () => { const firstSession = createSession(); const firstSessionId = firstSession.sessionId; - vi.mocked(uuidv4).mockReturnValue("new-uuid-456" as any); + vi.mocked(uuidv4).mockReturnValue("new-uuid-456"); const secondSession = startNewSession(); @@ -381,7 +381,7 @@ describe("SessionManager", () => { }, ]; - vi.mocked(uuidv4).mockReturnValue("new-uuid-789" as any); + vi.mocked(uuidv4).mockReturnValue("new-uuid-789"); const session = startNewSession(history); @@ -392,7 +392,7 @@ describe("SessionManager", () => { it("should set the new session as current", () => { const originalSession = createSession(); - vi.mocked(uuidv4).mockReturnValue("new-session-id" as any); + vi.mocked(uuidv4).mockReturnValue("new-session-id"); const newSession = startNewSession(); const currentSession = getCurrentSession(); @@ -401,4 +401,100 @@ describe("SessionManager", () => { expect(currentSession).not.toBe(originalSession); }); }); + + describe("session isolation", () => { + it("should not pollute new sessions with previous session history", () => { + // Simulate first CLI session + vi.mocked(uuidv4).mockReturnValue("session-1"); + const session1 = createSession(); + const history1: ChatHistoryItem[] = [ + { + message: { + role: "user", + content: "Tell me about dogs", + }, + contextItems: [], + }, + { + message: { + role: "assistant", + content: "Dogs are loyal companions...", + }, + contextItems: [], + }, + ]; + updateSessionHistory(history1); + + // Simulate starting a new CLI session (without --resume) + vi.mocked(uuidv4).mockReturnValue("session-2"); + const session2 = startNewSession([]); + + // New session should have clean state + expect(session2.sessionId).toBe("session-2"); + expect(session2.sessionId).not.toBe(session1.sessionId); + expect(session2.history).toEqual([]); + expect(session2.history.length).toBe(0); + }); + + it("should create independent sessions for concurrent operations", () => { + // Create first session with some data + vi.mocked(uuidv4).mockReturnValue("concurrent-1"); + const session1 = createSession(); + updateSessionTitle("Session 1"); + updateSessionHistory([ + { + message: { + role: "user", + content: "First session message", + }, + contextItems: [], + }, + ]); + + // Start a new session + vi.mocked(uuidv4).mockReturnValue("concurrent-2"); + const session2 = startNewSession([]); + + // Verify session2 is clean + expect(session2.title).toBe("Untitled Session"); + expect(session2.history).toEqual([]); + expect(session2.sessionId).not.toBe(session1.sessionId); + }); + + it("should properly clear session state when transitioning between sessions", () => { + // First session with complex history + vi.mocked(uuidv4).mockReturnValue("complex-session-1"); + const session1 = createSession(); + updateSessionTitle("Complex Session"); + const complexHistory: ChatHistoryItem[] = [ + { + message: { + role: "user", + content: "What were we discussing?", + }, + contextItems: [], + }, + { + message: { + role: "assistant", + content: "We were discussing dogs earlier.", + }, + contextItems: [], + }, + ]; + updateSessionHistory(complexHistory); + + // Verify first session has data + expect(getCurrentSession().history.length).toBe(2); + + // Start fresh session + vi.mocked(uuidv4).mockReturnValue("fresh-session-2"); + const session2 = startNewSession([]); + + // Verify clean state + expect(session2.history.length).toBe(0); + expect(session2.title).toBe("Untitled Session"); + expect(getCurrentSession().sessionId).toBe("fresh-session-2"); + }); + }); });