Files
vercel__eve/apps/docs/scripts/validate-memory-registry.ts
2026-09-04 12:56:44 -04:00

105 lines
3.4 KiB
TypeScript

import { access, readFile } from "node:fs/promises";
import { join } from "node:path";
import { memoryEntries } from "@eve/catalog";
interface RegistryFile {
path: string;
target?: string;
}
interface RegistryItem {
name: string;
dependencies?: string[];
envVars?: Record<string, string>;
files?: RegistryFile[];
meta?: {
eve?: {
setup?: { package?: string; bin?: string; args?: string[] };
};
};
}
interface Registry {
items: RegistryItem[];
}
const docsRoot = join(import.meta.dirname, "..");
const registry = JSON.parse(await readFile(join(docsRoot, "registry.json"), "utf8")) as Registry;
const items = registry.items.filter((item) => item.name.startsWith("memory/"));
const expectedSlugs = memoryEntries()
.filter((entry) => entry.surfaces.registry)
.map((entry) => entry.slug);
const actualSlugs = items.map((item) => item.name.slice("memory/".length));
if (JSON.stringify(actualSlugs) !== JSON.stringify(expectedSlugs)) {
throw new Error(
`Memory registry entries do not match the catalog.\nExpected: ${expectedSlugs.join(", ")}\nActual: ${actualSlugs.join(", ")}`,
);
}
for (const item of items) {
const slug = item.name.slice("memory/".length);
const expectedPath = `registry/memory/${slug}.ts`;
const expectedTarget = `agent/memory/${slug}.ts`;
const file = item.files?.[0];
if (item.files?.length !== 1 || file?.path !== expectedPath || file.target !== expectedTarget) {
throw new Error(
`Registry item "${item.name}" must write ${expectedPath} to ${expectedTarget}.`,
);
}
await access(join(docsRoot, expectedPath));
if (slug === "file") {
const setup = item.meta?.eve?.setup;
if (
setup?.package !== "eve" ||
setup.bin !== "eve" ||
JSON.stringify(setup.args) !== JSON.stringify(["integration", "setup", "file-memory"])
) {
throw new Error(
'Registry item "memory/file" must declare the trusted file-memory setup flow.',
);
}
} else if (slug === "upstash-agentkit") {
if (
!item.dependencies?.includes("@upstash/agentkit-eve") ||
!item.dependencies.includes("@upstash/redis")
) {
throw new Error(
'Registry item "memory/upstash-agentkit" must depend on @upstash/agentkit-eve and @upstash/redis.',
);
}
if (
!("UPSTASH_REDIS_REST_URL" in (item.envVars ?? {})) ||
!("UPSTASH_REDIS_REST_TOKEN" in (item.envVars ?? {}))
) {
throw new Error(
'Registry item "memory/upstash-agentkit" must declare UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN as environment variables.',
);
}
} else if (slug === "arcana") {
if (!item.dependencies?.includes("@kybernesis/arcana")) {
throw new Error('Registry item "memory/arcana" must depend on @kybernesis/arcana.');
}
if (
!("ARCANA_API_KEY" in (item.envVars ?? {})) ||
!("ARCANA_WORKSPACE" in (item.envVars ?? {}))
) {
throw new Error(
'Registry item "memory/arcana" must declare ARCANA_API_KEY and ARCANA_WORKSPACE as environment variables.',
);
}
} else if (slug === "supermemory") {
if (!item.dependencies?.includes("@supermemory/eve")) {
throw new Error('Registry item "memory/supermemory" must depend on @supermemory/eve.');
}
if (!("SUPERMEMORY_API_KEY" in (item.envVars ?? {}))) {
throw new Error(
'Registry item "memory/supermemory" must declare SUPERMEMORY_API_KEY as an environment variable.',
);
}
}
}