sage-mem 2.1.23 → 2.1.24
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/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/autodream/tools.js +7 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
**Cross-session memory for DeepSeek Harness — plain markdown files, no database, no worker.**
|
|
14
14
|
|
|
15
|
-
**Current release: `2.1.
|
|
15
|
+
**Current release: `2.1.24`** — the npm badge above is the dynamic source of truth. **Contract baseline: `1.0.0`** — the first stable release, whose public commitments, the capability boundaries and the list of things it explicitly cannot do are frozen in the
|
|
16
16
|
[frozen contract](https://github.com/gezi-wen/sage-mem/blob/main/docs/1.0.0-contract.md).
|
|
17
17
|
|
|
18
18
|
If it is useful to you, a Star is the most direct feedback.
|
package/README.zh.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
> File-based cross-session memory for DeepSeek Harness — every memory is a plain markdown file you can open, edit and delete. No database, no worker, no port.
|
|
16
16
|
|
|
17
|
-
**当前发布版本:`2.1.
|
|
17
|
+
**当前发布版本:`2.1.24`** —— 顶部 npm 徽章是动态权威。**契约基线:`1.0.0`** —— 第一个稳定版,公开承诺、能力边界与「明确做不到」的清单冻结在
|
|
18
18
|
[契约冻结](https://github.com/gezi-wen/sage-mem/blob/main/docs/1.0.0-contract.md)。
|
|
19
19
|
|
|
20
20
|
如果它对你有用,给个 Star 是最直接的反馈。
|
package/lib/autodream/tools.js
CHANGED
|
@@ -30,7 +30,7 @@ import { createHash } from 'node:crypto'
|
|
|
30
30
|
import { auditMemoryDir, formatAudit, parseFrontmatterLite } from './audit.js'
|
|
31
31
|
import { archiveMemory } from '../memory/archive.js'
|
|
32
32
|
import { MAX_FILE_BYTES, STATE_ROOT } from '../memory/config.js'
|
|
33
|
-
import { INDEX_FILE_KEY, SESSION_LOG_KEY } from '../shared/md-name.js'
|
|
33
|
+
import { INDEX_FILE_KEY, SESSION_LOG_KEY, isPlainMdName } from '../shared/md-name.js'
|
|
34
34
|
import { stampHuman as localStamp } from '../shared/stamp.js'
|
|
35
35
|
import { writeFileAtomic, warnLog } from '../memory/util.js'
|
|
36
36
|
import { buildConflict, listConflicts, readConflict, sameConflict, writeConflict } from '../memory/conflicts.js'
|
|
@@ -58,10 +58,13 @@ export function safeMemoryPath(memoryDir, raw) {
|
|
|
58
58
|
if (typeof raw !== 'string') return null
|
|
59
59
|
const trimmed = raw.trim()
|
|
60
60
|
if (!trimmed) return null
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
// 文件名合法性**只用唯一判据**(`shared/md-name.js`):路径分隔符、冒号(NTFS 交替数据流)、
|
|
62
|
+
// 通配符与控制字符一律拒。这里曾经自己抄了一份、只拒了两种分隔符与上跳 ——
|
|
63
|
+
// 于是 `a:b.md` / `MEMORY.md:evil.md` 能一路走到 join,而它正是这条写路径的入口(2026-11-03 收敛)。
|
|
64
|
+
if (!isPlainMdName(trimmed)) return null
|
|
64
65
|
const base = basename(trimmed)
|
|
66
|
+
// 业务约束,比「文件名合法性」更严:不写隐藏文件。它是本函数比
|
|
67
|
+
// `isPlainMdName` 多出来的**唯一**一条,`test/shared-parity-test.mjs` 第 1 组盯着它。
|
|
65
68
|
if (base.startsWith('.')) return null
|
|
66
69
|
return join(memoryDir, base)
|
|
67
70
|
}
|
package/package.json
CHANGED