@super-pocock-ai/memory-core 2.0.25 → 2.0.26
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 +20 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -290,24 +290,25 @@ function ensureConfig(projectRoot) {
|
|
|
290
290
|
// src/paths.ts
|
|
291
291
|
var import_crypto = require("crypto");
|
|
292
292
|
var import_path3 = require("path");
|
|
293
|
+
var import_os = require("os");
|
|
293
294
|
function resolveProjectId(absRepoPath) {
|
|
294
295
|
return (0, import_crypto.createHash)("sha256").update(absRepoPath).digest("hex").slice(0, 12);
|
|
295
296
|
}
|
|
296
|
-
function getMemoryRoot(
|
|
297
|
-
return (0, import_path3.join)(
|
|
297
|
+
function getMemoryRoot(_projectRoot) {
|
|
298
|
+
return (0, import_path3.join)((0, import_os.homedir)(), ".local", "share", "super-pocock", "memory");
|
|
298
299
|
}
|
|
299
300
|
function getProjectMemoryDir(projectRoot) {
|
|
300
301
|
const projectId = resolveProjectId(projectRoot);
|
|
301
|
-
return (0, import_path3.join)(getMemoryRoot(
|
|
302
|
+
return (0, import_path3.join)(getMemoryRoot(), "projects", projectId);
|
|
302
303
|
}
|
|
303
|
-
function getGlobalMemoryDir(
|
|
304
|
-
return (0, import_path3.join)(getMemoryRoot(
|
|
304
|
+
function getGlobalMemoryDir() {
|
|
305
|
+
return (0, import_path3.join)(getMemoryRoot(), "global");
|
|
305
306
|
}
|
|
306
307
|
function getSessionMemoryDir(projectRoot, sessionId) {
|
|
307
|
-
return (0, import_path3.join)(getMemoryRoot(
|
|
308
|
+
return (0, import_path3.join)(getMemoryRoot(), "sessions", sessionId);
|
|
308
309
|
}
|
|
309
|
-
function getDbPath(
|
|
310
|
-
return (0, import_path3.join)(getMemoryRoot(
|
|
310
|
+
function getDbPath() {
|
|
311
|
+
return (0, import_path3.join)(getMemoryRoot(), "memory.db");
|
|
311
312
|
}
|
|
312
313
|
|
|
313
314
|
// src/checkpoint-plugin.ts
|
|
@@ -315,7 +316,7 @@ var import_fs4 = require("fs");
|
|
|
315
316
|
var import_path4 = require("path");
|
|
316
317
|
var CheckpointPlugin = async ({ client, directory }) => {
|
|
317
318
|
const config = loadConfig(directory);
|
|
318
|
-
const memoryRoot = getMemoryRoot(
|
|
319
|
+
const memoryRoot = getMemoryRoot();
|
|
319
320
|
const projectDir = getProjectMemoryDir(directory);
|
|
320
321
|
(0, import_fs4.mkdirSync)(memoryRoot, { recursive: true });
|
|
321
322
|
(0, import_fs4.mkdirSync)((0, import_path4.join)(memoryRoot, "sessions"), { recursive: true });
|
|
@@ -417,7 +418,7 @@ var MemoryInjectionPlugin = async ({ directory }) => {
|
|
|
417
418
|
const config = loadConfig(directory);
|
|
418
419
|
const memoryCache = /* @__PURE__ */ new Map();
|
|
419
420
|
function getLatestSessionId() {
|
|
420
|
-
const sessionsDir = (0, import_path5.join)(getMemoryRoot(
|
|
421
|
+
const sessionsDir = (0, import_path5.join)(getMemoryRoot(), "sessions");
|
|
421
422
|
if (!(0, import_fs5.existsSync)(sessionsDir)) return null;
|
|
422
423
|
const sessions = (0, import_fs5.readdirSync)(sessionsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
423
424
|
if (sessions.length === 0) return null;
|
|
@@ -435,8 +436,8 @@ var MemoryInjectionPlugin = async ({ directory }) => {
|
|
|
435
436
|
}
|
|
436
437
|
function loadMemoryFiles(sessionId) {
|
|
437
438
|
const projectDir = getProjectMemoryDir(directory);
|
|
438
|
-
const globalDir = getGlobalMemoryDir(
|
|
439
|
-
const memoryRoot = getMemoryRoot(
|
|
439
|
+
const globalDir = getGlobalMemoryDir();
|
|
440
|
+
const memoryRoot = getMemoryRoot();
|
|
440
441
|
const memories = {};
|
|
441
442
|
const files = [
|
|
442
443
|
{ key: "memory", path: (0, import_path5.join)(projectDir, "MEMORY.md") },
|
|
@@ -606,15 +607,17 @@ var DreamPlugin = async ({ client, directory }) => {
|
|
|
606
607
|
// src/index.ts
|
|
607
608
|
var MemoryCorePlugin = async (ctx) => {
|
|
608
609
|
ensureConfig(ctx.directory);
|
|
609
|
-
const memoryRoot = getMemoryRoot(
|
|
610
|
+
const memoryRoot = getMemoryRoot();
|
|
610
611
|
const projectDir = getProjectMemoryDir(ctx.directory);
|
|
611
|
-
const globalDir = getGlobalMemoryDir(
|
|
612
|
+
const globalDir = getGlobalMemoryDir();
|
|
612
613
|
(0, import_fs7.mkdirSync)((0, import_path7.join)(memoryRoot, "global"), { recursive: true });
|
|
613
|
-
(0, import_fs7.mkdirSync)((0, import_path7.join)(
|
|
614
|
-
(0, import_fs7.mkdirSync)((0, import_path7.join)(
|
|
614
|
+
(0, import_fs7.mkdirSync)((0, import_path7.join)(memoryRoot, "projects"), { recursive: true });
|
|
615
|
+
(0, import_fs7.mkdirSync)((0, import_path7.join)(memoryRoot, "sessions"), { recursive: true });
|
|
616
|
+
(0, import_fs7.mkdirSync)(projectDir, { recursive: true });
|
|
615
617
|
const memoryTool = createMemoryTool({
|
|
616
618
|
memoryDir: memoryRoot,
|
|
617
|
-
dbPath: getDbPath(
|
|
619
|
+
dbPath: getDbPath(),
|
|
620
|
+
projectDir: ctx.directory
|
|
618
621
|
});
|
|
619
622
|
const checkpointPlugin = await CheckpointPlugin(ctx);
|
|
620
623
|
const injectionPlugin = await MemoryInjectionPlugin(ctx);
|
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 async 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 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 \n const stmt = this.db.prepare(sql)\n return stmt.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\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\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 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"]}
|
|
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()\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir()\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(memoryRoot, \"projects\"), { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(),\n projectDir: 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 async 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 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 \n const stmt = this.db.prepare(sql)\n return stmt.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\"\nimport { homedir } from \"os\"\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\n/**\n * 获取记忆系统根目录(全局目录)\n * 路径: ~/.local/share/super-pocock/memory/\n * 所有项目共享同一个记忆数据库,通过 project_id 区分\n */\nexport function getMemoryRoot(_projectRoot?: string): string {\n return join(homedir(), \".local\", \"share\", \"super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(): string {\n return join(getMemoryRoot(), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(), \"sessions\", sessionId)\n}\n\nexport function getDbPath(): string {\n return join(getMemoryRoot(), \"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()\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(), \"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()\n const memoryRoot = getMemoryRoot()\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\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\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 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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,IAAAA,aAA0B;AAC1B,IAAAC,eAAqB;;;ACFrB,oBAAqB;AACrB,iBAAkB;;;ACDlB,wBAAyB;AAkBlB,IAAM,cAAN,MAAkB;AAAA,EAChB;AAAA,EAEP,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAI,2BAAS,MAAM;AAC7B,SAAK,GAAG,KAAK,2BAA2B;AACxC,SAAK,KAAK;AAAA,EACZ;AAAA,EAEQ,OAAO;AACb,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUZ;AACD,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA,KAGZ;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,KAA4B;AAChD,UAAM,SACJ,IACG,MAAM,kBAAkB,GACvB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACpB,OAAO,OAAO,KAAK,CAAC;AACzB,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,UAAM,SAAS,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,WAAW,KAAK,EAAE,CAAC,GAAG;AAC7D,WAAO,OAAO,KAAK,MAAM;AAAA,EAC3B;AAAA,EAEA,OAAO,OAAe,UAAyB,CAAC,GAAmB;AACjE,QAAI;AACJ,QAAI,UAAU,KAAK;AACjB,iBAAW;AAAA,IACb,OAAO;AACL,YAAM,QAAQ,KAAK,cAAc,KAAK;AACtC,UAAI,CAAC,MAAO,QAAO,CAAC;AACpB,iBAAW;AAAA,IACb;AAEA,UAAM,QAAQ,QAAQ,SAAS;AAE/B,QAAI,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQV,UAAM,SAAoB,CAAC,QAAQ;AACnC,QAAI,QAAQ,OAAO;AAAE,aAAO;AAAoB,aAAO,KAAK,QAAQ,KAAK;AAAA,IAAE;AAC3E,QAAI,QAAQ,UAAU;AAAE,aAAO;AAAuB,aAAO,KAAK,QAAQ,QAAQ;AAAA,IAAE;AACpF,QAAI,QAAQ,MAAM;AAAE,aAAO;AAAmB,aAAO,KAAK,QAAQ,IAAI;AAAA,IAAE;AACxE,WAAO;AACP,WAAO,KAAK,KAAK;AAEjB,UAAM,OAAO,KAAK,GAAG,QAAQ,GAAG;AAChC,WAAO,KAAK,IAAI,GAAG,MAAM;AAAA,EAC3B;AAAA,EAEA,MAAM,MAAc,OAAe,UAAkB,MAAc,SAAiB;AAClF,UAAM,cAAc,GAAG,QAAQ,MAAM,IAAI,KAAK,IAAI,CAAC;AACnD,UAAM,MAAM,KAAK,IAAI;AAErB,SAAK,GAAG,MAAM;AAAA;AAAA;AAAA,KAGb,EAAE,IAAI,MAAM,OAAO,UAAU,MAAM,aAAa,GAAG;AAEpD,SAAK,GAAG,MAAM,uCAAuC,EAAE,IAAI,IAAI;AAC/D,SAAK,GAAG,MAAM,mDAAmD,EAAE,IAAI,MAAM,OAAO;AAAA,EACtF;AAAA,EAEA,OAAO,UAAkB;AACvB,SAAK,GAAG,MAAM,yCAAyC,EAAE,IAAI,QAAQ;AACrE,SAAK,GAAG,MAAM,uCAAuC,EAAE,IAAI,QAAQ;AAAA,EACrE;AAAA,EAEA,QAAQ;AACN,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;;;AChHA,gBAA0C;AAC1C,kBAAoC;AAGpC,SAAS,gBAAgB,YAAoB,UAAuD;AAClG,QAAM,UAAM,sBAAS,YAAY,QAAQ,EAAE,MAAM,eAAG;AACpD,MAAI,IAAI,CAAC,MAAM,SAAU,QAAO,EAAE,OAAO,UAAU,UAAU,GAAG;AAChE,MAAI,IAAI,CAAC,MAAM,cAAc,IAAI,UAAU,EAAG,QAAO,EAAE,OAAO,YAAY,UAAU,IAAI,CAAC,EAAE;AAC3F,MAAI,IAAI,CAAC,MAAM,cAAc,IAAI,UAAU,EAAG,QAAO,EAAE,OAAO,YAAY,UAAU,IAAI,CAAC,EAAE;AAC3F,SAAO,EAAE,OAAO,WAAW,UAAU,GAAG;AAC1C;AAEA,SAAS,YAAY,KAAuB;AAC1C,QAAM,UAAoB,CAAC;AAC3B,aAAW,aAAS,uBAAY,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAC7D,UAAM,WAAO,kBAAK,KAAK,MAAM,IAAI;AACjC,QAAI,MAAM,YAAY,GAAG;AACvB,cAAQ,KAAK,GAAG,YAAY,IAAI,CAAC;AAAA,IACnC,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;AACrC,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,mBAAmB,OAAoB,YAAoB;AACzE,QAAM,cAAc,YAAY,UAAU;AAC1C,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,QAAQ,aAAa;AAC9B,cAAU,IAAI,IAAI;AAClB,UAAM,cAAU,wBAAa,MAAM,OAAO;AAC1C,UAAM,EAAE,OAAO,SAAS,IAAI,gBAAgB,YAAY,IAAI;AAC5D,UAAM,MAAM,MAAM,OAAO,UAAU,YAAY,OAAO;AAAA,EACxD;AAEA,QAAM,UAAU,MAAM,GAAG,QAAQ,+BAA+B,EAAE,IAAI;AACtE,aAAW,OAAO,SAAS;AACzB,QAAI,CAAC,UAAU,IAAI,IAAI,IAAI,GAAG;AAC5B,YAAM,OAAO,IAAI,IAAI;AAAA,IACvB;AAAA,EACF;AACF;;;AFtCA,IAAAC,aAA0B;AAEnB,SAAS,iBAAiB,KAA4C;AAC3E,MAAI,QAA4B;AAEhC,WAAS,cAAc;AACrB,QAAI,CAAC,OAAO;AACV,gCAAU,IAAI,WAAW,EAAE,WAAW,KAAK,CAAC;AAC5C,cAAQ,IAAI,YAAY,IAAI,MAAM;AAClC,yBAAmB,OAAO,IAAI,SAAS;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AAEA,aAAO,oBAAK;AAAA,IACV,aAAa;AAAA,IACb,MAAM;AAAA,MACJ,WAAW,aAAE,KAAK,CAAC,UAAU,SAAS,QAAQ,QAAQ,CAAC;AAAA,MACvD,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,UAAU,aAAE,OAAO,EAAE,SAAS;AAAA,MAC9B,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,MAC1B,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,IACjC;AAAA,IACA,MAAM,QAAQ,MAAW;AACvB,YAAM,IAAI,YAAY;AAEtB,UAAI,KAAK,cAAc,UAAU;AAC/B,YAAI,CAAC,KAAK,MAAO,QAAO;AACxB,cAAM,UAAU,EAAE,OAAO,KAAK,OAAO;AAAA,UACnC,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,MAAM,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,QACd,CAAC;AACD,YAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,eAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,MACxC;AAEA,UAAI,KAAK,cAAc,SAAS;AAC9B,YAAI,CAAC,KAAK,KAAM,QAAO;AACvB,YAAI,CAAC,KAAK,QAAS,QAAO;AAC1B,UAAE;AAAA,UACA,KAAK;AAAA,UACL,KAAK,SAAS;AAAA,UACd,KAAK,YAAY;AAAA,UACjB,KAAK,QAAQ;AAAA,UACb,KAAK;AAAA,QACP;AACA,eAAO,YAAY,KAAK,IAAI;AAAA,MAC9B;AAEA,UAAI,KAAK,cAAc,QAAQ;AAC7B,cAAM,UAAU,EAAE,OAAO,KAAK;AAAA,UAC5B,OAAO,KAAK;AAAA,UACZ,UAAU,KAAK;AAAA,UACf,MAAM,KAAK;AAAA,UACX,OAAO,KAAK,SAAS;AAAA,QACvB,CAAC;AACD,eAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,MACxC;AAEA,UAAI,KAAK,cAAc,UAAU;AAC/B,YAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,UAAE,OAAO,KAAK,SAAS;AACvB,eAAO,UAAU,KAAK,SAAS;AAAA,MACjC;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;;;AG9EA,IAAAC,aAAmE;AACnE,IAAAC,eAA8B;AA8BvB,IAAM,iBAA+B;AAAA,EAC1C,QAAQ;AAAA,IACN,WAAW;AAAA,MACT,cAAc;AAAA,MACd,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,YAAY,CAAC,OAAO,OAAO,OAAO,KAAK;AAAA,MACvC,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,IACnB;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,eAAe;AAAA,IACjB;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,eAAe;AAAA,IACjB;AAAA,EACF;AACF;AAEO,SAAS,cAAc,aAA6B;AACzD,aAAO,mBAAK,aAAa,iBAAiB,aAAa;AACzD;AAEO,SAAS,WAAW,aAAmC;AAC5D,QAAM,aAAa,cAAc,WAAW;AAC5C,UAAI,uBAAW,UAAU,GAAG;AAC1B,UAAM,cAAU,yBAAa,YAAY,OAAO;AAChD,WAAO,EAAE,GAAG,gBAAgB,GAAG,KAAK,MAAM,OAAO,EAAE;AAAA,EACrD;AACA,SAAO;AACT;AAEO,SAAS,aAAa,aAA2B;AACtD,QAAM,aAAa,cAAc,WAAW;AAC5C,MAAI,KAAC,uBAAW,UAAU,GAAG;AAC3B,kCAAU,sBAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,kCAAc,YAAY,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAAC;AAAA,EACnE;AACF;;;AC9EA,oBAA2B;AAC3B,IAAAC,eAAqB;AACrB,gBAAwB;AAIjB,SAAS,iBAAiB,aAA6B;AAC5D,aAAO,0BAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC3E;AAOO,SAAS,cAAc,cAA+B;AAC3D,aAAO,uBAAK,mBAAQ,GAAG,UAAU,SAAS,gBAAgB,QAAQ;AACpE;AAEO,SAAS,oBAAoB,aAA6B;AAC/D,QAAM,YAAY,iBAAiB,WAAW;AAC9C,aAAO,mBAAK,cAAc,GAAG,YAAY,SAAS;AACpD;AAEO,SAAS,qBAA6B;AAC3C,aAAO,mBAAK,cAAc,GAAG,QAAQ;AACvC;AAEO,SAAS,oBAAoB,aAAqB,WAA2B;AAClF,aAAO,mBAAK,cAAc,GAAG,YAAY,SAAS;AACpD;AAEO,SAAS,YAAoB;AAClC,aAAO,mBAAK,cAAc,GAAG,WAAW;AAC1C;;;AC/BA,IAAAC,aAA0B;AAC1B,IAAAC,eAAqB;AAEd,IAAM,mBAA2B,OAAO,EAAE,QAAQ,UAAU,MAAM;AACvE,QAAM,SAAS,WAAW,SAAS;AACnC,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,oBAAoB,SAAS;AAGhD,4BAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACzC,gCAAU,mBAAK,YAAY,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3D,4BAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAEzC,MAAI,sBAAsB;AAC1B,QAAM,aAAa,OAAO,OAAO,WAAW,WAAW,IAAI,OAAK,WAAW,CAAC,IAAI,GAAG;AACnF,MAAI,mBAAkC;AAEtC,SAAO;AAAA,IACL,OAAO,OAAO,EAAE,MAAM,MAAM;AAE1B,UAAI,MAAM,SAAS,mBAAmB;AACpC,cAAM,eAAe,MAAM,YAAY,MAAM;AAG7C,YAAI,oBAAoB,qBAAqB,cAAc;AACzD,gBAAM,kBAAkB,QAAQ,kBAAkB,WAAW,qBAAqB;AAAA,QACpF;AAEA,2BAAmB,gBAAgB;AAAA,MACrC;AAGA,UAAI,MAAM,SAAS,2BAA2B;AAC5C,cAAM,QAAQ,MAAM,WAAW,SAAS,MAAM,WAAW;AACzD,cAAM,gBAAgB,WAAW,KAAK,OAAK,IAAI,mBAAmB;AAClE,YAAI,iBAAiB,SAAS,eAAe;AAC3C,gCAAsB;AACtB,gBAAM,kBAAkB,QAAQ,MAAM,WAAW,WAAW,WAAW,eAAe,KAAK,MAAM,QAAQ,GAAG,CAAC,GAAG;AAAA,QAClH;AAAA,MACF;AAGA,UAAI,MAAM,SAAS,oBAAoB,MAAM,YAAY,QAAQ,SAAS,QAAQ;AAChF,mBAAW,YAAY;AACrB,gBAAM,kBAAkB,QAAQ,MAAM,WAAW,WAAW,WAAW,cAAc;AAAA,QACvF,GAAG,OAAO,OAAO,WAAW,eAAe;AAAA,MAC7C;AAGA,UAAI,MAAM,SAAS,gBAAgB;AACjC,cAAM,kBAAkB,QAAQ,MAAM,WAAW,WAAW,WAAW,cAAc;AAAA,MACvF;AAGA,UAAI,MAAM,SAAS,mBAAmB;AACpC,cAAM,kBAAkB,QAAQ,MAAM,WAAW,KAAK,IAAI,WAAW,iBAAiB;AAAA,MACxF;AAGA,UAAI,MAAM,SAAS,4BAA4B;AAC7C,YAAI,kBAAkB;AACpB,gBAAM,kBAAkB,QAAQ,kBAAkB,WAAW,UAAU;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,mCAAmC,OAAO,OAAO,WAAW;AAC1D,aAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAcnB;AAAA,IACH;AAAA,EACF;AACF;AAEA,eAAe,kBAAkB,QAAa,WAAmB,WAAmB,QAAiB;AACnG,QAAM,WAAW,MAAM,OAAO,QAAQ,SAAS,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;AAC1E,QAAM,UAAU,2BAA2B,QAAQ;AAGnD,QAAM,aAAa,oBAAoB,WAAW,SAAS;AAC3D,4BAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAGzC,QAAM,OAAO,IAAI,IAAI;AAAA,IACnB,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS,yBAAyB,UAAU,SAAS,cAAc,SAAS;AAAA,IAC9E;AAAA,EACF,CAAC;AAGD,SAAO,QAAQ,OAAO;AAAA,IACpB,MAAM,EAAE,IAAI,UAAU;AAAA,IACtB,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,CAAC;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,EAA0C,OAAO;AAAA;AAAA;AAAA,2CAAsE,SAAS;AAAA;AAAA,MACxI,CAAC;AAAA,IACH;AAAA,EACF,CAAC,EAAE,MAAM,CAAC,QAAa;AAErB,YAAQ,MAAM,sBAAsB,GAAG;AAAA,EACzC,CAAC;AACH;AAEA,SAAS,2BAA2B,UAAyB;AAC3D,SAAO,SAAS,IAAI,OAAK,IAAI,EAAE,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI;AACjE;;;ACzHA,IAAAC,aAAsD;AACtD,IAAAC,eAAqB;AAEd,IAAM,wBAAgC,OAAO,EAAE,UAAU,MAAM;AACpE,QAAM,SAAS,WAAW,SAAS;AACnC,QAAM,cAAc,oBAAI,IAAoC;AAE5D,WAAS,qBAAoC;AAC3C,UAAM,kBAAc,mBAAK,cAAc,GAAG,UAAU;AACpD,QAAI,KAAC,uBAAW,WAAW,EAAG,QAAO;AAErC,UAAM,eAAW,wBAAY,aAAa,EAAE,eAAe,KAAK,CAAC,EAC9D,OAAO,OAAK,EAAE,YAAY,CAAC,EAC3B,IAAI,OAAK,EAAE,IAAI;AAElB,QAAI,SAAS,WAAW,EAAG,QAAO;AAGlC,QAAI,gBAAgB,SAAS,CAAC;AAC9B,QAAI,aAAa;AAEjB,eAAW,WAAW,UAAU;AAC9B,YAAM,kBAAc,mBAAK,aAAa,OAAO;AAC7C,YAAM,OAAO,QAAQ,IAAI,EAAE,SAAS,WAAW;AAC/C,UAAI,KAAK,UAAU,YAAY;AAC7B,qBAAa,KAAK;AAClB,wBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,gBAAgB,WAAoB;AAC3C,UAAM,aAAa,oBAAoB,SAAS;AAChD,UAAM,YAAY,mBAAmB;AACrC,UAAM,aAAa,cAAc;AAEjC,UAAM,WAAmC,CAAC;AAG1C,UAAM,QAAQ;AAAA,MACZ,EAAE,KAAK,UAAU,UAAM,mBAAK,YAAY,WAAW,EAAE;AAAA,MACrD,EAAE,KAAK,SAAS,UAAM,mBAAK,YAAY,UAAU,EAAE;AAAA,MACnD,EAAE,KAAK,YAAY,UAAM,mBAAK,YAAY,SAAS,aAAa,EAAE;AAAA,MAClE,EAAE,KAAK,iBAAiB,UAAM,mBAAK,WAAW,WAAW,EAAE;AAAA,IAC7D;AAEA,eAAW,QAAQ,OAAO;AACxB,cAAI,uBAAW,KAAK,IAAI,GAAG;AACzB,iBAAS,KAAK,GAAG,QAAI,yBAAa,KAAK,MAAM,OAAO;AAAA,MACtD;AAAA,IACF;AAGA,QAAI,WAAW;AACb,YAAM,wBAAoB,mBAAK,YAAY,YAAY,WAAW,eAAe;AACjF,cAAI,uBAAW,iBAAiB,GAAG;AACjC,iBAAS,iBAAa,yBAAa,mBAAmB,OAAO;AAAA,MAC/D;AAAA,IACF;AAGA,QAAI,CAAC,SAAS,YAAY;AACxB,YAAM,wBAAoB,mBAAK,YAAY,eAAe;AAC1D,cAAI,uBAAW,iBAAiB,GAAG;AACjC,iBAAS,iBAAa,yBAAa,mBAAmB,OAAO;AAAA,MAC/D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,MAAsB;AAC5C,WAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AAAA,EAClC;AAEA,WAAS,cAAc,MAAc,WAA2B;AAC9D,UAAM,kBAAkB,eAAe,IAAI;AAC3C,QAAI,mBAAmB,UAAW,QAAO;AAEzC,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,QAAQ,KAAK,UAAU,GAAG,SAAS;AACzC,UAAM,MAAM,KAAK,UAAU,KAAK,SAAS,SAAS;AAElD,WAAO,GAAG,KAAK;AAAA;AAAA,kDAAoB,eAAe;AAAA;AAAA,EAAmB,GAAG;AAAA,EAC1E;AAEA,WAAS,aAAa,UAAkC,QAAwC;AAC9F,UAAM,WAAW,CAAC;AAElB,QAAI,SAAS,cAAc,OAAO,aAAa,GAAG;AAChD,eAAS,KAAK;AAAA,EAAa,cAAc,SAAS,YAAY,OAAO,UAAU,CAAC,EAAE;AAAA,IACpF;AACA,QAAI,SAAS,UAAU,OAAO,SAAS,GAAG;AACxC,eAAS,KAAK;AAAA,EAAY,cAAc,SAAS,QAAQ,OAAO,MAAM,CAAC,EAAE;AAAA,IAC3E;AACA,QAAI,SAAS,iBAAiB,OAAO,SAAS,GAAG;AAC/C,eAAS,KAAK;AAAA,EAAY,cAAc,SAAS,eAAe,OAAO,SAAS,GAAG,CAAC,EAAE;AAAA,IACxF;AACA,QAAI,SAAS,SAAS,OAAO,QAAQ,GAAG;AACtC,eAAS,KAAK;AAAA,EAAY,cAAc,SAAS,OAAO,OAAO,KAAK,CAAC,EAAE;AAAA,IACzE;AACA,QAAI,SAAS,YAAY,OAAO,WAAW,GAAG;AAC5C,eAAS,KAAK;AAAA,EAAY,cAAc,SAAS,UAAU,OAAO,QAAQ,CAAC,EAAE;AAAA,IAC/E;AAEA,WAAO,SAAS,KAAK,MAAM;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,EAAE,MAAM,MAAM;AAC1B,UAAI,MAAM,SAAS,mBAAmB;AAEpC,cAAM,kBAAkB,mBAAmB;AAC3C,cAAM,WAAW,gBAAgB,eAAe;AAChD,oBAAY,IAAI,MAAM,WAAW,WAAW,QAAQ;AAAA,MACtD;AAAA,IACF;AAAA,IAEA,sCAAsC,OAAO,OAAO,WAAW;AAC7D,YAAM,WAAW,YAAY,IAAI,MAAM,SAAS;AAChD,UAAI,CAAC,SAAU;AAEf,YAAM,cAAc,OAAO,OAAO,UAAU;AAC5C,YAAM,aAAa,OAAO,OAAO,UAAU;AAE3C,YAAM,SAAS;AAAA,QACb,YAAY,KAAK,MAAM,cAAc,WAAW,UAAU;AAAA,QAC1D,QAAQ,KAAK,MAAM,cAAc,WAAW,MAAM;AAAA,QAClD,OAAO,KAAK,MAAM,cAAc,WAAW,KAAK;AAAA,QAChD,UAAU,KAAK,MAAM,cAAc,WAAW,QAAQ;AAAA,MACxD;AAEA,YAAM,gBAAgB,aAAa,UAAU,MAAM;AAEnD,UAAI,eAAe;AACjB,eAAO,OAAO,KAAK;AAAA;AAAA;AAAA,EAAkC,aAAa,EAAE;AAAA,MACtE;AAAA,IACF;AAAA,IAEA,mCAAmC,OAAO,OAAO,WAAW;AAC1D,YAAM,WAAW,YAAY,IAAI,MAAM,SAAS;AAChD,UAAI,CAAC,SAAU;AAEf,YAAM,iBAAiB,CAAC;AACxB,UAAI,SAAS,YAAY;AACvB,uBAAe,KAAK,mCAAU,SAAS,WAAW,UAAU,GAAG,GAAG,CAAC,EAAE;AAAA,MACvE;AACA,UAAI,SAAS,UAAU;AACrB,uBAAe,KAAK,yCAAW,SAAS,SAAS,UAAU,GAAG,GAAG,CAAC,EAAE;AAAA,MACtE;AAEA,aAAO,QAAQ,KAAK;AAAA,EAAe,eAAe,KAAK,MAAM,CAAC,EAAE;AAAA,IAClE;AAAA,EACF;AACF;;;AC5JA,IAAAC,aAAmE;AACnE,IAAAC,eAAqB;AAEd,IAAM,cAAsB,OAAO,EAAE,QAAQ,UAAU,MAAM;AAClE,QAAM,SAAS,WAAW,SAAS;AACnC,QAAM,YAAY,oBAAoB,SAAS;AAC/C,4BAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAExC,WAAS,iBAAiB,UAA0B;AAClD,UAAM,eAAW,mBAAK,WAAW,QAAQ;AACzC,YAAI,uBAAW,QAAQ,GAAG;AACxB,YAAM,OAAO,KAAK,UAAM,yBAAa,UAAU,OAAO,CAAC;AACvD,aAAO,KAAK,aAAa;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAEA,WAAS,iBAAiB,UAAkB;AAC1C,UAAM,eAAW,mBAAK,WAAW,QAAQ;AACzC,kCAAc,UAAU,KAAK,UAAU,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC,CAAC;AAAA,EACnE;AAEA,WAAS,cAAc,UAAkB,cAA+B;AACtE,UAAM,UAAU,iBAAiB,QAAQ;AACzC,UAAM,aAAa,eAAe,KAAK,KAAK,KAAK;AACjD,WAAO,KAAK,IAAI,IAAI,UAAU;AAAA,EAChC;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,EAAE,MAAM,MAAM;AAC1B,UAAI,MAAM,SAAS,mBAAmB;AAEpC,YAAI,OAAO,OAAO,MAAM,QAAQ,cAAc,oBAAoB,OAAO,OAAO,MAAM,aAAa,GAAG;AACpG,gBAAM,OAAO,QAAQ,OAAO;AAAA,YAC1B,MAAM,EAAE,IAAI,MAAM,WAAW,UAAU;AAAA,YACvC,MAAM;AAAA,cACJ,OAAO;AAAA,cACP,OAAO,CAAC;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,cACR,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AACD,2BAAiB,kBAAkB;AAAA,QACrC;AAGA,YAAI,OAAO,OAAO,QAAQ,QAAQ,cAAc,sBAAsB,OAAO,OAAO,QAAQ,aAAa,GAAG;AAC1G,gBAAM,OAAO,QAAQ,OAAO;AAAA,YAC1B,MAAM,EAAE,IAAI,MAAM,WAAW,UAAU;AAAA,YACvC,MAAM;AAAA,cACJ,OAAO;AAAA,cACP,OAAO,CAAC;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM;AAAA,cACR,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AACD,2BAAiB,oBAAoB;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ARxDO,IAAM,mBAA2B,OAAO,QAAQ;AAErD,eAAa,IAAI,SAAS;AAE1B,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,oBAAoB,IAAI,SAAS;AACpD,QAAM,YAAY,mBAAmB;AAGrC,gCAAU,mBAAK,YAAY,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,gCAAU,mBAAK,YAAY,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3D,gCAAU,mBAAK,YAAY,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3D,4BAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAGzC,QAAM,aAAa,iBAAiB;AAAA,IAClC,WAAW;AAAA,IACX,QAAQ,UAAU;AAAA,IAClB,YAAY,IAAI;AAAA,EAClB,CAAC;AAGD,QAAM,mBAAmB,MAAM,iBAAiB,GAAG;AACnD,QAAM,kBAAkB,MAAM,sBAAsB,GAAG;AACvD,QAAM,cAAc,MAAM,YAAY,GAAG;AAEzC,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,QAAQ;AAAA,IACV;AAAA,IACA,OAAO,OAAO,UAAU;AACtB,YAAM,iBAAiB,QAAQ,KAAK;AACpC,YAAM,gBAAgB,QAAQ,KAAK;AACnC,YAAM,YAAY,QAAQ,KAAK;AAAA,IACjC;AAAA,IACA,sCAAsC,OAAO,OAAO,WAAW;AAC7D,YAAM,gBAAgB,oCAAoC,IAAI,OAAO,MAAM;AAAA,IAC7E;AAAA,IACA,mCAAmC,OAAO,OAAO,WAAW;AAC1D,YAAM,iBAAiB,iCAAiC,IAAI,OAAO,MAAM;AACzE,YAAM,gBAAgB,iCAAiC,IAAI,OAAO,MAAM;AAAA,IAC1E;AAAA,EACF;AACF;AAEA,IAAO,gBAAQ;","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
|
@@ -264,24 +264,25 @@ function ensureConfig(projectRoot) {
|
|
|
264
264
|
// src/paths.ts
|
|
265
265
|
import { createHash } from "crypto";
|
|
266
266
|
import { join as join3 } from "path";
|
|
267
|
+
import { homedir } from "os";
|
|
267
268
|
function resolveProjectId(absRepoPath) {
|
|
268
269
|
return createHash("sha256").update(absRepoPath).digest("hex").slice(0, 12);
|
|
269
270
|
}
|
|
270
|
-
function getMemoryRoot(
|
|
271
|
-
return join3(
|
|
271
|
+
function getMemoryRoot(_projectRoot) {
|
|
272
|
+
return join3(homedir(), ".local", "share", "super-pocock", "memory");
|
|
272
273
|
}
|
|
273
274
|
function getProjectMemoryDir(projectRoot) {
|
|
274
275
|
const projectId = resolveProjectId(projectRoot);
|
|
275
|
-
return join3(getMemoryRoot(
|
|
276
|
+
return join3(getMemoryRoot(), "projects", projectId);
|
|
276
277
|
}
|
|
277
|
-
function getGlobalMemoryDir(
|
|
278
|
-
return join3(getMemoryRoot(
|
|
278
|
+
function getGlobalMemoryDir() {
|
|
279
|
+
return join3(getMemoryRoot(), "global");
|
|
279
280
|
}
|
|
280
281
|
function getSessionMemoryDir(projectRoot, sessionId) {
|
|
281
|
-
return join3(getMemoryRoot(
|
|
282
|
+
return join3(getMemoryRoot(), "sessions", sessionId);
|
|
282
283
|
}
|
|
283
|
-
function getDbPath(
|
|
284
|
-
return join3(getMemoryRoot(
|
|
284
|
+
function getDbPath() {
|
|
285
|
+
return join3(getMemoryRoot(), "memory.db");
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
// src/checkpoint-plugin.ts
|
|
@@ -289,7 +290,7 @@ import { mkdirSync as mkdirSync3 } from "fs";
|
|
|
289
290
|
import { join as join4 } from "path";
|
|
290
291
|
var CheckpointPlugin = async ({ client, directory }) => {
|
|
291
292
|
const config = loadConfig(directory);
|
|
292
|
-
const memoryRoot = getMemoryRoot(
|
|
293
|
+
const memoryRoot = getMemoryRoot();
|
|
293
294
|
const projectDir = getProjectMemoryDir(directory);
|
|
294
295
|
mkdirSync3(memoryRoot, { recursive: true });
|
|
295
296
|
mkdirSync3(join4(memoryRoot, "sessions"), { recursive: true });
|
|
@@ -391,7 +392,7 @@ var MemoryInjectionPlugin = async ({ directory }) => {
|
|
|
391
392
|
const config = loadConfig(directory);
|
|
392
393
|
const memoryCache = /* @__PURE__ */ new Map();
|
|
393
394
|
function getLatestSessionId() {
|
|
394
|
-
const sessionsDir = join5(getMemoryRoot(
|
|
395
|
+
const sessionsDir = join5(getMemoryRoot(), "sessions");
|
|
395
396
|
if (!existsSync2(sessionsDir)) return null;
|
|
396
397
|
const sessions = readdirSync2(sessionsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
397
398
|
if (sessions.length === 0) return null;
|
|
@@ -409,8 +410,8 @@ var MemoryInjectionPlugin = async ({ directory }) => {
|
|
|
409
410
|
}
|
|
410
411
|
function loadMemoryFiles(sessionId) {
|
|
411
412
|
const projectDir = getProjectMemoryDir(directory);
|
|
412
|
-
const globalDir = getGlobalMemoryDir(
|
|
413
|
-
const memoryRoot = getMemoryRoot(
|
|
413
|
+
const globalDir = getGlobalMemoryDir();
|
|
414
|
+
const memoryRoot = getMemoryRoot();
|
|
414
415
|
const memories = {};
|
|
415
416
|
const files = [
|
|
416
417
|
{ key: "memory", path: join5(projectDir, "MEMORY.md") },
|
|
@@ -580,15 +581,17 @@ var DreamPlugin = async ({ client, directory }) => {
|
|
|
580
581
|
// src/index.ts
|
|
581
582
|
var MemoryCorePlugin = async (ctx) => {
|
|
582
583
|
ensureConfig(ctx.directory);
|
|
583
|
-
const memoryRoot = getMemoryRoot(
|
|
584
|
+
const memoryRoot = getMemoryRoot();
|
|
584
585
|
const projectDir = getProjectMemoryDir(ctx.directory);
|
|
585
|
-
const globalDir = getGlobalMemoryDir(
|
|
586
|
+
const globalDir = getGlobalMemoryDir();
|
|
586
587
|
mkdirSync5(join7(memoryRoot, "global"), { recursive: true });
|
|
587
|
-
mkdirSync5(join7(
|
|
588
|
-
mkdirSync5(join7(
|
|
588
|
+
mkdirSync5(join7(memoryRoot, "projects"), { recursive: true });
|
|
589
|
+
mkdirSync5(join7(memoryRoot, "sessions"), { recursive: true });
|
|
590
|
+
mkdirSync5(projectDir, { recursive: true });
|
|
589
591
|
const memoryTool = createMemoryTool({
|
|
590
592
|
memoryDir: memoryRoot,
|
|
591
|
-
dbPath: getDbPath(
|
|
593
|
+
dbPath: getDbPath(),
|
|
594
|
+
projectDir: ctx.directory
|
|
592
595
|
});
|
|
593
596
|
const checkpointPlugin = await CheckpointPlugin(ctx);
|
|
594
597
|
const injectionPlugin = await MemoryInjectionPlugin(ctx);
|
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 async 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 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 \n const stmt = this.db.prepare(sql)\n return stmt.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\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\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 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()\n const projectDir = getProjectMemoryDir(ctx.directory)\n const globalDir = getGlobalMemoryDir()\n\n // 创建目录结构\n mkdirSync(join(memoryRoot, \"global\"), { recursive: true })\n mkdirSync(join(memoryRoot, \"projects\"), { recursive: true })\n mkdirSync(join(memoryRoot, \"sessions\"), { recursive: true })\n mkdirSync(projectDir, { recursive: true })\n\n // 创建 memory 工具\n const memoryTool = createMemoryTool({\n memoryDir: memoryRoot,\n dbPath: getDbPath(),\n projectDir: 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 async 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 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 \n const stmt = this.db.prepare(sql)\n return stmt.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\"\nimport { homedir } from \"os\"\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\n/**\n * 获取记忆系统根目录(全局目录)\n * 路径: ~/.local/share/super-pocock/memory/\n * 所有项目共享同一个记忆数据库,通过 project_id 区分\n */\nexport function getMemoryRoot(_projectRoot?: string): string {\n return join(homedir(), \".local\", \"share\", \"super-pocock\", \"memory\")\n}\n\nexport function getProjectMemoryDir(projectRoot: string): string {\n const projectId = resolveProjectId(projectRoot)\n return join(getMemoryRoot(), \"projects\", projectId)\n}\n\nexport function getGlobalMemoryDir(): string {\n return join(getMemoryRoot(), \"global\")\n}\n\nexport function getSessionMemoryDir(projectRoot: string, sessionId: string): string {\n return join(getMemoryRoot(), \"sessions\", sessionId)\n}\n\nexport function getDbPath(): string {\n return join(getMemoryRoot(), \"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()\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(), \"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()\n const memoryRoot = getMemoryRoot()\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\n \"experimental.chat.system.transform\": async (input, output) => {\n const memories = memoryCache.get(input.sessionID)\n if (!memories) return\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 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"]}
|