open-memex
Version:
Local-first memory layer and protocol for AI coding agents. Markdown source of truth, SQLite FTS5 index, zero cloud.
49 lines (48 loc) • 2 kB
JavaScript
import { z } from "zod";
import { PLUGIN_ID, bootstrapPlugin, captureFromText, captureHandoff, injectOnce, } from "./plugin-core.js";
import { makeTools } from "./tools/memory.js";
/** Register the five memory tools on a v2 host. */
async function registerTools(ctx, state) {
const tools = makeTools(() => state.scope, state.cfg);
await ctx.tool.transform((editor) => {
for (const [name, t] of Object.entries(tools)) {
editor.add({
name,
description: t.description,
input: z.toJSONSchema(z.object(t.args)),
options: { codemode: false },
execute: async (input) => {
const r = await t.execute(input, undefined);
const content = typeof r === "string" ? r : (r.output ?? JSON.stringify(r));
return { content };
},
});
}
});
}
export const v2Plugin = {
id: PLUGIN_ID,
async setup(ctx) {
const root = ctx.location?.directory ?? ctx.location?.project?.directory ?? process.cwd();
const state = bootstrapPlugin(root);
const registrations = [];
await registerTools(ctx, state);
registrations.push(await ctx.session.hook("prompt", (ev) => {
captureFromText(ev.prompt?.text ?? "", state, ev.sessionID ?? "");
}));
registrations.push(await ctx.session.hook("context", (ev) => {
const sessionID = ev.sessionID ?? "";
injectOnce(sessionID, state, (block) => {
ev.system.push({ type: "text", text: block });
});
// D73: tell the agent what the keyword hook already stored this turn.
const handoff = captureHandoff(sessionID, state);
if (handoff)
ev.system.push({ type: "text", text: handoff });
}));
return () => {
for (const r of registrations)
void r.dispose?.();
};
},
};