diff --git a/package.json b/package.json index 25110cc..a52228f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opencode-supermemory", - "version": "2.1.0", + "version": "2.1.1", "description": "OpenCode plugin that gives coding agents persistent memory using Supermemory", "type": "module", "main": "dist/index.js", diff --git a/src/services/memory-tool.test.ts b/src/services/memory-tool.test.ts index 5b9224e..d1ac050 100644 --- a/src/services/memory-tool.test.ts +++ b/src/services/memory-tool.test.ts @@ -144,4 +144,28 @@ describe("shared supermemory tool", () => { expect(result.success).toBe(true); expect(containers).toEqual([tags.canonical, "legacy_user"]); }); + + test("list shows each document's content when v5 has no summary", async () => { + const result = JSON.parse( + await executeSupermemoryTool({ mode: "list" }, tags, { + configured: true, + memoryClient: client({ + listMemoriesScoped: async () => ({ + success: true, + memories: [ + { id: "doc_1", summary: null, content: "Use bun for builds", title: "Bun" }, + { id: "doc_2", summary: "Legacy summary", content: "raw" }, + { id: "doc_3", summary: null, title: "Still processing" }, + ], + pagination: { currentPage: 1, totalItems: 3, totalPages: 1 }, + }), + } as Partial), + }), + ); + expect(result.memories.map((memory: { content: string }) => memory.content)).toEqual([ + "Use bun for builds", + "Legacy summary", + "Still processing", + ]); + }); }); diff --git a/src/services/memory-tool.ts b/src/services/memory-tool.ts index 1a94c1d..17f3f39 100644 --- a/src/services/memory-tool.ts +++ b/src/services/memory-tool.ts @@ -279,7 +279,7 @@ export async function executeSupermemoryTool( count: memories.length, memories: memories.map((memory) => ({ id: memory.id, - content: memory.summary, + content: memory.summary || memory.content || memory.title || null, createdAt: memory.createdAt, metadata: memory.metadata, })), diff --git a/src/services/v5-client.test.ts b/src/services/v5-client.test.ts new file mode 100644 index 0000000..7cfc452 --- /dev/null +++ b/src/services/v5-client.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, test } from "bun:test"; + +import { V5Client } from "./v5-client.js"; + +function clientWithDocument(metadata: Record) { + const client = new V5Client("sm_test", "http://127.0.0.1:9", { + update: async () => ({}), + }, 5_000); + (client as unknown as { sdk: unknown }).sdk = { + list: async () => ({ + documents: [ + { id: "doc_1", title: "Bun", summary: null, system: { status: "done", createdAt: "2026-10-01T00:00:00Z" } }, + ], + pagination: { currentPage: 1, totalItems: 1, totalPages: 1 }, + }), + documents: { + get: async () => ({ id: "doc_1", content: "Use bun for builds", metadata }), + }, + }; + return client; +} + +const projectScope = { + containerTags: ["repo_test__0123456789abcdef"], + filters: { AND: [{ key: "sm_scope", value: "project", filterType: "metadata" as const }] }, + limit: 20, + order: "desc" as const, + sort: "createdAt" as const, + includeContent: true, +}; + +describe("V5Client document list", () => { + test("hydrates content when the read omits reserved sm_* keys", async () => { + const result = await clientWithDocument({ type: "preference" }).memories.list(projectScope); + expect(result.memories[0]).toMatchObject({ id: "doc_1", content: "Use bun for builds" }); + }); + + test("skips content when the document states another scope", async () => { + const result = await clientWithDocument({ sm_scope: "personal" }).memories.list(projectScope); + expect(result.memories[0]?.content).toBeUndefined(); + }); +}); diff --git a/src/services/v5-client.ts b/src/services/v5-client.ts index e7be229..dc562df 100644 --- a/src/services/v5-client.ts +++ b/src/services/v5-client.ts @@ -261,14 +261,17 @@ export class V5Client { }, remainingMs); }), ]); + // The list already filtered by scope and reads omit sm_* keys, so only a stated mismatch is wrong. + const scopeMatches = + request.filters?.AND.every(({ key, value }) => { + const actual = document.metadata?.[key]; + return actual === undefined || actual === value; + }) ?? true; if ( document.id === item.id && (typeof document.content === "string" || document.content === null) && - (request.filters?.AND.every( - ({ key, value }) => document.metadata?.[key] === value, - ) ?? - true) + scopeMatches ) { content = document.content; } else { diff --git a/src/version.ts b/src/version.ts index 435a1f1..3b850aa 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,3 +1,3 @@ // AUTO-GENERATED by scripts/sync-version.mjs — do not edit by hand. // Sourced from package.json "version" so the two cannot drift. -export const PLUGIN_VERSION = "2.1.0"; +export const PLUGIN_VERSION = "2.1.1";