Forked from khtsly/persistent-memory
Project Files
src / projectMemory.ts
/**
* @file projectMemory.ts
* Shared helpers for project-scoped memory policy.
*/
import type { MemoryCategory, MemoryScope } from "./constants";
export interface ProjectMemoryConfig {
activeProject: string;
}
export interface ProjectMemoryTargetInput {
scope?: MemoryScope;
project?: string | null;
forceActiveProject?: boolean;
}
export interface ProjectMemoryTarget {
scope: MemoryScope;
project: string | null;
}
const PROJECT_MEMORY_CATEGORIES: MemoryCategory[] = [
"project",
"instruction",
"fact",
"note",
];
export function getDurableProjectCategories(): MemoryCategory[] {
return [...PROJECT_MEMORY_CATEGORIES];
}
export function isDurableProjectCategory(category: MemoryCategory): boolean {
return PROJECT_MEMORY_CATEGORIES.includes(category);
}
export function normalizeProjectSlug(project?: string | null): string | null {
const normalized = project?.trim();
return normalized ? normalized : null;
}
export function resolveProjectMemoryTarget(
cfg: ProjectMemoryConfig,
input: ProjectMemoryTargetInput,
): ProjectMemoryTarget {
const activeProject = normalizeProjectSlug(cfg.activeProject);
const requestedProject = normalizeProjectSlug(input.project);
if (input.scope === "session") {
return { scope: "session", project: null };
}
if (input.forceActiveProject && activeProject) {
return { scope: "project", project: activeProject };
}
if (input.scope === "project") {
return { scope: "project", project: requestedProject ?? activeProject };
}
if (requestedProject) {
return { scope: "project", project: requestedProject };
}
return {
scope: input.scope ?? "global",
project: null,
};
}
export function buildProjectMemoryTags(
tags: string[] | undefined,
project: string,
): string[] {
const normalized = new Set<string>();
for (const tag of tags ?? []) {
const clean = tag.trim().toLowerCase();
if (clean) normalized.add(clean);
}
normalized.add("project-memory");
normalized.add(project.trim().toLowerCase());
return [...normalized];
}