Initial scaffold: open-memory plugin for OpenCode

- Plugin entry point with hooks: experimental.session.compacting,
  experimental.chat.system.transform, event
- Context tracker: SSE-based token tracking per session with
  green/yellow/red/critical thresholds
- Tools: memory_context, memory_compact, memory_summary,
  memory_sessions, memory_messages, memory_search, memory_plans
- History module: sqlite3 queries + markdown rendering
- Compaction: improved prompt emphasizing self-continuity
- Research docs: ARCHITECTURE.md + opencode-memory reference
This commit is contained in:
2026-04-20 14:55:20 +00:00
commit 9a42dcfb94
16 changed files with 1296 additions and 0 deletions

57
src/index.ts Normal file
View File

@@ -0,0 +1,57 @@
import type { Plugin, PluginInput } from "@opencode-ai/plugin";
import { createTools } from "./tools.js";
import { startContextTracker } from "./context/tracker.js";
import { getCompactionPrompt } from "./compaction/prompt.js";
const OpenMemoryPlugin: Plugin = async (ctx) => {
const contextTracker = startContextTracker(ctx);
return {
tool: createTools(ctx, contextTracker),
"experimental.session.compacting": async (_input, output) => {
output.prompt = getCompactionPrompt();
},
"experimental.chat.system.transform": async (input, output) => {
if (!input.sessionID) return;
const info = contextTracker.getContextInfo(input.sessionID);
if (!info) return;
const statusEmoji =
info.status === "critical"
? "🔴"
: info.status === "red"
? "🟠"
: info.status === "yellow"
? "🟡"
: "🟢";
const advisory =
info.status === "critical"
? "Context is nearly full. Use memory_compact immediately if possible."
: info.status === "red"
? "Context is running low. Use memory_compact at your next natural break point."
: info.status === "yellow"
? "Context usage is getting high. Consider memory_compact when convenient."
: null;
const lines = [
`${statusEmoji} Context: ${info.percentage}% used (${info.usedTokens.toLocaleString()} / ${info.limitTokens.toLocaleString()} tokens, ${info.model})`,
];
if (advisory) {
lines.push(advisory);
}
output.system.push(lines.join("\n"));
},
event: async ({ event }) => {
contextTracker.handleEvent(event);
},
};
};
export default OpenMemoryPlugin;