feat: M4 主動關心、待辦與記憶鞏固核心模組

- care:事件式關心(冷卻、每日上限、靜音、回覆中/輸入中不彈出),toast 與注入兩種輸出,台詞依觸發 × 個性 × 好感階段
- todo:新增、完成、承諾事項與到期提醒
- memory:檢索評分、遺忘曲線、鞏固與反思、金鑰過濾
- 以假時鐘與記憶體檔案系統測試核心接縫

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 13:30:22 +08:00
co-authored by Claude Sonnet 5.5
parent 030c599208
commit ac33dcca3b
6 changed files with 1125 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
// 檔案系統與時鐘由外部注入,核心不直接碰真實環境
export interface Fs {
read(path: string): Promise<string | null>
/** 原子寫入:先寫暫存檔再改名 */
write(path: string, data: string): Promise<void>
}
export type Clock = () => number
export function memoryFs(): Fs & { files: Map<string, string> } {
const files = new Map<string, string>()
return {
files,
async read(p) {
return files.get(p) ?? null
},
async write(p, d) {
files.set(p, d)
},
}
}
export async function readJson<T>(fs: Fs, path: string, fallback: T): Promise<T> {
const raw = await fs.read(path)
if (raw === null) return fallback
try {
return JSON.parse(raw) as T
} catch {
return fallback
}
}
export const writeJson = (fs: Fs, path: string, value: unknown) => fs.write(path, JSON.stringify(value, null, 2))
export async function nodeFs(): Promise<Fs> {
const { readFile, writeFile, rename, mkdir } = await import('node:fs/promises')
const { dirname } = await import('node:path')
return {
async read(p) {
try {
return await readFile(p, 'utf8')
} catch {
return null
}
},
async write(p, d) {
await mkdir(dirname(p), { recursive: true })
const tmp = `${p}.${process.pid}.tmp`
await writeFile(tmp, d)
await rename(tmp, p)
},
}
}