@super-pocock-ai/memory-core 2.0.20 → 2.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +27 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +26 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -50,12 +40,12 @@ var import_plugin = require("@opencode-ai/plugin");
|
|
|
50
40
|
var import_zod = require("zod");
|
|
51
41
|
|
|
52
42
|
// src/store.ts
|
|
53
|
-
var
|
|
43
|
+
var import_bun_sqlite = require("bun:sqlite");
|
|
54
44
|
var MemoryStore = class {
|
|
55
45
|
db;
|
|
56
46
|
constructor(dbPath) {
|
|
57
|
-
this.db = new
|
|
58
|
-
this.db.
|
|
47
|
+
this.db = new import_bun_sqlite.Database(dbPath);
|
|
48
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
59
49
|
this.init();
|
|
60
50
|
}
|
|
61
51
|
init() {
|
|
@@ -75,10 +65,25 @@ var MemoryStore = class {
|
|
|
75
65
|
USING fts5(path, body, tokenize='unicode61')
|
|
76
66
|
`);
|
|
77
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* 构建 FTS5 查询 - 使用 MiMo Code 的方式
|
|
70
|
+
* 避免 FTS5 特殊字符导致崩溃
|
|
71
|
+
*/
|
|
72
|
+
buildFtsQuery(raw) {
|
|
73
|
+
const tokens = raw.match(/[\p{L}\p{N}_]+/gu)?.map((t) => t.trim()).filter(Boolean) ?? [];
|
|
74
|
+
if (tokens.length === 0) return null;
|
|
75
|
+
const quoted = tokens.map((t) => `"${t.replaceAll('"', "")}"`);
|
|
76
|
+
return quoted.join(" OR ");
|
|
77
|
+
}
|
|
78
78
|
search(query, filters = {}) {
|
|
79
|
-
|
|
80
|
-
if (
|
|
81
|
-
|
|
79
|
+
let ftsQuery;
|
|
80
|
+
if (query === "*") {
|
|
81
|
+
ftsQuery = "*";
|
|
82
|
+
} else {
|
|
83
|
+
const built = this.buildFtsQuery(query);
|
|
84
|
+
if (!built) return [];
|
|
85
|
+
ftsQuery = built;
|
|
86
|
+
}
|
|
82
87
|
const limit = filters.limit ?? 10;
|
|
83
88
|
let sql = `
|
|
84
89
|
SELECT f.path, m.scope, m.scope_id, m.type,
|
|
@@ -103,21 +108,21 @@ var MemoryStore = class {
|
|
|
103
108
|
}
|
|
104
109
|
sql += ` ORDER BY score LIMIT ?`;
|
|
105
110
|
params.push(limit);
|
|
106
|
-
return this.db.
|
|
111
|
+
return this.db.query(sql).all(...params);
|
|
107
112
|
}
|
|
108
113
|
write(path, scope, scope_id, type, content) {
|
|
109
114
|
const fingerprint = `${content.length}-${Date.now()}`;
|
|
110
115
|
const now = Date.now();
|
|
111
|
-
this.db.
|
|
116
|
+
this.db.query(`
|
|
112
117
|
INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)
|
|
113
118
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
114
119
|
`).run(path, scope, scope_id, type, fingerprint, now);
|
|
115
|
-
this.db.
|
|
116
|
-
this.db.
|
|
120
|
+
this.db.query(`DELETE FROM memory_fts WHERE path = ?`).run(path);
|
|
121
|
+
this.db.query(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content);
|
|
117
122
|
}
|
|
118
123
|
forget(memoryId) {
|
|
119
|
-
this.db.
|
|
120
|
-
this.db.
|
|
124
|
+
this.db.query("DELETE FROM memory_files WHERE path = ?").run(memoryId);
|
|
125
|
+
this.db.query("DELETE FROM memory_fts WHERE path = ?").run(memoryId);
|
|
121
126
|
}
|
|
122
127
|
close() {
|
|
123
128
|
this.db.close();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/tool.ts","../src/store.ts","../src/reconcile.ts","../src/config.ts","../src/paths.ts","../src/checkpoint-plugin.ts","../src/injection-plugin.ts","../src/dream-plugin.ts"],"sourcesContent":["import type { Plugin } from \"@opencode-ai/plugin\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\nimport { createMemoryTool } from \"./tool\"\nimport { CheckpointPlugin } from \"./checkpoint-plugin\"\nimport { MemoryInjectionPlugin } from \"./injection-plugin\"\nimport { DreamPlugin } from \"./dream-plugin\"\nimport { getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir, getDbPath } from \"./paths\"\nimport { ensureConfig } from \"./config\"\n\nexport const MemoryCorePlugin: Plugin = async (ctx) => {\n // 确保配置文件存在\n ensureConfig(ctx.directory)\n\n const memoryRoot = getMemoryRoot(ctx.directory)\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir(ctx.directory)\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(projectDir, \"sessions\"), { recursive: true })\n mkdirSync(join(projectDir, \"tasks\"), { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(ctx.directory),\n })\n\n // 初始化子插件\n const checkpointPlugin = await CheckpointPlugin(ctx)\n const injectionPlugin = await MemoryInjectionPlugin(ctx)\n const dreamPlugin = await DreamPlugin(ctx)\n\n return {\n tool: {\n memory: memoryTool,\n },\n event: async (input) => {\n await checkpointPlugin.event?.(input)\n await injectionPlugin.event?.(input)\n await dreamPlugin.event?.(input)\n },\n \"experimental.chat.system.transform\": async (input, output) => {\n await injectionPlugin[\"experimental.chat.system.transform\"]?.(input, output)\n },\n \"experimental.session.compacting\": async (input, output) => {\n await checkpointPlugin[\"experimental.session.compacting\"]?.(input, output)\n await injectionPlugin[\"experimental.session.compacting\"]?.(input, output)\n },\n }\n}\n\nexport default MemoryCorePlugin\n\n// 导出子模块\nexport { MemoryStore } from \"./store\"\nexport { createMemoryTool } from \"./tool\"\nexport { resolveProjectId, getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir } from \"./paths\"\nexport { loadConfig, DEFAULT_CONFIG } from \"./config\"\nexport type { MemoryConfig } from \"./config\"\nexport type { SearchResult, SearchFilters } from \"./store\"\n","import { tool } from \"@opencode-ai/plugin\"\nimport { z } from \"zod\"\nimport { MemoryStore } from \"./store\"\nimport { reconcileMemoryDir } from \"./reconcile\"\nimport { mkdirSync } from \"fs\"\n\nexport function createMemoryTool(ctx: { memoryDir: string; dbPath: string }) {\n let store: MemoryStore | null = null\n\n function ensureStore() {\n if (!store) {\n mkdirSync(ctx.memoryDir, { recursive: true })\n store = new MemoryStore(ctx.dbPath)\n reconcileMemoryDir(store, ctx.memoryDir)\n }\n return store\n }\n\n return tool({\n description: \"Search or write to the persistent memory store. Search returns ranked results across memory files. Write saves content to a memory file.\",\n args: {\n operation: z.enum([\"search\", \"write\", \"list\", \"forget\"]),\n query: z.string().optional(),\n scope: z.string().optional(),\n scope_id: z.string().optional(),\n type: z.string().optional(),\n limit: z.number().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n memory_id: z.string().optional(),\n },\n execute(args: any) {\n const s = ensureStore()\n\n if (args.operation === \"search\") {\n if (!args.query) return \"query is required for search\"\n const results = s.search(args.query, {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit,\n })\n if (results.length === 0) return \"No results found\"\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"write\") {\n if (!args.path) return \"path is required for write\"\n if (!args.content) return \"content is required for write\"\n s.write(\n args.path,\n args.scope ?? \"unknown\",\n args.scope_id ?? \"\",\n args.type ?? \"snapshot\",\n args.content,\n )\n return `Wrote to ${args.path}`\n }\n\n if (args.operation === \"list\") {\n const results = s.search(\"*\", {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit ?? 50,\n })\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"forget\") {\n if (!args.memory_id) return \"memory_id is required for forget\"\n s.forget(args.memory_id)\n return `Forgot ${args.memory_id}`\n }\n\n return \"Invalid operation\"\n },\n })\n}\n","import Database from \"better-sqlite3\"\n\nexport interface SearchFilters {\n scope?: string\n scope_id?: string\n type?: string\n limit?: number\n}\n\nexport interface SearchResult {\n path: string\n scope: string\n scope_id: string\n type: string\n snippet: string\n score: number\n}\n\nexport class MemoryStore {\n public db: Database.Database\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath)\n this.db.pragma(\"journal_mode = WAL\")\n this.init()\n }\n\n private init() {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS memory_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL UNIQUE,\n scope TEXT NOT NULL,\n scope_id TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL,\n fingerprint TEXT NOT NULL,\n last_indexed_at INTEGER NOT NULL\n )\n `)\n this.db.exec(`\n CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts\n USING fts5(path, body, tokenize='unicode61')\n `)\n }\n\n search(query: string, filters: SearchFilters = {}): SearchResult[] {\n const tokens = query.split(/\\s+/).filter(Boolean).map(t => `\"${t}\"`)\n if (tokens.length === 0) return []\n const ftsQuery = tokens.join(\" OR \")\n const limit = filters.limit ?? 10\n\n let sql = `\n SELECT f.path, m.scope, m.scope_id, m.type,\n snippet(memory_fts, 1, '<<', '>>', '...', 32) AS snippet,\n bm25(memory_fts) AS score\n FROM memory_fts f\n JOIN memory_files m ON m.path = f.path\n WHERE memory_fts MATCH ?\n `\n const params: any[] = [ftsQuery]\n if (filters.scope) { sql += ` AND m.scope = ?`; params.push(filters.scope) }\n if (filters.scope_id) { sql += ` AND m.scope_id = ?`; params.push(filters.scope_id) }\n if (filters.type) { sql += ` AND m.type = ?`; params.push(filters.type) }\n sql += ` ORDER BY score LIMIT ?`\n params.push(limit)\n return this.db.prepare(sql).all(...params) as SearchResult[]\n }\n\n write(path: string, scope: string, scope_id: string, type: string, content: string) {\n const fingerprint = `${content.length}-${Date.now()}`\n const now = Date.now()\n\n this.db.prepare(`\n INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(path, scope, scope_id, type, fingerprint, now)\n\n this.db.prepare(`DELETE FROM memory_fts WHERE path = ?`).run(path)\n this.db.prepare(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content)\n }\n\n forget(memoryId: string) {\n this.db.prepare(\"DELETE FROM memory_files WHERE path = ?\").run(memoryId)\n this.db.prepare(\"DELETE FROM memory_fts WHERE path = ?\").run(memoryId)\n }\n\n close() {\n this.db.close()\n }\n}\n","import { readdirSync, readFileSync } from \"fs\"\nimport { join, relative, sep } from \"path\"\nimport type { MemoryStore } from \"./store\"\n\nfunction parseScopeAndId(memoryRoot: string, filePath: string): { scope: string; scope_id: string } {\n const rel = relative(memoryRoot, filePath).split(sep)\n if (rel[0] === \"global\") return { scope: \"global\", scope_id: \"\" }\n if (rel[0] === \"projects\" && rel.length >= 3) return { scope: \"projects\", scope_id: rel[1] }\n if (rel[0] === \"sessions\" && rel.length >= 3) return { scope: \"sessions\", scope_id: rel[1] }\n return { scope: \"unknown\", scope_id: \"\" }\n}\n\nfunction walkMdFiles(dir: string): string[] {\n const results: string[] = []\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...walkMdFiles(full))\n } else if (entry.name.endsWith(\".md\")) {\n results.push(full)\n }\n }\n return results\n}\n\nexport function reconcileMemoryDir(store: MemoryStore, memoryRoot: string) {\n const filesOnDisk = walkMdFiles(memoryRoot)\n const diskPaths = new Set<string>()\n\n for (const file of filesOnDisk) {\n diskPaths.add(file)\n const content = readFileSync(file, \"utf-8\")\n const { scope, scope_id } = parseScopeAndId(memoryRoot, file)\n store.write(file, scope, scope_id, \"snapshot\", content)\n }\n\n const indexed = store.db.prepare(\"SELECT path FROM memory_files\").all() as { path: string }[]\n for (const row of indexed) {\n if (!diskPaths.has(row.path)) {\n store.forget(row.path)\n }\n }\n}\n","import { readFileSync, existsSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join, dirname } from \"path\"\n\nexport interface MemoryConfig {\n memory: {\n injection: {\n total_budget: number\n allocation: {\n checkpoint: number\n memory: number\n notes: number\n progress: number\n buffer: number\n }\n }\n checkpoint: {\n thresholds: string[]\n drain_timeout_ms: number\n idle_timeout_ms: number\n }\n dream: {\n auto: boolean\n interval_days: number\n }\n distill: {\n auto: boolean\n interval_days: number\n }\n }\n}\n\nexport const DEFAULT_CONFIG: MemoryConfig = {\n memory: {\n injection: {\n total_budget: 2000,\n allocation: {\n checkpoint: 0.30,\n memory: 0.25,\n notes: 0.20,\n progress: 0.15,\n buffer: 0.10\n }\n },\n checkpoint: {\n thresholds: [\"20%\", \"40%\", \"60%\", \"80%\"],\n drain_timeout_ms: 120000,\n idle_timeout_ms: 300000\n },\n dream: {\n auto: true,\n interval_days: 7\n },\n distill: {\n auto: true,\n interval_days: 30\n }\n }\n}\n\nexport function getConfigPath(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"config.json\")\n}\n\nexport function loadConfig(projectRoot: string): MemoryConfig {\n const configPath = getConfigPath(projectRoot)\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, \"utf-8\")\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) }\n }\n return DEFAULT_CONFIG\n}\n\nexport function ensureConfig(projectRoot: string): void {\n const configPath = getConfigPath(projectRoot)\n if (!existsSync(configPath)) {\n mkdirSync(dirname(configPath), { recursive: true })\n writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2))\n }\n}\n","import { createHash } from \"crypto\"\nimport { join } from \"path\"\n\nexport type Scope = \"global\" | \"projects\" | \"sessions\"\n\nexport function resolveProjectId(absRepoPath: string): string {\n return createHash(\"sha256\").update(absRepoPath).digest(\"hex\").slice(0, 12)\n}\n\nexport function getMemoryRoot(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(projectRoot), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(projectRoot), \"sessions\", sessionId)\n}\n\nexport function getDbPath(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"memory.db\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const CheckpointPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryRoot = getMemoryRoot(directory)\n const projectDir = getProjectMemoryDir(directory)\n \n // 创建必要的目录\n mkdirSync(memoryRoot, { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n let lastCheckpointRatio = 0\n const THRESHOLDS = config.memory.checkpoint.thresholds.map(t => parseFloat(t) / 100)\n let currentSessionID: string | null = null\n\n return {\n event: async ({ event }) => {\n // 记录当前会话 ID\n if (event.type === \"session.created\") {\n const newSessionID = event.properties?.info?.id\n \n // 触发 1: 新建会话时,保存上一个会话的 checkpoint\n if (currentSessionID && currentSessionID !== newSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"new session created\")\n }\n \n currentSessionID = newSessionID || null\n }\n\n // 触发 2: Token 比例阈值\n if (event.type === \"session.next.step.ended\") {\n const ratio = event.properties.tokens / event.properties.contextLimit\n const nextThreshold = THRESHOLDS.find(t => t > lastCheckpointRatio)\n if (nextThreshold && ratio >= nextThreshold) {\n lastCheckpointRatio = ratio\n await triggerCheckpoint(client, event.properties.sessionID, directory, `token ratio ${Math.round(ratio * 100)}%`)\n }\n }\n\n // 触发 3: 会话结束(idle 超时)\n if (event.type === \"session.status\" && event.properties?.status?.type === \"idle\") {\n setTimeout(async () => {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"idle timeout\")\n }, config.memory.checkpoint.idle_timeout_ms)\n }\n\n // 触发 4: 会话空闲\n if (event.type === \"session.idle\") {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"session idle\")\n }\n\n // 触发 5: 会话删除时保存 checkpoint\n if (event.type === \"session.deleted\") {\n await triggerCheckpoint(client, event.properties.info.id, directory, \"session deleted\")\n }\n\n // 触发 6: 退出程序时保存当前会话 checkpoint\n if (event.type === \"server.instance.disposed\") {\n if (currentSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"app exit\")\n }\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n output.context.push(`\n## Checkpoint Instructions\nExtract and preserve these 11 fields:\n1. Intent (用户的核心目标)\n2. Actions (已执行的操作)\n3. Task Tree (子任务层级)\n4. Errors & Workarounds (遇到的问题及解决)\n5. Design Decisions (关键技术选择)\n6. Constraints (限制条件)\n7. Current State (任务进度)\n8. TODOs (剩余工作)\n9. Code Changes Summary (Git diff 概要)\n10. Key File Paths (涉及的核心文件)\n11. Timestamp (检查点创建时间)\n `)\n },\n }\n}\n\nasync function triggerCheckpoint(client: any, sessionID: string, directory: string, reason?: string) {\n const messages = await client.session.messages({ path: { id: sessionID } })\n const context = constructCheckpointContext(messages)\n\n // 创建会话目录\n const sessionDir = getSessionMemoryDir(directory, sessionID)\n mkdirSync(sessionDir, { recursive: true })\n\n // 记录日志\n await client.app.log({\n body: {\n service: 'memory-core',\n level: 'info',\n message: `Checkpoint triggered: ${reason || 'unknown'} (session: ${sessionID})`\n }\n })\n\n // 非阻塞调用,不等待完成\n client.session.prompt({\n path: { id: sessionID },\n body: {\n agent: \"checkpoint-writer\",\n parts: [{\n type: \"text\",\n text: `Extract checkpoint from this context:\\n${context}\\n\\nWrite checkpoint to:\\n- Session: .super-pocock/memory/sessions/${sessionID}/checkpoint.md\\n- Project: .super-pocock/memory/projects/<pid>/checkpoint.md`\n }],\n },\n }).catch((err: any) => {\n // 静默处理错误,不影响主 agent\n console.error('Checkpoint failed:', err)\n })\n}\n\nfunction constructCheckpointContext(messages: any[]): string {\n return messages.map(m => `[${m.role}]: ${m.content}`).join(\"\\n\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getGlobalMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { existsSync, readFileSync, readdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const MemoryInjectionPlugin: Plugin = async ({ directory }) => {\n const config = loadConfig(directory)\n const memoryCache = new Map<string, Record<string, string>>()\n\n function getLatestSessionId(): string | null {\n const sessionsDir = join(getMemoryRoot(directory), \"sessions\")\n if (!existsSync(sessionsDir)) return null\n \n const sessions = readdirSync(sessionsDir, { withFileTypes: true })\n .filter(d => d.isDirectory())\n .map(d => d.name)\n \n if (sessions.length === 0) return null\n \n // 返回最新的会话(按目录修改时间)\n let latestSession = sessions[0]\n let latestTime = 0\n \n for (const session of sessions) {\n const sessionPath = join(sessionsDir, session)\n const stat = require(\"fs\").statSync(sessionPath)\n if (stat.mtimeMs > latestTime) {\n latestTime = stat.mtimeMs\n latestSession = session\n }\n }\n \n return latestSession\n }\n\n function loadMemoryFiles(sessionId?: string) {\n const projectDir = getProjectMemoryDir(directory)\n const globalDir = getGlobalMemoryDir(directory)\n const memoryRoot = getMemoryRoot(directory)\n\n const memories: Record<string, string> = {}\n\n // 项目级记忆\n const files = [\n { key: \"memory\", path: join(projectDir, \"MEMORY.md\") },\n { key: \"notes\", path: join(projectDir, \"notes.md\") },\n { key: \"progress\", path: join(projectDir, \"tasks\", \"progress.md\") },\n { key: \"global_memory\", path: join(globalDir, \"MEMORY.md\") },\n ]\n\n for (const file of files) {\n if (existsSync(file.path)) {\n memories[file.key] = readFileSync(file.path, \"utf-8\")\n }\n }\n\n // 会话级 checkpoint(优先)\n if (sessionId) {\n const sessionCheckpoint = join(memoryRoot, \"sessions\", sessionId, \"checkpoint.md\")\n if (existsSync(sessionCheckpoint)) {\n memories.checkpoint = readFileSync(sessionCheckpoint, \"utf-8\")\n }\n }\n\n // 项目级 checkpoint(备选)\n if (!memories.checkpoint) {\n const projectCheckpoint = join(projectDir, \"checkpoint.md\")\n if (existsSync(projectCheckpoint)) {\n memories.checkpoint = readFileSync(projectCheckpoint, \"utf-8\")\n }\n }\n\n return memories\n }\n\n function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n }\n\n function smartTruncate(text: string, maxTokens: number): string {\n const estimatedTokens = estimateTokens(text)\n if (estimatedTokens <= maxTokens) return text\n\n const keepChars = maxTokens * 4 * 0.3\n const start = text.substring(0, keepChars)\n const end = text.substring(text.length - keepChars)\n\n return `${start}\\n\\n... [记忆已压缩,原 ${estimatedTokens} tokens] ...\\n\\n${end}`\n }\n\n function formatMemory(memories: Record<string, string>, budget: Record<string, number>): string {\n const sections = []\n\n if (memories.checkpoint && budget.checkpoint > 0) {\n sections.push(`## 检查点状态\\n${smartTruncate(memories.checkpoint, budget.checkpoint)}`)\n }\n if (memories.memory && budget.memory > 0) {\n sections.push(`## 项目记忆\\n${smartTruncate(memories.memory, budget.memory)}`)\n }\n if (memories.global_memory && budget.memory > 0) {\n sections.push(`## 全局记忆\\n${smartTruncate(memories.global_memory, budget.memory * 0.5)}`)\n }\n if (memories.notes && budget.notes > 0) {\n sections.push(`## 当前笔记\\n${smartTruncate(memories.notes, budget.notes)}`)\n }\n if (memories.progress && budget.progress > 0) {\n sections.push(`## 任务进度\\n${smartTruncate(memories.progress, budget.progress)}`)\n }\n\n return sections.join(\"\\n\\n\")\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 获取最新的会话 ID\n const latestSessionId = getLatestSessionId()\n const memories = loadMemoryFiles(latestSessionId)\n memoryCache.set(event.properties.sessionID, memories)\n \n // 记录注入状态\n const memoryKeys = Object.keys(memories)\n const totalTokens = Object.values(memories).reduce((sum, content) => sum + estimateTokens(content), 0)\n console.log(`[memory-core] Loaded ${memoryKeys.length} memory files (${totalTokens} tokens) for session ${event.properties.sessionID}`)\n }\n },\n\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) {\n console.log(`[memory-core] No memories found for session ${input.sessionID}`)\n return\n }\n\n const totalBudget = config.memory.injection.total_budget\n const allocation = config.memory.injection.allocation\n\n const budget = {\n checkpoint: Math.floor(totalBudget * allocation.checkpoint),\n memory: Math.floor(totalBudget * allocation.memory),\n notes: Math.floor(totalBudget * allocation.notes),\n progress: Math.floor(totalBudget * allocation.progress),\n }\n\n const memoryContext = formatMemory(memories, budget)\n\n if (memoryContext) {\n const injectedTokens = estimateTokens(memoryContext)\n console.log(`[memory-core] Injecting ${injectedTokens} tokens (budget: ${totalBudget}) into system prompt`)\n output.system.push(`\\n\\n# Injected Memory Context\\n${memoryContext}`)\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\n\n const criticalMemory = []\n if (memories.checkpoint) {\n criticalMemory.push(`当前检查点: ${memories.checkpoint.substring(0, 500)}`)\n }\n if (memories.progress) {\n criticalMemory.push(`任务进度摘要: ${memories.progress.substring(0, 300)}`)\n }\n\n output.context.push(`## 保留的关键记忆\\n${criticalMemory.join(\"\\n\\n\")}`)\n },\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir } from \"./paths\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const DreamPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryDir = getProjectMemoryDir(directory)\n mkdirSync(memoryDir, { recursive: true })\n\n function getLastTimestamp(metaFile: string): number {\n const metaPath = join(memoryDir, metaFile)\n if (existsSync(metaPath)) {\n const meta = JSON.parse(readFileSync(metaPath, \"utf-8\"))\n return meta.timestamp ?? 0\n }\n return 0\n }\n\n function setLastTimestamp(metaFile: string) {\n const metaPath = join(memoryDir, metaFile)\n writeFileSync(metaPath, JSON.stringify({ timestamp: Date.now() }))\n }\n\n function shouldAutoRun(metaFile: string, intervalDays: number): boolean {\n const lastRun = getLastTimestamp(metaFile)\n const intervalMs = intervalDays * 24 * 60 * 60 * 1000\n return Date.now() - lastRun > intervalMs\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 自动触发 dream\n if (config.memory.dream.auto && shouldAutoRun(\".dream-meta.json\", config.memory.dream.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"dream\",\n parts: [{\n type: \"text\",\n text: \"Run automatic dream memory consolidation pass.\"\n }],\n },\n })\n setLastTimestamp(\".dream-meta.json\")\n }\n\n // 自动触发 distill\n if (config.memory.distill.auto && shouldAutoRun(\".distill-meta.json\", config.memory.distill.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"distill\",\n parts: [{\n type: \"text\",\n text: \"Run automatic distill pass.\"\n }],\n },\n })\n setLastTimestamp(\".distill-meta.json\")\n }\n }\n },\n }\n}\n"],"mappings":"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","names":["import_fs","import_path","Database","import_fs","import_fs","import_path","import_path","import_fs","import_path","import_fs","import_path","import_fs","import_path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tool.ts","../src/store.ts","../src/reconcile.ts","../src/config.ts","../src/paths.ts","../src/checkpoint-plugin.ts","../src/injection-plugin.ts","../src/dream-plugin.ts"],"sourcesContent":["import type { Plugin } from \"@opencode-ai/plugin\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\nimport { createMemoryTool } from \"./tool\"\nimport { CheckpointPlugin } from \"./checkpoint-plugin\"\nimport { MemoryInjectionPlugin } from \"./injection-plugin\"\nimport { DreamPlugin } from \"./dream-plugin\"\nimport { getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir, getDbPath } from \"./paths\"\nimport { ensureConfig } from \"./config\"\n\nexport const MemoryCorePlugin: Plugin = async (ctx) => {\n // 确保配置文件存在\n ensureConfig(ctx.directory)\n\n const memoryRoot = getMemoryRoot(ctx.directory)\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir(ctx.directory)\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(projectDir, \"sessions\"), { recursive: true })\n mkdirSync(join(projectDir, \"tasks\"), { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(ctx.directory),\n })\n\n // 初始化子插件\n const checkpointPlugin = await CheckpointPlugin(ctx)\n const injectionPlugin = await MemoryInjectionPlugin(ctx)\n const dreamPlugin = await DreamPlugin(ctx)\n\n return {\n tool: {\n memory: memoryTool,\n },\n event: async (input) => {\n await checkpointPlugin.event?.(input)\n await injectionPlugin.event?.(input)\n await dreamPlugin.event?.(input)\n },\n \"experimental.chat.system.transform\": async (input, output) => {\n await injectionPlugin[\"experimental.chat.system.transform\"]?.(input, output)\n },\n \"experimental.session.compacting\": async (input, output) => {\n await checkpointPlugin[\"experimental.session.compacting\"]?.(input, output)\n await injectionPlugin[\"experimental.session.compacting\"]?.(input, output)\n },\n }\n}\n\nexport default MemoryCorePlugin\n\n// 导出子模块\nexport { MemoryStore } from \"./store\"\nexport { createMemoryTool } from \"./tool\"\nexport { resolveProjectId, getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir } from \"./paths\"\nexport { loadConfig, DEFAULT_CONFIG } from \"./config\"\nexport type { MemoryConfig } from \"./config\"\nexport type { SearchResult, SearchFilters } from \"./store\"\n","import { tool } from \"@opencode-ai/plugin\"\nimport { z } from \"zod\"\nimport { MemoryStore } from \"./store\"\nimport { reconcileMemoryDir } from \"./reconcile\"\nimport { mkdirSync } from \"fs\"\n\nexport function createMemoryTool(ctx: { memoryDir: string; dbPath: string }) {\n let store: MemoryStore | null = null\n\n function ensureStore() {\n if (!store) {\n mkdirSync(ctx.memoryDir, { recursive: true })\n store = new MemoryStore(ctx.dbPath)\n reconcileMemoryDir(store, ctx.memoryDir)\n }\n return store\n }\n\n return tool({\n description: \"Search or write to the persistent memory store. Search returns ranked results across memory files. Write saves content to a memory file.\",\n args: {\n operation: z.enum([\"search\", \"write\", \"list\", \"forget\"]),\n query: z.string().optional(),\n scope: z.string().optional(),\n scope_id: z.string().optional(),\n type: z.string().optional(),\n limit: z.number().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n memory_id: z.string().optional(),\n },\n execute(args: any) {\n const s = ensureStore()\n\n if (args.operation === \"search\") {\n if (!args.query) return \"query is required for search\"\n const results = s.search(args.query, {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit,\n })\n if (results.length === 0) return \"No results found\"\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"write\") {\n if (!args.path) return \"path is required for write\"\n if (!args.content) return \"content is required for write\"\n s.write(\n args.path,\n args.scope ?? \"unknown\",\n args.scope_id ?? \"\",\n args.type ?? \"snapshot\",\n args.content,\n )\n return `Wrote to ${args.path}`\n }\n\n if (args.operation === \"list\") {\n const results = s.search(\"*\", {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit ?? 50,\n })\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"forget\") {\n if (!args.memory_id) return \"memory_id is required for forget\"\n s.forget(args.memory_id)\n return `Forgot ${args.memory_id}`\n }\n\n return \"Invalid operation\"\n },\n })\n}\n","import { Database } from \"bun:sqlite\"\n\nexport interface SearchFilters {\n scope?: string\n scope_id?: string\n type?: string\n limit?: number\n}\n\nexport interface SearchResult {\n path: string\n scope: string\n scope_id: string\n type: string\n snippet: string\n score: number\n}\n\nexport class MemoryStore {\n public db: Database\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath)\n this.db.exec(\"PRAGMA journal_mode = WAL\")\n this.init()\n }\n\n private init() {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS memory_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL UNIQUE,\n scope TEXT NOT NULL,\n scope_id TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL,\n fingerprint TEXT NOT NULL,\n last_indexed_at INTEGER NOT NULL\n )\n `)\n this.db.exec(`\n CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts\n USING fts5(path, body, tokenize='unicode61')\n `)\n }\n\n /**\n * 构建 FTS5 查询 - 使用 MiMo Code 的方式\n * 避免 FTS5 特殊字符导致崩溃\n */\n private buildFtsQuery(raw: string): string | null {\n const tokens =\n raw\n .match(/[\\p{L}\\p{N}_]+/gu)\n ?.map((t) => t.trim())\n .filter(Boolean) ?? []\n if (tokens.length === 0) return null\n const quoted = tokens.map((t) => `\"${t.replaceAll('\"', \"\")}\"`)\n return quoted.join(\" OR \")\n }\n\n search(query: string, filters: SearchFilters = {}): SearchResult[] {\n // 处理通配符查询\n let ftsQuery: string\n if (query === \"*\") {\n ftsQuery = \"*\"\n } else {\n const built = this.buildFtsQuery(query)\n if (!built) return []\n ftsQuery = built\n }\n\n const limit = filters.limit ?? 10\n\n let sql = `\n SELECT f.path, m.scope, m.scope_id, m.type,\n snippet(memory_fts, 1, '<<', '>>', '...', 32) AS snippet,\n bm25(memory_fts) AS score\n FROM memory_fts f\n JOIN memory_files m ON m.path = f.path\n WHERE memory_fts MATCH ?\n `\n const params: unknown[] = [ftsQuery]\n if (filters.scope) { sql += ` AND m.scope = ?`; params.push(filters.scope) }\n if (filters.scope_id) { sql += ` AND m.scope_id = ?`; params.push(filters.scope_id) }\n if (filters.type) { sql += ` AND m.type = ?`; params.push(filters.type) }\n sql += ` ORDER BY score LIMIT ?`\n params.push(limit)\n return this.db.query(sql).all(...params) as SearchResult[]\n }\n\n write(path: string, scope: string, scope_id: string, type: string, content: string) {\n const fingerprint = `${content.length}-${Date.now()}`\n const now = Date.now()\n\n this.db.query(`\n INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(path, scope, scope_id, type, fingerprint, now)\n\n this.db.query(`DELETE FROM memory_fts WHERE path = ?`).run(path)\n this.db.query(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content)\n }\n\n forget(memoryId: string) {\n this.db.query(\"DELETE FROM memory_files WHERE path = ?\").run(memoryId)\n this.db.query(\"DELETE FROM memory_fts WHERE path = ?\").run(memoryId)\n }\n\n close() {\n this.db.close()\n }\n}\n","import { readdirSync, readFileSync } from \"fs\"\nimport { join, relative, sep } from \"path\"\nimport type { MemoryStore } from \"./store\"\n\nfunction parseScopeAndId(memoryRoot: string, filePath: string): { scope: string; scope_id: string } {\n const rel = relative(memoryRoot, filePath).split(sep)\n if (rel[0] === \"global\") return { scope: \"global\", scope_id: \"\" }\n if (rel[0] === \"projects\" && rel.length >= 3) return { scope: \"projects\", scope_id: rel[1] }\n if (rel[0] === \"sessions\" && rel.length >= 3) return { scope: \"sessions\", scope_id: rel[1] }\n return { scope: \"unknown\", scope_id: \"\" }\n}\n\nfunction walkMdFiles(dir: string): string[] {\n const results: string[] = []\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...walkMdFiles(full))\n } else if (entry.name.endsWith(\".md\")) {\n results.push(full)\n }\n }\n return results\n}\n\nexport function reconcileMemoryDir(store: MemoryStore, memoryRoot: string) {\n const filesOnDisk = walkMdFiles(memoryRoot)\n const diskPaths = new Set<string>()\n\n for (const file of filesOnDisk) {\n diskPaths.add(file)\n const content = readFileSync(file, \"utf-8\")\n const { scope, scope_id } = parseScopeAndId(memoryRoot, file)\n store.write(file, scope, scope_id, \"snapshot\", content)\n }\n\n const indexed = store.db.prepare(\"SELECT path FROM memory_files\").all() as { path: string }[]\n for (const row of indexed) {\n if (!diskPaths.has(row.path)) {\n store.forget(row.path)\n }\n }\n}\n","import { readFileSync, existsSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join, dirname } from \"path\"\n\nexport interface MemoryConfig {\n memory: {\n injection: {\n total_budget: number\n allocation: {\n checkpoint: number\n memory: number\n notes: number\n progress: number\n buffer: number\n }\n }\n checkpoint: {\n thresholds: string[]\n drain_timeout_ms: number\n idle_timeout_ms: number\n }\n dream: {\n auto: boolean\n interval_days: number\n }\n distill: {\n auto: boolean\n interval_days: number\n }\n }\n}\n\nexport const DEFAULT_CONFIG: MemoryConfig = {\n memory: {\n injection: {\n total_budget: 2000,\n allocation: {\n checkpoint: 0.30,\n memory: 0.25,\n notes: 0.20,\n progress: 0.15,\n buffer: 0.10\n }\n },\n checkpoint: {\n thresholds: [\"20%\", \"40%\", \"60%\", \"80%\"],\n drain_timeout_ms: 120000,\n idle_timeout_ms: 300000\n },\n dream: {\n auto: true,\n interval_days: 7\n },\n distill: {\n auto: true,\n interval_days: 30\n }\n }\n}\n\nexport function getConfigPath(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"config.json\")\n}\n\nexport function loadConfig(projectRoot: string): MemoryConfig {\n const configPath = getConfigPath(projectRoot)\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, \"utf-8\")\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) }\n }\n return DEFAULT_CONFIG\n}\n\nexport function ensureConfig(projectRoot: string): void {\n const configPath = getConfigPath(projectRoot)\n if (!existsSync(configPath)) {\n mkdirSync(dirname(configPath), { recursive: true })\n writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2))\n }\n}\n","import { createHash } from \"crypto\"\nimport { join } from \"path\"\n\nexport type Scope = \"global\" | \"projects\" | \"sessions\"\n\nexport function resolveProjectId(absRepoPath: string): string {\n return createHash(\"sha256\").update(absRepoPath).digest(\"hex\").slice(0, 12)\n}\n\nexport function getMemoryRoot(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(projectRoot), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(projectRoot), \"sessions\", sessionId)\n}\n\nexport function getDbPath(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"memory.db\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const CheckpointPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryRoot = getMemoryRoot(directory)\n const projectDir = getProjectMemoryDir(directory)\n \n // 创建必要的目录\n mkdirSync(memoryRoot, { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n let lastCheckpointRatio = 0\n const THRESHOLDS = config.memory.checkpoint.thresholds.map(t => parseFloat(t) / 100)\n let currentSessionID: string | null = null\n\n return {\n event: async ({ event }) => {\n // 记录当前会话 ID\n if (event.type === \"session.created\") {\n const newSessionID = event.properties?.info?.id\n \n // 触发 1: 新建会话时,保存上一个会话的 checkpoint\n if (currentSessionID && currentSessionID !== newSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"new session created\")\n }\n \n currentSessionID = newSessionID || null\n }\n\n // 触发 2: Token 比例阈值\n if (event.type === \"session.next.step.ended\") {\n const ratio = event.properties.tokens / event.properties.contextLimit\n const nextThreshold = THRESHOLDS.find(t => t > lastCheckpointRatio)\n if (nextThreshold && ratio >= nextThreshold) {\n lastCheckpointRatio = ratio\n await triggerCheckpoint(client, event.properties.sessionID, directory, `token ratio ${Math.round(ratio * 100)}%`)\n }\n }\n\n // 触发 3: 会话结束(idle 超时)\n if (event.type === \"session.status\" && event.properties?.status?.type === \"idle\") {\n setTimeout(async () => {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"idle timeout\")\n }, config.memory.checkpoint.idle_timeout_ms)\n }\n\n // 触发 4: 会话空闲\n if (event.type === \"session.idle\") {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"session idle\")\n }\n\n // 触发 5: 会话删除时保存 checkpoint\n if (event.type === \"session.deleted\") {\n await triggerCheckpoint(client, event.properties.info.id, directory, \"session deleted\")\n }\n\n // 触发 6: 退出程序时保存当前会话 checkpoint\n if (event.type === \"server.instance.disposed\") {\n if (currentSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"app exit\")\n }\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n output.context.push(`\n## Checkpoint Instructions\nExtract and preserve these 11 fields:\n1. Intent (用户的核心目标)\n2. Actions (已执行的操作)\n3. Task Tree (子任务层级)\n4. Errors & Workarounds (遇到的问题及解决)\n5. Design Decisions (关键技术选择)\n6. Constraints (限制条件)\n7. Current State (任务进度)\n8. TODOs (剩余工作)\n9. Code Changes Summary (Git diff 概要)\n10. Key File Paths (涉及的核心文件)\n11. Timestamp (检查点创建时间)\n `)\n },\n }\n}\n\nasync function triggerCheckpoint(client: any, sessionID: string, directory: string, reason?: string) {\n const messages = await client.session.messages({ path: { id: sessionID } })\n const context = constructCheckpointContext(messages)\n\n // 创建会话目录\n const sessionDir = getSessionMemoryDir(directory, sessionID)\n mkdirSync(sessionDir, { recursive: true })\n\n // 记录日志\n await client.app.log({\n body: {\n service: 'memory-core',\n level: 'info',\n message: `Checkpoint triggered: ${reason || 'unknown'} (session: ${sessionID})`\n }\n })\n\n // 非阻塞调用,不等待完成\n client.session.prompt({\n path: { id: sessionID },\n body: {\n agent: \"checkpoint-writer\",\n parts: [{\n type: \"text\",\n text: `Extract checkpoint from this context:\\n${context}\\n\\nWrite checkpoint to:\\n- Session: .super-pocock/memory/sessions/${sessionID}/checkpoint.md\\n- Project: .super-pocock/memory/projects/<pid>/checkpoint.md`\n }],\n },\n }).catch((err: any) => {\n // 静默处理错误,不影响主 agent\n console.error('Checkpoint failed:', err)\n })\n}\n\nfunction constructCheckpointContext(messages: any[]): string {\n return messages.map(m => `[${m.role}]: ${m.content}`).join(\"\\n\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getGlobalMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { existsSync, readFileSync, readdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const MemoryInjectionPlugin: Plugin = async ({ directory }) => {\n const config = loadConfig(directory)\n const memoryCache = new Map<string, Record<string, string>>()\n\n function getLatestSessionId(): string | null {\n const sessionsDir = join(getMemoryRoot(directory), \"sessions\")\n if (!existsSync(sessionsDir)) return null\n \n const sessions = readdirSync(sessionsDir, { withFileTypes: true })\n .filter(d => d.isDirectory())\n .map(d => d.name)\n \n if (sessions.length === 0) return null\n \n // 返回最新的会话(按目录修改时间)\n let latestSession = sessions[0]\n let latestTime = 0\n \n for (const session of sessions) {\n const sessionPath = join(sessionsDir, session)\n const stat = require(\"fs\").statSync(sessionPath)\n if (stat.mtimeMs > latestTime) {\n latestTime = stat.mtimeMs\n latestSession = session\n }\n }\n \n return latestSession\n }\n\n function loadMemoryFiles(sessionId?: string) {\n const projectDir = getProjectMemoryDir(directory)\n const globalDir = getGlobalMemoryDir(directory)\n const memoryRoot = getMemoryRoot(directory)\n\n const memories: Record<string, string> = {}\n\n // 项目级记忆\n const files = [\n { key: \"memory\", path: join(projectDir, \"MEMORY.md\") },\n { key: \"notes\", path: join(projectDir, \"notes.md\") },\n { key: \"progress\", path: join(projectDir, \"tasks\", \"progress.md\") },\n { key: \"global_memory\", path: join(globalDir, \"MEMORY.md\") },\n ]\n\n for (const file of files) {\n if (existsSync(file.path)) {\n memories[file.key] = readFileSync(file.path, \"utf-8\")\n }\n }\n\n // 会话级 checkpoint(优先)\n if (sessionId) {\n const sessionCheckpoint = join(memoryRoot, \"sessions\", sessionId, \"checkpoint.md\")\n if (existsSync(sessionCheckpoint)) {\n memories.checkpoint = readFileSync(sessionCheckpoint, \"utf-8\")\n }\n }\n\n // 项目级 checkpoint(备选)\n if (!memories.checkpoint) {\n const projectCheckpoint = join(projectDir, \"checkpoint.md\")\n if (existsSync(projectCheckpoint)) {\n memories.checkpoint = readFileSync(projectCheckpoint, \"utf-8\")\n }\n }\n\n return memories\n }\n\n function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n }\n\n function smartTruncate(text: string, maxTokens: number): string {\n const estimatedTokens = estimateTokens(text)\n if (estimatedTokens <= maxTokens) return text\n\n const keepChars = maxTokens * 4 * 0.3\n const start = text.substring(0, keepChars)\n const end = text.substring(text.length - keepChars)\n\n return `${start}\\n\\n... [记忆已压缩,原 ${estimatedTokens} tokens] ...\\n\\n${end}`\n }\n\n function formatMemory(memories: Record<string, string>, budget: Record<string, number>): string {\n const sections = []\n\n if (memories.checkpoint && budget.checkpoint > 0) {\n sections.push(`## 检查点状态\\n${smartTruncate(memories.checkpoint, budget.checkpoint)}`)\n }\n if (memories.memory && budget.memory > 0) {\n sections.push(`## 项目记忆\\n${smartTruncate(memories.memory, budget.memory)}`)\n }\n if (memories.global_memory && budget.memory > 0) {\n sections.push(`## 全局记忆\\n${smartTruncate(memories.global_memory, budget.memory * 0.5)}`)\n }\n if (memories.notes && budget.notes > 0) {\n sections.push(`## 当前笔记\\n${smartTruncate(memories.notes, budget.notes)}`)\n }\n if (memories.progress && budget.progress > 0) {\n sections.push(`## 任务进度\\n${smartTruncate(memories.progress, budget.progress)}`)\n }\n\n return sections.join(\"\\n\\n\")\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 获取最新的会话 ID\n const latestSessionId = getLatestSessionId()\n const memories = loadMemoryFiles(latestSessionId)\n memoryCache.set(event.properties.sessionID, memories)\n \n // 记录注入状态\n const memoryKeys = Object.keys(memories)\n const totalTokens = Object.values(memories).reduce((sum, content) => sum + estimateTokens(content), 0)\n console.log(`[memory-core] Loaded ${memoryKeys.length} memory files (${totalTokens} tokens) for session ${event.properties.sessionID}`)\n }\n },\n\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) {\n console.log(`[memory-core] No memories found for session ${input.sessionID}`)\n return\n }\n\n const totalBudget = config.memory.injection.total_budget\n const allocation = config.memory.injection.allocation\n\n const budget = {\n checkpoint: Math.floor(totalBudget * allocation.checkpoint),\n memory: Math.floor(totalBudget * allocation.memory),\n notes: Math.floor(totalBudget * allocation.notes),\n progress: Math.floor(totalBudget * allocation.progress),\n }\n\n const memoryContext = formatMemory(memories, budget)\n\n if (memoryContext) {\n const injectedTokens = estimateTokens(memoryContext)\n console.log(`[memory-core] Injecting ${injectedTokens} tokens (budget: ${totalBudget}) into system prompt`)\n output.system.push(`\\n\\n# Injected Memory Context\\n${memoryContext}`)\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\n\n const criticalMemory = []\n if (memories.checkpoint) {\n criticalMemory.push(`当前检查点: ${memories.checkpoint.substring(0, 500)}`)\n }\n if (memories.progress) {\n criticalMemory.push(`任务进度摘要: ${memories.progress.substring(0, 300)}`)\n }\n\n output.context.push(`## 保留的关键记忆\\n${criticalMemory.join(\"\\n\\n\")}`)\n },\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir } from \"./paths\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const DreamPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryDir = getProjectMemoryDir(directory)\n mkdirSync(memoryDir, { recursive: true })\n\n function getLastTimestamp(metaFile: string): number {\n const metaPath = join(memoryDir, metaFile)\n if (existsSync(metaPath)) {\n const meta = JSON.parse(readFileSync(metaPath, \"utf-8\"))\n return meta.timestamp ?? 0\n }\n return 0\n }\n\n function setLastTimestamp(metaFile: string) {\n const metaPath = join(memoryDir, metaFile)\n writeFileSync(metaPath, JSON.stringify({ timestamp: Date.now() }))\n }\n\n function shouldAutoRun(metaFile: string, intervalDays: number): boolean {\n const lastRun = getLastTimestamp(metaFile)\n const intervalMs = intervalDays * 24 * 60 * 60 * 1000\n return Date.now() - lastRun > intervalMs\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 自动触发 dream\n if (config.memory.dream.auto && shouldAutoRun(\".dream-meta.json\", config.memory.dream.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"dream\",\n parts: [{\n type: \"text\",\n text: \"Run automatic dream memory consolidation pass.\"\n }],\n },\n })\n setLastTimestamp(\".dream-meta.json\")\n }\n\n // 自动触发 distill\n if (config.memory.distill.auto && shouldAutoRun(\".distill-meta.json\", config.memory.distill.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"distill\",\n parts: [{\n type: \"text\",\n text: \"Run automatic distill pass.\"\n }],\n },\n })\n setLastTimestamp(\".distill-meta.json\")\n }\n }\n },\n }\n}\n"],"mappings":"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","names":["import_fs","import_path","import_fs","import_fs","import_path","import_path","import_fs","import_path","import_fs","import_path","import_fs","import_path"]}
|
package/dist/index.mjs
CHANGED
|
@@ -14,12 +14,12 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
|
|
16
16
|
// src/store.ts
|
|
17
|
-
import Database from "
|
|
17
|
+
import { Database } from "bun:sqlite";
|
|
18
18
|
var MemoryStore = class {
|
|
19
19
|
db;
|
|
20
20
|
constructor(dbPath) {
|
|
21
21
|
this.db = new Database(dbPath);
|
|
22
|
-
this.db.
|
|
22
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
23
23
|
this.init();
|
|
24
24
|
}
|
|
25
25
|
init() {
|
|
@@ -39,10 +39,25 @@ var MemoryStore = class {
|
|
|
39
39
|
USING fts5(path, body, tokenize='unicode61')
|
|
40
40
|
`);
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* 构建 FTS5 查询 - 使用 MiMo Code 的方式
|
|
44
|
+
* 避免 FTS5 特殊字符导致崩溃
|
|
45
|
+
*/
|
|
46
|
+
buildFtsQuery(raw) {
|
|
47
|
+
const tokens = raw.match(/[\p{L}\p{N}_]+/gu)?.map((t) => t.trim()).filter(Boolean) ?? [];
|
|
48
|
+
if (tokens.length === 0) return null;
|
|
49
|
+
const quoted = tokens.map((t) => `"${t.replaceAll('"', "")}"`);
|
|
50
|
+
return quoted.join(" OR ");
|
|
51
|
+
}
|
|
42
52
|
search(query, filters = {}) {
|
|
43
|
-
|
|
44
|
-
if (
|
|
45
|
-
|
|
53
|
+
let ftsQuery;
|
|
54
|
+
if (query === "*") {
|
|
55
|
+
ftsQuery = "*";
|
|
56
|
+
} else {
|
|
57
|
+
const built = this.buildFtsQuery(query);
|
|
58
|
+
if (!built) return [];
|
|
59
|
+
ftsQuery = built;
|
|
60
|
+
}
|
|
46
61
|
const limit = filters.limit ?? 10;
|
|
47
62
|
let sql = `
|
|
48
63
|
SELECT f.path, m.scope, m.scope_id, m.type,
|
|
@@ -67,21 +82,21 @@ var MemoryStore = class {
|
|
|
67
82
|
}
|
|
68
83
|
sql += ` ORDER BY score LIMIT ?`;
|
|
69
84
|
params.push(limit);
|
|
70
|
-
return this.db.
|
|
85
|
+
return this.db.query(sql).all(...params);
|
|
71
86
|
}
|
|
72
87
|
write(path, scope, scope_id, type, content) {
|
|
73
88
|
const fingerprint = `${content.length}-${Date.now()}`;
|
|
74
89
|
const now = Date.now();
|
|
75
|
-
this.db.
|
|
90
|
+
this.db.query(`
|
|
76
91
|
INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)
|
|
77
92
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
78
93
|
`).run(path, scope, scope_id, type, fingerprint, now);
|
|
79
|
-
this.db.
|
|
80
|
-
this.db.
|
|
94
|
+
this.db.query(`DELETE FROM memory_fts WHERE path = ?`).run(path);
|
|
95
|
+
this.db.query(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content);
|
|
81
96
|
}
|
|
82
97
|
forget(memoryId) {
|
|
83
|
-
this.db.
|
|
84
|
-
this.db.
|
|
98
|
+
this.db.query("DELETE FROM memory_files WHERE path = ?").run(memoryId);
|
|
99
|
+
this.db.query("DELETE FROM memory_fts WHERE path = ?").run(memoryId);
|
|
85
100
|
}
|
|
86
101
|
close() {
|
|
87
102
|
this.db.close();
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/tool.ts","../src/store.ts","../src/reconcile.ts","../src/config.ts","../src/paths.ts","../src/checkpoint-plugin.ts","../src/injection-plugin.ts","../src/dream-plugin.ts"],"sourcesContent":["import type { Plugin } from \"@opencode-ai/plugin\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\nimport { createMemoryTool } from \"./tool\"\nimport { CheckpointPlugin } from \"./checkpoint-plugin\"\nimport { MemoryInjectionPlugin } from \"./injection-plugin\"\nimport { DreamPlugin } from \"./dream-plugin\"\nimport { getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir, getDbPath } from \"./paths\"\nimport { ensureConfig } from \"./config\"\n\nexport const MemoryCorePlugin: Plugin = async (ctx) => {\n // 确保配置文件存在\n ensureConfig(ctx.directory)\n\n const memoryRoot = getMemoryRoot(ctx.directory)\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir(ctx.directory)\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(projectDir, \"sessions\"), { recursive: true })\n mkdirSync(join(projectDir, \"tasks\"), { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(ctx.directory),\n })\n\n // 初始化子插件\n const checkpointPlugin = await CheckpointPlugin(ctx)\n const injectionPlugin = await MemoryInjectionPlugin(ctx)\n const dreamPlugin = await DreamPlugin(ctx)\n\n return {\n tool: {\n memory: memoryTool,\n },\n event: async (input) => {\n await checkpointPlugin.event?.(input)\n await injectionPlugin.event?.(input)\n await dreamPlugin.event?.(input)\n },\n \"experimental.chat.system.transform\": async (input, output) => {\n await injectionPlugin[\"experimental.chat.system.transform\"]?.(input, output)\n },\n \"experimental.session.compacting\": async (input, output) => {\n await checkpointPlugin[\"experimental.session.compacting\"]?.(input, output)\n await injectionPlugin[\"experimental.session.compacting\"]?.(input, output)\n },\n }\n}\n\nexport default MemoryCorePlugin\n\n// 导出子模块\nexport { MemoryStore } from \"./store\"\nexport { createMemoryTool } from \"./tool\"\nexport { resolveProjectId, getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir } from \"./paths\"\nexport { loadConfig, DEFAULT_CONFIG } from \"./config\"\nexport type { MemoryConfig } from \"./config\"\nexport type { SearchResult, SearchFilters } from \"./store\"\n","import { tool } from \"@opencode-ai/plugin\"\nimport { z } from \"zod\"\nimport { MemoryStore } from \"./store\"\nimport { reconcileMemoryDir } from \"./reconcile\"\nimport { mkdirSync } from \"fs\"\n\nexport function createMemoryTool(ctx: { memoryDir: string; dbPath: string }) {\n let store: MemoryStore | null = null\n\n function ensureStore() {\n if (!store) {\n mkdirSync(ctx.memoryDir, { recursive: true })\n store = new MemoryStore(ctx.dbPath)\n reconcileMemoryDir(store, ctx.memoryDir)\n }\n return store\n }\n\n return tool({\n description: \"Search or write to the persistent memory store. Search returns ranked results across memory files. Write saves content to a memory file.\",\n args: {\n operation: z.enum([\"search\", \"write\", \"list\", \"forget\"]),\n query: z.string().optional(),\n scope: z.string().optional(),\n scope_id: z.string().optional(),\n type: z.string().optional(),\n limit: z.number().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n memory_id: z.string().optional(),\n },\n execute(args: any) {\n const s = ensureStore()\n\n if (args.operation === \"search\") {\n if (!args.query) return \"query is required for search\"\n const results = s.search(args.query, {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit,\n })\n if (results.length === 0) return \"No results found\"\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"write\") {\n if (!args.path) return \"path is required for write\"\n if (!args.content) return \"content is required for write\"\n s.write(\n args.path,\n args.scope ?? \"unknown\",\n args.scope_id ?? \"\",\n args.type ?? \"snapshot\",\n args.content,\n )\n return `Wrote to ${args.path}`\n }\n\n if (args.operation === \"list\") {\n const results = s.search(\"*\", {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit ?? 50,\n })\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"forget\") {\n if (!args.memory_id) return \"memory_id is required for forget\"\n s.forget(args.memory_id)\n return `Forgot ${args.memory_id}`\n }\n\n return \"Invalid operation\"\n },\n })\n}\n","import Database from \"better-sqlite3\"\n\nexport interface SearchFilters {\n scope?: string\n scope_id?: string\n type?: string\n limit?: number\n}\n\nexport interface SearchResult {\n path: string\n scope: string\n scope_id: string\n type: string\n snippet: string\n score: number\n}\n\nexport class MemoryStore {\n public db: Database.Database\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath)\n this.db.pragma(\"journal_mode = WAL\")\n this.init()\n }\n\n private init() {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS memory_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL UNIQUE,\n scope TEXT NOT NULL,\n scope_id TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL,\n fingerprint TEXT NOT NULL,\n last_indexed_at INTEGER NOT NULL\n )\n `)\n this.db.exec(`\n CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts\n USING fts5(path, body, tokenize='unicode61')\n `)\n }\n\n search(query: string, filters: SearchFilters = {}): SearchResult[] {\n const tokens = query.split(/\\s+/).filter(Boolean).map(t => `\"${t}\"`)\n if (tokens.length === 0) return []\n const ftsQuery = tokens.join(\" OR \")\n const limit = filters.limit ?? 10\n\n let sql = `\n SELECT f.path, m.scope, m.scope_id, m.type,\n snippet(memory_fts, 1, '<<', '>>', '...', 32) AS snippet,\n bm25(memory_fts) AS score\n FROM memory_fts f\n JOIN memory_files m ON m.path = f.path\n WHERE memory_fts MATCH ?\n `\n const params: any[] = [ftsQuery]\n if (filters.scope) { sql += ` AND m.scope = ?`; params.push(filters.scope) }\n if (filters.scope_id) { sql += ` AND m.scope_id = ?`; params.push(filters.scope_id) }\n if (filters.type) { sql += ` AND m.type = ?`; params.push(filters.type) }\n sql += ` ORDER BY score LIMIT ?`\n params.push(limit)\n return this.db.prepare(sql).all(...params) as SearchResult[]\n }\n\n write(path: string, scope: string, scope_id: string, type: string, content: string) {\n const fingerprint = `${content.length}-${Date.now()}`\n const now = Date.now()\n\n this.db.prepare(`\n INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(path, scope, scope_id, type, fingerprint, now)\n\n this.db.prepare(`DELETE FROM memory_fts WHERE path = ?`).run(path)\n this.db.prepare(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content)\n }\n\n forget(memoryId: string) {\n this.db.prepare(\"DELETE FROM memory_files WHERE path = ?\").run(memoryId)\n this.db.prepare(\"DELETE FROM memory_fts WHERE path = ?\").run(memoryId)\n }\n\n close() {\n this.db.close()\n }\n}\n","import { readdirSync, readFileSync } from \"fs\"\nimport { join, relative, sep } from \"path\"\nimport type { MemoryStore } from \"./store\"\n\nfunction parseScopeAndId(memoryRoot: string, filePath: string): { scope: string; scope_id: string } {\n const rel = relative(memoryRoot, filePath).split(sep)\n if (rel[0] === \"global\") return { scope: \"global\", scope_id: \"\" }\n if (rel[0] === \"projects\" && rel.length >= 3) return { scope: \"projects\", scope_id: rel[1] }\n if (rel[0] === \"sessions\" && rel.length >= 3) return { scope: \"sessions\", scope_id: rel[1] }\n return { scope: \"unknown\", scope_id: \"\" }\n}\n\nfunction walkMdFiles(dir: string): string[] {\n const results: string[] = []\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...walkMdFiles(full))\n } else if (entry.name.endsWith(\".md\")) {\n results.push(full)\n }\n }\n return results\n}\n\nexport function reconcileMemoryDir(store: MemoryStore, memoryRoot: string) {\n const filesOnDisk = walkMdFiles(memoryRoot)\n const diskPaths = new Set<string>()\n\n for (const file of filesOnDisk) {\n diskPaths.add(file)\n const content = readFileSync(file, \"utf-8\")\n const { scope, scope_id } = parseScopeAndId(memoryRoot, file)\n store.write(file, scope, scope_id, \"snapshot\", content)\n }\n\n const indexed = store.db.prepare(\"SELECT path FROM memory_files\").all() as { path: string }[]\n for (const row of indexed) {\n if (!diskPaths.has(row.path)) {\n store.forget(row.path)\n }\n }\n}\n","import { readFileSync, existsSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join, dirname } from \"path\"\n\nexport interface MemoryConfig {\n memory: {\n injection: {\n total_budget: number\n allocation: {\n checkpoint: number\n memory: number\n notes: number\n progress: number\n buffer: number\n }\n }\n checkpoint: {\n thresholds: string[]\n drain_timeout_ms: number\n idle_timeout_ms: number\n }\n dream: {\n auto: boolean\n interval_days: number\n }\n distill: {\n auto: boolean\n interval_days: number\n }\n }\n}\n\nexport const DEFAULT_CONFIG: MemoryConfig = {\n memory: {\n injection: {\n total_budget: 2000,\n allocation: {\n checkpoint: 0.30,\n memory: 0.25,\n notes: 0.20,\n progress: 0.15,\n buffer: 0.10\n }\n },\n checkpoint: {\n thresholds: [\"20%\", \"40%\", \"60%\", \"80%\"],\n drain_timeout_ms: 120000,\n idle_timeout_ms: 300000\n },\n dream: {\n auto: true,\n interval_days: 7\n },\n distill: {\n auto: true,\n interval_days: 30\n }\n }\n}\n\nexport function getConfigPath(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"config.json\")\n}\n\nexport function loadConfig(projectRoot: string): MemoryConfig {\n const configPath = getConfigPath(projectRoot)\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, \"utf-8\")\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) }\n }\n return DEFAULT_CONFIG\n}\n\nexport function ensureConfig(projectRoot: string): void {\n const configPath = getConfigPath(projectRoot)\n if (!existsSync(configPath)) {\n mkdirSync(dirname(configPath), { recursive: true })\n writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2))\n }\n}\n","import { createHash } from \"crypto\"\nimport { join } from \"path\"\n\nexport type Scope = \"global\" | \"projects\" | \"sessions\"\n\nexport function resolveProjectId(absRepoPath: string): string {\n return createHash(\"sha256\").update(absRepoPath).digest(\"hex\").slice(0, 12)\n}\n\nexport function getMemoryRoot(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(projectRoot), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(projectRoot), \"sessions\", sessionId)\n}\n\nexport function getDbPath(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"memory.db\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const CheckpointPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryRoot = getMemoryRoot(directory)\n const projectDir = getProjectMemoryDir(directory)\n \n // 创建必要的目录\n mkdirSync(memoryRoot, { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n let lastCheckpointRatio = 0\n const THRESHOLDS = config.memory.checkpoint.thresholds.map(t => parseFloat(t) / 100)\n let currentSessionID: string | null = null\n\n return {\n event: async ({ event }) => {\n // 记录当前会话 ID\n if (event.type === \"session.created\") {\n const newSessionID = event.properties?.info?.id\n \n // 触发 1: 新建会话时,保存上一个会话的 checkpoint\n if (currentSessionID && currentSessionID !== newSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"new session created\")\n }\n \n currentSessionID = newSessionID || null\n }\n\n // 触发 2: Token 比例阈值\n if (event.type === \"session.next.step.ended\") {\n const ratio = event.properties.tokens / event.properties.contextLimit\n const nextThreshold = THRESHOLDS.find(t => t > lastCheckpointRatio)\n if (nextThreshold && ratio >= nextThreshold) {\n lastCheckpointRatio = ratio\n await triggerCheckpoint(client, event.properties.sessionID, directory, `token ratio ${Math.round(ratio * 100)}%`)\n }\n }\n\n // 触发 3: 会话结束(idle 超时)\n if (event.type === \"session.status\" && event.properties?.status?.type === \"idle\") {\n setTimeout(async () => {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"idle timeout\")\n }, config.memory.checkpoint.idle_timeout_ms)\n }\n\n // 触发 4: 会话空闲\n if (event.type === \"session.idle\") {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"session idle\")\n }\n\n // 触发 5: 会话删除时保存 checkpoint\n if (event.type === \"session.deleted\") {\n await triggerCheckpoint(client, event.properties.info.id, directory, \"session deleted\")\n }\n\n // 触发 6: 退出程序时保存当前会话 checkpoint\n if (event.type === \"server.instance.disposed\") {\n if (currentSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"app exit\")\n }\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n output.context.push(`\n## Checkpoint Instructions\nExtract and preserve these 11 fields:\n1. Intent (用户的核心目标)\n2. Actions (已执行的操作)\n3. Task Tree (子任务层级)\n4. Errors & Workarounds (遇到的问题及解决)\n5. Design Decisions (关键技术选择)\n6. Constraints (限制条件)\n7. Current State (任务进度)\n8. TODOs (剩余工作)\n9. Code Changes Summary (Git diff 概要)\n10. Key File Paths (涉及的核心文件)\n11. Timestamp (检查点创建时间)\n `)\n },\n }\n}\n\nasync function triggerCheckpoint(client: any, sessionID: string, directory: string, reason?: string) {\n const messages = await client.session.messages({ path: { id: sessionID } })\n const context = constructCheckpointContext(messages)\n\n // 创建会话目录\n const sessionDir = getSessionMemoryDir(directory, sessionID)\n mkdirSync(sessionDir, { recursive: true })\n\n // 记录日志\n await client.app.log({\n body: {\n service: 'memory-core',\n level: 'info',\n message: `Checkpoint triggered: ${reason || 'unknown'} (session: ${sessionID})`\n }\n })\n\n // 非阻塞调用,不等待完成\n client.session.prompt({\n path: { id: sessionID },\n body: {\n agent: \"checkpoint-writer\",\n parts: [{\n type: \"text\",\n text: `Extract checkpoint from this context:\\n${context}\\n\\nWrite checkpoint to:\\n- Session: .super-pocock/memory/sessions/${sessionID}/checkpoint.md\\n- Project: .super-pocock/memory/projects/<pid>/checkpoint.md`\n }],\n },\n }).catch((err: any) => {\n // 静默处理错误,不影响主 agent\n console.error('Checkpoint failed:', err)\n })\n}\n\nfunction constructCheckpointContext(messages: any[]): string {\n return messages.map(m => `[${m.role}]: ${m.content}`).join(\"\\n\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getGlobalMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { existsSync, readFileSync, readdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const MemoryInjectionPlugin: Plugin = async ({ directory }) => {\n const config = loadConfig(directory)\n const memoryCache = new Map<string, Record<string, string>>()\n\n function getLatestSessionId(): string | null {\n const sessionsDir = join(getMemoryRoot(directory), \"sessions\")\n if (!existsSync(sessionsDir)) return null\n \n const sessions = readdirSync(sessionsDir, { withFileTypes: true })\n .filter(d => d.isDirectory())\n .map(d => d.name)\n \n if (sessions.length === 0) return null\n \n // 返回最新的会话(按目录修改时间)\n let latestSession = sessions[0]\n let latestTime = 0\n \n for (const session of sessions) {\n const sessionPath = join(sessionsDir, session)\n const stat = require(\"fs\").statSync(sessionPath)\n if (stat.mtimeMs > latestTime) {\n latestTime = stat.mtimeMs\n latestSession = session\n }\n }\n \n return latestSession\n }\n\n function loadMemoryFiles(sessionId?: string) {\n const projectDir = getProjectMemoryDir(directory)\n const globalDir = getGlobalMemoryDir(directory)\n const memoryRoot = getMemoryRoot(directory)\n\n const memories: Record<string, string> = {}\n\n // 项目级记忆\n const files = [\n { key: \"memory\", path: join(projectDir, \"MEMORY.md\") },\n { key: \"notes\", path: join(projectDir, \"notes.md\") },\n { key: \"progress\", path: join(projectDir, \"tasks\", \"progress.md\") },\n { key: \"global_memory\", path: join(globalDir, \"MEMORY.md\") },\n ]\n\n for (const file of files) {\n if (existsSync(file.path)) {\n memories[file.key] = readFileSync(file.path, \"utf-8\")\n }\n }\n\n // 会话级 checkpoint(优先)\n if (sessionId) {\n const sessionCheckpoint = join(memoryRoot, \"sessions\", sessionId, \"checkpoint.md\")\n if (existsSync(sessionCheckpoint)) {\n memories.checkpoint = readFileSync(sessionCheckpoint, \"utf-8\")\n }\n }\n\n // 项目级 checkpoint(备选)\n if (!memories.checkpoint) {\n const projectCheckpoint = join(projectDir, \"checkpoint.md\")\n if (existsSync(projectCheckpoint)) {\n memories.checkpoint = readFileSync(projectCheckpoint, \"utf-8\")\n }\n }\n\n return memories\n }\n\n function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n }\n\n function smartTruncate(text: string, maxTokens: number): string {\n const estimatedTokens = estimateTokens(text)\n if (estimatedTokens <= maxTokens) return text\n\n const keepChars = maxTokens * 4 * 0.3\n const start = text.substring(0, keepChars)\n const end = text.substring(text.length - keepChars)\n\n return `${start}\\n\\n... [记忆已压缩,原 ${estimatedTokens} tokens] ...\\n\\n${end}`\n }\n\n function formatMemory(memories: Record<string, string>, budget: Record<string, number>): string {\n const sections = []\n\n if (memories.checkpoint && budget.checkpoint > 0) {\n sections.push(`## 检查点状态\\n${smartTruncate(memories.checkpoint, budget.checkpoint)}`)\n }\n if (memories.memory && budget.memory > 0) {\n sections.push(`## 项目记忆\\n${smartTruncate(memories.memory, budget.memory)}`)\n }\n if (memories.global_memory && budget.memory > 0) {\n sections.push(`## 全局记忆\\n${smartTruncate(memories.global_memory, budget.memory * 0.5)}`)\n }\n if (memories.notes && budget.notes > 0) {\n sections.push(`## 当前笔记\\n${smartTruncate(memories.notes, budget.notes)}`)\n }\n if (memories.progress && budget.progress > 0) {\n sections.push(`## 任务进度\\n${smartTruncate(memories.progress, budget.progress)}`)\n }\n\n return sections.join(\"\\n\\n\")\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 获取最新的会话 ID\n const latestSessionId = getLatestSessionId()\n const memories = loadMemoryFiles(latestSessionId)\n memoryCache.set(event.properties.sessionID, memories)\n \n // 记录注入状态\n const memoryKeys = Object.keys(memories)\n const totalTokens = Object.values(memories).reduce((sum, content) => sum + estimateTokens(content), 0)\n console.log(`[memory-core] Loaded ${memoryKeys.length} memory files (${totalTokens} tokens) for session ${event.properties.sessionID}`)\n }\n },\n\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) {\n console.log(`[memory-core] No memories found for session ${input.sessionID}`)\n return\n }\n\n const totalBudget = config.memory.injection.total_budget\n const allocation = config.memory.injection.allocation\n\n const budget = {\n checkpoint: Math.floor(totalBudget * allocation.checkpoint),\n memory: Math.floor(totalBudget * allocation.memory),\n notes: Math.floor(totalBudget * allocation.notes),\n progress: Math.floor(totalBudget * allocation.progress),\n }\n\n const memoryContext = formatMemory(memories, budget)\n\n if (memoryContext) {\n const injectedTokens = estimateTokens(memoryContext)\n console.log(`[memory-core] Injecting ${injectedTokens} tokens (budget: ${totalBudget}) into system prompt`)\n output.system.push(`\\n\\n# Injected Memory Context\\n${memoryContext}`)\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\n\n const criticalMemory = []\n if (memories.checkpoint) {\n criticalMemory.push(`当前检查点: ${memories.checkpoint.substring(0, 500)}`)\n }\n if (memories.progress) {\n criticalMemory.push(`任务进度摘要: ${memories.progress.substring(0, 300)}`)\n }\n\n output.context.push(`## 保留的关键记忆\\n${criticalMemory.join(\"\\n\\n\")}`)\n },\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir } from \"./paths\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const DreamPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryDir = getProjectMemoryDir(directory)\n mkdirSync(memoryDir, { recursive: true })\n\n function getLastTimestamp(metaFile: string): number {\n const metaPath = join(memoryDir, metaFile)\n if (existsSync(metaPath)) {\n const meta = JSON.parse(readFileSync(metaPath, \"utf-8\"))\n return meta.timestamp ?? 0\n }\n return 0\n }\n\n function setLastTimestamp(metaFile: string) {\n const metaPath = join(memoryDir, metaFile)\n writeFileSync(metaPath, JSON.stringify({ timestamp: Date.now() }))\n }\n\n function shouldAutoRun(metaFile: string, intervalDays: number): boolean {\n const lastRun = getLastTimestamp(metaFile)\n const intervalMs = intervalDays * 24 * 60 * 60 * 1000\n return Date.now() - lastRun > intervalMs\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 自动触发 dream\n if (config.memory.dream.auto && shouldAutoRun(\".dream-meta.json\", config.memory.dream.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"dream\",\n parts: [{\n type: \"text\",\n text: \"Run automatic dream memory consolidation pass.\"\n }],\n },\n })\n setLastTimestamp(\".dream-meta.json\")\n }\n\n // 自动触发 distill\n if (config.memory.distill.auto && shouldAutoRun(\".distill-meta.json\", config.memory.distill.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"distill\",\n parts: [{\n type: \"text\",\n text: \"Run automatic distill pass.\"\n }],\n },\n })\n setLastTimestamp(\".distill-meta.json\")\n }\n }\n },\n }\n}\n"],"mappings":"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","names":["mkdirSync","join","readFileSync","mkdirSync","join","join","mkdirSync","join","existsSync","readFileSync","readdirSync","join","existsSync","readFileSync","writeFileSync","mkdirSync","join","mkdirSync","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tool.ts","../src/store.ts","../src/reconcile.ts","../src/config.ts","../src/paths.ts","../src/checkpoint-plugin.ts","../src/injection-plugin.ts","../src/dream-plugin.ts"],"sourcesContent":["import type { Plugin } from \"@opencode-ai/plugin\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\nimport { createMemoryTool } from \"./tool\"\nimport { CheckpointPlugin } from \"./checkpoint-plugin\"\nimport { MemoryInjectionPlugin } from \"./injection-plugin\"\nimport { DreamPlugin } from \"./dream-plugin\"\nimport { getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir, getDbPath } from \"./paths\"\nimport { ensureConfig } from \"./config\"\n\nexport const MemoryCorePlugin: Plugin = async (ctx) => {\n // 确保配置文件存在\n ensureConfig(ctx.directory)\n\n const memoryRoot = getMemoryRoot(ctx.directory)\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir(ctx.directory)\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(projectDir, \"sessions\"), { recursive: true })\n mkdirSync(join(projectDir, \"tasks\"), { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(ctx.directory),\n })\n\n // 初始化子插件\n const checkpointPlugin = await CheckpointPlugin(ctx)\n const injectionPlugin = await MemoryInjectionPlugin(ctx)\n const dreamPlugin = await DreamPlugin(ctx)\n\n return {\n tool: {\n memory: memoryTool,\n },\n event: async (input) => {\n await checkpointPlugin.event?.(input)\n await injectionPlugin.event?.(input)\n await dreamPlugin.event?.(input)\n },\n \"experimental.chat.system.transform\": async (input, output) => {\n await injectionPlugin[\"experimental.chat.system.transform\"]?.(input, output)\n },\n \"experimental.session.compacting\": async (input, output) => {\n await checkpointPlugin[\"experimental.session.compacting\"]?.(input, output)\n await injectionPlugin[\"experimental.session.compacting\"]?.(input, output)\n },\n }\n}\n\nexport default MemoryCorePlugin\n\n// 导出子模块\nexport { MemoryStore } from \"./store\"\nexport { createMemoryTool } from \"./tool\"\nexport { resolveProjectId, getMemoryRoot, getProjectMemoryDir, getGlobalMemoryDir } from \"./paths\"\nexport { loadConfig, DEFAULT_CONFIG } from \"./config\"\nexport type { MemoryConfig } from \"./config\"\nexport type { SearchResult, SearchFilters } from \"./store\"\n","import { tool } from \"@opencode-ai/plugin\"\nimport { z } from \"zod\"\nimport { MemoryStore } from \"./store\"\nimport { reconcileMemoryDir } from \"./reconcile\"\nimport { mkdirSync } from \"fs\"\n\nexport function createMemoryTool(ctx: { memoryDir: string; dbPath: string }) {\n let store: MemoryStore | null = null\n\n function ensureStore() {\n if (!store) {\n mkdirSync(ctx.memoryDir, { recursive: true })\n store = new MemoryStore(ctx.dbPath)\n reconcileMemoryDir(store, ctx.memoryDir)\n }\n return store\n }\n\n return tool({\n description: \"Search or write to the persistent memory store. Search returns ranked results across memory files. Write saves content to a memory file.\",\n args: {\n operation: z.enum([\"search\", \"write\", \"list\", \"forget\"]),\n query: z.string().optional(),\n scope: z.string().optional(),\n scope_id: z.string().optional(),\n type: z.string().optional(),\n limit: z.number().optional(),\n path: z.string().optional(),\n content: z.string().optional(),\n memory_id: z.string().optional(),\n },\n execute(args: any) {\n const s = ensureStore()\n\n if (args.operation === \"search\") {\n if (!args.query) return \"query is required for search\"\n const results = s.search(args.query, {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit,\n })\n if (results.length === 0) return \"No results found\"\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"write\") {\n if (!args.path) return \"path is required for write\"\n if (!args.content) return \"content is required for write\"\n s.write(\n args.path,\n args.scope ?? \"unknown\",\n args.scope_id ?? \"\",\n args.type ?? \"snapshot\",\n args.content,\n )\n return `Wrote to ${args.path}`\n }\n\n if (args.operation === \"list\") {\n const results = s.search(\"*\", {\n scope: args.scope,\n scope_id: args.scope_id,\n type: args.type,\n limit: args.limit ?? 50,\n })\n return JSON.stringify(results, null, 2)\n }\n\n if (args.operation === \"forget\") {\n if (!args.memory_id) return \"memory_id is required for forget\"\n s.forget(args.memory_id)\n return `Forgot ${args.memory_id}`\n }\n\n return \"Invalid operation\"\n },\n })\n}\n","import { Database } from \"bun:sqlite\"\n\nexport interface SearchFilters {\n scope?: string\n scope_id?: string\n type?: string\n limit?: number\n}\n\nexport interface SearchResult {\n path: string\n scope: string\n scope_id: string\n type: string\n snippet: string\n score: number\n}\n\nexport class MemoryStore {\n public db: Database\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath)\n this.db.exec(\"PRAGMA journal_mode = WAL\")\n this.init()\n }\n\n private init() {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS memory_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL UNIQUE,\n scope TEXT NOT NULL,\n scope_id TEXT NOT NULL DEFAULT '',\n type TEXT NOT NULL,\n fingerprint TEXT NOT NULL,\n last_indexed_at INTEGER NOT NULL\n )\n `)\n this.db.exec(`\n CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts\n USING fts5(path, body, tokenize='unicode61')\n `)\n }\n\n /**\n * 构建 FTS5 查询 - 使用 MiMo Code 的方式\n * 避免 FTS5 特殊字符导致崩溃\n */\n private buildFtsQuery(raw: string): string | null {\n const tokens =\n raw\n .match(/[\\p{L}\\p{N}_]+/gu)\n ?.map((t) => t.trim())\n .filter(Boolean) ?? []\n if (tokens.length === 0) return null\n const quoted = tokens.map((t) => `\"${t.replaceAll('\"', \"\")}\"`)\n return quoted.join(\" OR \")\n }\n\n search(query: string, filters: SearchFilters = {}): SearchResult[] {\n // 处理通配符查询\n let ftsQuery: string\n if (query === \"*\") {\n ftsQuery = \"*\"\n } else {\n const built = this.buildFtsQuery(query)\n if (!built) return []\n ftsQuery = built\n }\n\n const limit = filters.limit ?? 10\n\n let sql = `\n SELECT f.path, m.scope, m.scope_id, m.type,\n snippet(memory_fts, 1, '<<', '>>', '...', 32) AS snippet,\n bm25(memory_fts) AS score\n FROM memory_fts f\n JOIN memory_files m ON m.path = f.path\n WHERE memory_fts MATCH ?\n `\n const params: unknown[] = [ftsQuery]\n if (filters.scope) { sql += ` AND m.scope = ?`; params.push(filters.scope) }\n if (filters.scope_id) { sql += ` AND m.scope_id = ?`; params.push(filters.scope_id) }\n if (filters.type) { sql += ` AND m.type = ?`; params.push(filters.type) }\n sql += ` ORDER BY score LIMIT ?`\n params.push(limit)\n return this.db.query(sql).all(...params) as SearchResult[]\n }\n\n write(path: string, scope: string, scope_id: string, type: string, content: string) {\n const fingerprint = `${content.length}-${Date.now()}`\n const now = Date.now()\n\n this.db.query(`\n INSERT OR REPLACE INTO memory_files (path, scope, scope_id, type, fingerprint, last_indexed_at)\n VALUES (?, ?, ?, ?, ?, ?)\n `).run(path, scope, scope_id, type, fingerprint, now)\n\n this.db.query(`DELETE FROM memory_fts WHERE path = ?`).run(path)\n this.db.query(`INSERT INTO memory_fts (path, body) VALUES (?, ?)`).run(path, content)\n }\n\n forget(memoryId: string) {\n this.db.query(\"DELETE FROM memory_files WHERE path = ?\").run(memoryId)\n this.db.query(\"DELETE FROM memory_fts WHERE path = ?\").run(memoryId)\n }\n\n close() {\n this.db.close()\n }\n}\n","import { readdirSync, readFileSync } from \"fs\"\nimport { join, relative, sep } from \"path\"\nimport type { MemoryStore } from \"./store\"\n\nfunction parseScopeAndId(memoryRoot: string, filePath: string): { scope: string; scope_id: string } {\n const rel = relative(memoryRoot, filePath).split(sep)\n if (rel[0] === \"global\") return { scope: \"global\", scope_id: \"\" }\n if (rel[0] === \"projects\" && rel.length >= 3) return { scope: \"projects\", scope_id: rel[1] }\n if (rel[0] === \"sessions\" && rel.length >= 3) return { scope: \"sessions\", scope_id: rel[1] }\n return { scope: \"unknown\", scope_id: \"\" }\n}\n\nfunction walkMdFiles(dir: string): string[] {\n const results: string[] = []\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n results.push(...walkMdFiles(full))\n } else if (entry.name.endsWith(\".md\")) {\n results.push(full)\n }\n }\n return results\n}\n\nexport function reconcileMemoryDir(store: MemoryStore, memoryRoot: string) {\n const filesOnDisk = walkMdFiles(memoryRoot)\n const diskPaths = new Set<string>()\n\n for (const file of filesOnDisk) {\n diskPaths.add(file)\n const content = readFileSync(file, \"utf-8\")\n const { scope, scope_id } = parseScopeAndId(memoryRoot, file)\n store.write(file, scope, scope_id, \"snapshot\", content)\n }\n\n const indexed = store.db.prepare(\"SELECT path FROM memory_files\").all() as { path: string }[]\n for (const row of indexed) {\n if (!diskPaths.has(row.path)) {\n store.forget(row.path)\n }\n }\n}\n","import { readFileSync, existsSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join, dirname } from \"path\"\n\nexport interface MemoryConfig {\n memory: {\n injection: {\n total_budget: number\n allocation: {\n checkpoint: number\n memory: number\n notes: number\n progress: number\n buffer: number\n }\n }\n checkpoint: {\n thresholds: string[]\n drain_timeout_ms: number\n idle_timeout_ms: number\n }\n dream: {\n auto: boolean\n interval_days: number\n }\n distill: {\n auto: boolean\n interval_days: number\n }\n }\n}\n\nexport const DEFAULT_CONFIG: MemoryConfig = {\n memory: {\n injection: {\n total_budget: 2000,\n allocation: {\n checkpoint: 0.30,\n memory: 0.25,\n notes: 0.20,\n progress: 0.15,\n buffer: 0.10\n }\n },\n checkpoint: {\n thresholds: [\"20%\", \"40%\", \"60%\", \"80%\"],\n drain_timeout_ms: 120000,\n idle_timeout_ms: 300000\n },\n dream: {\n auto: true,\n interval_days: 7\n },\n distill: {\n auto: true,\n interval_days: 30\n }\n }\n}\n\nexport function getConfigPath(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"config.json\")\n}\n\nexport function loadConfig(projectRoot: string): MemoryConfig {\n const configPath = getConfigPath(projectRoot)\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, \"utf-8\")\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) }\n }\n return DEFAULT_CONFIG\n}\n\nexport function ensureConfig(projectRoot: string): void {\n const configPath = getConfigPath(projectRoot)\n if (!existsSync(configPath)) {\n mkdirSync(dirname(configPath), { recursive: true })\n writeFileSync(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2))\n }\n}\n","import { createHash } from \"crypto\"\nimport { join } from \"path\"\n\nexport type Scope = \"global\" | \"projects\" | \"sessions\"\n\nexport function resolveProjectId(absRepoPath: string): string {\n return createHash(\"sha256\").update(absRepoPath).digest(\"hex\").slice(0, 12)\n}\n\nexport function getMemoryRoot(projectRoot: string): string {\n return join(projectRoot, \".super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(projectRoot), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(projectRoot), \"sessions\", sessionId)\n}\n\nexport function getDbPath(projectRoot: string): string {\n return join(getMemoryRoot(projectRoot), \"memory.db\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const CheckpointPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryRoot = getMemoryRoot(directory)\n const projectDir = getProjectMemoryDir(directory)\n \n // 创建必要的目录\n mkdirSync(memoryRoot, { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n let lastCheckpointRatio = 0\n const THRESHOLDS = config.memory.checkpoint.thresholds.map(t => parseFloat(t) / 100)\n let currentSessionID: string | null = null\n\n return {\n event: async ({ event }) => {\n // 记录当前会话 ID\n if (event.type === \"session.created\") {\n const newSessionID = event.properties?.info?.id\n \n // 触发 1: 新建会话时,保存上一个会话的 checkpoint\n if (currentSessionID && currentSessionID !== newSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"new session created\")\n }\n \n currentSessionID = newSessionID || null\n }\n\n // 触发 2: Token 比例阈值\n if (event.type === \"session.next.step.ended\") {\n const ratio = event.properties.tokens / event.properties.contextLimit\n const nextThreshold = THRESHOLDS.find(t => t > lastCheckpointRatio)\n if (nextThreshold && ratio >= nextThreshold) {\n lastCheckpointRatio = ratio\n await triggerCheckpoint(client, event.properties.sessionID, directory, `token ratio ${Math.round(ratio * 100)}%`)\n }\n }\n\n // 触发 3: 会话结束(idle 超时)\n if (event.type === \"session.status\" && event.properties?.status?.type === \"idle\") {\n setTimeout(async () => {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"idle timeout\")\n }, config.memory.checkpoint.idle_timeout_ms)\n }\n\n // 触发 4: 会话空闲\n if (event.type === \"session.idle\") {\n await triggerCheckpoint(client, event.properties.sessionID, directory, \"session idle\")\n }\n\n // 触发 5: 会话删除时保存 checkpoint\n if (event.type === \"session.deleted\") {\n await triggerCheckpoint(client, event.properties.info.id, directory, \"session deleted\")\n }\n\n // 触发 6: 退出程序时保存当前会话 checkpoint\n if (event.type === \"server.instance.disposed\") {\n if (currentSessionID) {\n await triggerCheckpoint(client, currentSessionID, directory, \"app exit\")\n }\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n output.context.push(`\n## Checkpoint Instructions\nExtract and preserve these 11 fields:\n1. Intent (用户的核心目标)\n2. Actions (已执行的操作)\n3. Task Tree (子任务层级)\n4. Errors & Workarounds (遇到的问题及解决)\n5. Design Decisions (关键技术选择)\n6. Constraints (限制条件)\n7. Current State (任务进度)\n8. TODOs (剩余工作)\n9. Code Changes Summary (Git diff 概要)\n10. Key File Paths (涉及的核心文件)\n11. Timestamp (检查点创建时间)\n `)\n },\n }\n}\n\nasync function triggerCheckpoint(client: any, sessionID: string, directory: string, reason?: string) {\n const messages = await client.session.messages({ path: { id: sessionID } })\n const context = constructCheckpointContext(messages)\n\n // 创建会话目录\n const sessionDir = getSessionMemoryDir(directory, sessionID)\n mkdirSync(sessionDir, { recursive: true })\n\n // 记录日志\n await client.app.log({\n body: {\n service: 'memory-core',\n level: 'info',\n message: `Checkpoint triggered: ${reason || 'unknown'} (session: ${sessionID})`\n }\n })\n\n // 非阻塞调用,不等待完成\n client.session.prompt({\n path: { id: sessionID },\n body: {\n agent: \"checkpoint-writer\",\n parts: [{\n type: \"text\",\n text: `Extract checkpoint from this context:\\n${context}\\n\\nWrite checkpoint to:\\n- Session: .super-pocock/memory/sessions/${sessionID}/checkpoint.md\\n- Project: .super-pocock/memory/projects/<pid>/checkpoint.md`\n }],\n },\n }).catch((err: any) => {\n // 静默处理错误,不影响主 agent\n console.error('Checkpoint failed:', err)\n })\n}\n\nfunction constructCheckpointContext(messages: any[]): string {\n return messages.map(m => `[${m.role}]: ${m.content}`).join(\"\\n\")\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir, getGlobalMemoryDir, getSessionMemoryDir, getMemoryRoot } from \"./paths\"\nimport { existsSync, readFileSync, readdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const MemoryInjectionPlugin: Plugin = async ({ directory }) => {\n const config = loadConfig(directory)\n const memoryCache = new Map<string, Record<string, string>>()\n\n function getLatestSessionId(): string | null {\n const sessionsDir = join(getMemoryRoot(directory), \"sessions\")\n if (!existsSync(sessionsDir)) return null\n \n const sessions = readdirSync(sessionsDir, { withFileTypes: true })\n .filter(d => d.isDirectory())\n .map(d => d.name)\n \n if (sessions.length === 0) return null\n \n // 返回最新的会话(按目录修改时间)\n let latestSession = sessions[0]\n let latestTime = 0\n \n for (const session of sessions) {\n const sessionPath = join(sessionsDir, session)\n const stat = require(\"fs\").statSync(sessionPath)\n if (stat.mtimeMs > latestTime) {\n latestTime = stat.mtimeMs\n latestSession = session\n }\n }\n \n return latestSession\n }\n\n function loadMemoryFiles(sessionId?: string) {\n const projectDir = getProjectMemoryDir(directory)\n const globalDir = getGlobalMemoryDir(directory)\n const memoryRoot = getMemoryRoot(directory)\n\n const memories: Record<string, string> = {}\n\n // 项目级记忆\n const files = [\n { key: \"memory\", path: join(projectDir, \"MEMORY.md\") },\n { key: \"notes\", path: join(projectDir, \"notes.md\") },\n { key: \"progress\", path: join(projectDir, \"tasks\", \"progress.md\") },\n { key: \"global_memory\", path: join(globalDir, \"MEMORY.md\") },\n ]\n\n for (const file of files) {\n if (existsSync(file.path)) {\n memories[file.key] = readFileSync(file.path, \"utf-8\")\n }\n }\n\n // 会话级 checkpoint(优先)\n if (sessionId) {\n const sessionCheckpoint = join(memoryRoot, \"sessions\", sessionId, \"checkpoint.md\")\n if (existsSync(sessionCheckpoint)) {\n memories.checkpoint = readFileSync(sessionCheckpoint, \"utf-8\")\n }\n }\n\n // 项目级 checkpoint(备选)\n if (!memories.checkpoint) {\n const projectCheckpoint = join(projectDir, \"checkpoint.md\")\n if (existsSync(projectCheckpoint)) {\n memories.checkpoint = readFileSync(projectCheckpoint, \"utf-8\")\n }\n }\n\n return memories\n }\n\n function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n }\n\n function smartTruncate(text: string, maxTokens: number): string {\n const estimatedTokens = estimateTokens(text)\n if (estimatedTokens <= maxTokens) return text\n\n const keepChars = maxTokens * 4 * 0.3\n const start = text.substring(0, keepChars)\n const end = text.substring(text.length - keepChars)\n\n return `${start}\\n\\n... [记忆已压缩,原 ${estimatedTokens} tokens] ...\\n\\n${end}`\n }\n\n function formatMemory(memories: Record<string, string>, budget: Record<string, number>): string {\n const sections = []\n\n if (memories.checkpoint && budget.checkpoint > 0) {\n sections.push(`## 检查点状态\\n${smartTruncate(memories.checkpoint, budget.checkpoint)}`)\n }\n if (memories.memory && budget.memory > 0) {\n sections.push(`## 项目记忆\\n${smartTruncate(memories.memory, budget.memory)}`)\n }\n if (memories.global_memory && budget.memory > 0) {\n sections.push(`## 全局记忆\\n${smartTruncate(memories.global_memory, budget.memory * 0.5)}`)\n }\n if (memories.notes && budget.notes > 0) {\n sections.push(`## 当前笔记\\n${smartTruncate(memories.notes, budget.notes)}`)\n }\n if (memories.progress && budget.progress > 0) {\n sections.push(`## 任务进度\\n${smartTruncate(memories.progress, budget.progress)}`)\n }\n\n return sections.join(\"\\n\\n\")\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 获取最新的会话 ID\n const latestSessionId = getLatestSessionId()\n const memories = loadMemoryFiles(latestSessionId)\n memoryCache.set(event.properties.sessionID, memories)\n \n // 记录注入状态\n const memoryKeys = Object.keys(memories)\n const totalTokens = Object.values(memories).reduce((sum, content) => sum + estimateTokens(content), 0)\n console.log(`[memory-core] Loaded ${memoryKeys.length} memory files (${totalTokens} tokens) for session ${event.properties.sessionID}`)\n }\n },\n\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) {\n console.log(`[memory-core] No memories found for session ${input.sessionID}`)\n return\n }\n\n const totalBudget = config.memory.injection.total_budget\n const allocation = config.memory.injection.allocation\n\n const budget = {\n checkpoint: Math.floor(totalBudget * allocation.checkpoint),\n memory: Math.floor(totalBudget * allocation.memory),\n notes: Math.floor(totalBudget * allocation.notes),\n progress: Math.floor(totalBudget * allocation.progress),\n }\n\n const memoryContext = formatMemory(memories, budget)\n\n if (memoryContext) {\n const injectedTokens = estimateTokens(memoryContext)\n console.log(`[memory-core] Injecting ${injectedTokens} tokens (budget: ${totalBudget}) into system prompt`)\n output.system.push(`\\n\\n# Injected Memory Context\\n${memoryContext}`)\n }\n },\n\n \"experimental.session.compacting\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\n\n const criticalMemory = []\n if (memories.checkpoint) {\n criticalMemory.push(`当前检查点: ${memories.checkpoint.substring(0, 500)}`)\n }\n if (memories.progress) {\n criticalMemory.push(`任务进度摘要: ${memories.progress.substring(0, 300)}`)\n }\n\n output.context.push(`## 保留的关键记忆\\n${criticalMemory.join(\"\\n\\n\")}`)\n },\n }\n}\n","import type { Plugin } from \"@opencode-ai/plugin\"\nimport { loadConfig } from \"./config\"\nimport { getProjectMemoryDir } from \"./paths\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\"\nimport { join } from \"path\"\n\nexport const DreamPlugin: Plugin = async ({ client, directory }) => {\n const config = loadConfig(directory)\n const memoryDir = getProjectMemoryDir(directory)\n mkdirSync(memoryDir, { recursive: true })\n\n function getLastTimestamp(metaFile: string): number {\n const metaPath = join(memoryDir, metaFile)\n if (existsSync(metaPath)) {\n const meta = JSON.parse(readFileSync(metaPath, \"utf-8\"))\n return meta.timestamp ?? 0\n }\n return 0\n }\n\n function setLastTimestamp(metaFile: string) {\n const metaPath = join(memoryDir, metaFile)\n writeFileSync(metaPath, JSON.stringify({ timestamp: Date.now() }))\n }\n\n function shouldAutoRun(metaFile: string, intervalDays: number): boolean {\n const lastRun = getLastTimestamp(metaFile)\n const intervalMs = intervalDays * 24 * 60 * 60 * 1000\n return Date.now() - lastRun > intervalMs\n }\n\n return {\n event: async ({ event }) => {\n if (event.type === \"session.created\") {\n // 自动触发 dream\n if (config.memory.dream.auto && shouldAutoRun(\".dream-meta.json\", config.memory.dream.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"dream\",\n parts: [{\n type: \"text\",\n text: \"Run automatic dream memory consolidation pass.\"\n }],\n },\n })\n setLastTimestamp(\".dream-meta.json\")\n }\n\n // 自动触发 distill\n if (config.memory.distill.auto && shouldAutoRun(\".distill-meta.json\", config.memory.distill.interval_days)) {\n await client.session.prompt({\n path: { id: event.properties.sessionID },\n body: {\n agent: \"distill\",\n parts: [{\n type: \"text\",\n text: \"Run automatic distill pass.\"\n }],\n },\n })\n setLastTimestamp(\".distill-meta.json\")\n }\n }\n },\n }\n}\n"],"mappings":"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","names":["mkdirSync","join","readFileSync","mkdirSync","join","join","mkdirSync","join","existsSync","readFileSync","readdirSync","join","existsSync","readFileSync","writeFileSync","mkdirSync","join","mkdirSync","join"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@super-pocock-ai/memory-core",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "持久化记忆系统,基于 SQLite FTS5 和 BM25
|
|
3
|
+
"version": "2.0.23",
|
|
4
|
+
"description": "持久化记忆系统,基于 SQLite FTS5 和 BM25 搜索(使用 bun:sqlite)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@opencode-ai/plugin": "latest",
|
|
26
|
-
"better-sqlite3": "^11.0.0",
|
|
27
26
|
"zod": "^3.23.0"
|
|
28
27
|
},
|
|
29
28
|
"devDependencies": {
|