import { describe, expect, it } from "vitest"; import { collectLocalProfileSignals, mergeUserMemorySections, persistUserProfileHarvest, } from "./user-profile-harvest"; describe("user-profile-harvest", () => { it("collects timezone and locale signals", () => { const signals = collectLocalProfileSignals({ name: "Ingo", email: "ingo@example.com", defaultProvider: "openrouter", defaultModel: "gpt-4", computerHost: "docker", }); expect(signals.timezone).toBeTruthy(); expect(signals.locale).toBeTruthy(); expect(signals.name).toBe("Ingo"); expect(signals.harvestedAt).toMatch(/^\d{4}-/); }); it("keeps existing notes and leaves profile data to the user profile", () => { const merged = mergeUserMemorySections("# Space memory\n\nExisting note.\n"); expect(merged).toContain("Existing note."); expect(merged).not.toContain("## User profile (auto-harvested)"); }); it("persists help vibe via memory.update on user scope without profile data", async () => { const updates: Array<{ documentId: string; content: string }> = []; const hints = await persistUserProfileHarvest( { memory: { list: async () => [{ id: "mem1", path: "MEMORY.md", content: "# Space memory\n" }], update: async (input) => { updates.push(input); }, }, }, collectLocalProfileSignals({ name: "Ingo", email: "ingo@example.com", defaultProvider: null, defaultModel: null, computerHost: "docker", }), ); expect(updates).toHaveLength(1); expect(updates[0]?.content).toContain("## Help & vibe (inferred)"); expect(updates[0]?.content).not.toContain("Ingo"); expect(updates[0]?.content).not.toContain("ingo@example.com"); expect(hints.suggestedLanes).toContain("builder"); }); });