From d65e1cb3514c0f3d5a2a6724cbf44865b7e3d6b1 Mon Sep 17 00:00:00 2001 From: jknapp Date: Sun, 17 May 2026 06:43:19 -0700 Subject: [PATCH] feat(memory): allow editing scope and project on memory.update Extends both the Web UI edit form and the memory.update MCP tool so existing memories can be reclassified between user-global and project-attached scopes without delete+rewrite. Schema refines enforce the user/project consistency invariants; audit log captures from/to scope and projectKey on transitions. --- apps/web/app/(authed)/memories/[id]/page.tsx | 45 ++++++++++- apps/web/lib/mcp/tools.ts | 80 ++++++++++++++++++-- apps/web/lib/memory-actions.ts | 69 +++++++++++++++-- packages/schemas/src/index.ts | 22 +++++- 4 files changed, 199 insertions(+), 17 deletions(-) diff --git a/apps/web/app/(authed)/memories/[id]/page.tsx b/apps/web/app/(authed)/memories/[id]/page.tsx index e3d0ac0..b4e1695 100644 --- a/apps/web/app/(authed)/memories/[id]/page.tsx +++ b/apps/web/app/(authed)/memories/[id]/page.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; import { notFound } from "next/navigation"; -import { and, eq, isNull } from "drizzle-orm"; +import { and, desc, eq, isNull } from "drizzle-orm"; import { auth } from "@/auth"; import { db } from "@/lib/db/client"; import { memories, projects } from "@/lib/db/schema"; @@ -48,6 +48,15 @@ export default async function MemoryDetailPage({ const isEditing = edit === "1"; + const projectList = isEditing + ? await db + .select({ key: projects.key, displayName: projects.displayName }) + .from(projects) + .where(eq(projects.userId, userId)) + .orderBy(desc(projects.updatedAt)) + .limit(50) + : []; + return (
+
+ + +
+
+ + + {projectList.length > 0 ? ( + + {projectList.map((p) => ( + + ))} + + ) : null} +