@jacklika/dsh-memory-curator 0.1.0-alpha.20 → 0.1.0-alpha.21
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/index.js +17 -6
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Curator tools for the DSH memory vault. This package is a member of the `@jackli
|
|
|
11
11
|
|
|
12
12
|
- `memory_forget(id, baseVersion)` — Move a curated note into the vault archive area (`archive/<original-relative-path>`). The note is not deleted; it can still be read directly, but `wiki_search` and `wiki_graph` exclude it by default. Requires the current `version` from `wiki_read`; a stale version fails closed. The move is committed by `memory-git` when configured.
|
|
13
13
|
|
|
14
|
-
- `memory_compact(scope?, maxAgeDays?, dryRun?)` — Archive notes. With the default `scope: 'auto-capture'` it archives old per-turn auto-capture notes, keeping only the most recent sessions (disabled by default; enable with `autoCaptureCompact: { enabled: true, keepSessions: N }` in the curator config). With `scope: 'stale'` it archives any note that is both older than `maxAgeDays` (required, ≥ 1) and has no inbound `[[links]]` — link presence is derived from the active `wiki_graph` link edges, so the graph tool must be installed for stale passes. Stale compaction needs no curator config beyond the parameters. The pass is idempotent: repeated runs produce no duplicate archives. It respects the same cross-process lock lane as other mutation tools. Pass `dryRun: true` to preview the selection — it returns `{ compacted: true, dryRun: true, kept, archived: 0, archivedIds: [], wouldArchive }` and archives nothing.
|
|
14
|
+
- `memory_compact(scope?, maxAgeDays?, keepSessions?, dryRun?)` — Archive notes. With the default `scope: 'auto-capture'` it archives old per-turn auto-capture notes, keeping only the most recent sessions (disabled by default; enable with `autoCaptureCompact: { enabled: true, keepSessions: N }` in the curator config). With `scope: 'stale'` it archives any note that is both older than `maxAgeDays` (required, ≥ 1) and has no inbound `[[links]]` — link presence is derived from the active `wiki_graph` link edges, so the graph tool must be installed for stale passes. Stale compaction needs no curator config beyond the parameters. The pass is idempotent: repeated runs produce no duplicate archives. It respects the same cross-process lock lane as other mutation tools. Pass `dryRun: true` to preview the selection — it returns `{ compacted: true, dryRun: true, enabled, kept, archived: 0, archivedIds: [], wouldArchive }` and archives nothing. `dryRun` is not gated by `autoCaptureCompact.enabled`, and a per-call `keepSessions` previews a hypothetical retention count before the feature is configured.
|
|
15
15
|
|
|
16
16
|
## Note ids
|
|
17
17
|
|
package/README.zh.md
CHANGED
|
@@ -11,7 +11,7 @@ DSH 记忆库的策展工具。本包是 `@jacklika/dsh-memory` Bundle 的成员
|
|
|
11
11
|
|
|
12
12
|
- `memory_forget(id, baseVersion)` — 将策展笔记移入归档区(`archive/<原相对路径>`)。笔记未被物理删除,仍可显式 `wiki_read` 读取,但 `wiki_search` 与 `wiki_graph` 默认不再返回它。必须传入 `wiki_read` 得到的当前 `version`;过期版本会失败关闭。若配置了 `memory-git`,此次移动会被提交。
|
|
13
13
|
|
|
14
|
-
- `memory_compact(scope?, maxAgeDays?, dryRun?)` — 归档笔记。默认 `scope: 'auto-capture'` 归档旧的逐回合自动捕获笔记,只保留最近 N 个会话(默认关闭;在 curator 配置中通过 `autoCaptureCompact: { enabled: true, keepSessions: N }` 开启)。`scope: 'stale'` 归档同时满足「mtime 早于 `maxAgeDays`(必填,≥ 1)」且「无入链 `[[links]]`」的笔记——链接关系取自 `wiki_graph` 的 link 边,因此 stale pass 需要安装 graph 工具;除参数外无需额外 curator 配置。该 pass 是幂等的:重复执行不会产生重复归档文件。它与其他变更工具使用同一跨进程锁车道。传 `dryRun: true` 可预览选中项——返回 `{ compacted: true, dryRun: true, kept, archived: 0, archivedIds: [], wouldArchive }
|
|
14
|
+
- `memory_compact(scope?, maxAgeDays?, keepSessions?, dryRun?)` — 归档笔记。默认 `scope: 'auto-capture'` 归档旧的逐回合自动捕获笔记,只保留最近 N 个会话(默认关闭;在 curator 配置中通过 `autoCaptureCompact: { enabled: true, keepSessions: N }` 开启)。`scope: 'stale'` 归档同时满足「mtime 早于 `maxAgeDays`(必填,≥ 1)」且「无入链 `[[links]]`」的笔记——链接关系取自 `wiki_graph` 的 link 边,因此 stale pass 需要安装 graph 工具;除参数外无需额外 curator 配置。该 pass 是幂等的:重复执行不会产生重复归档文件。它与其他变更工具使用同一跨进程锁车道。传 `dryRun: true` 可预览选中项——返回 `{ compacted: true, dryRun: true, enabled, kept, archived: 0, archivedIds: [], wouldArchive }`,不归档任何内容。`dryRun` 不受 `autoCaptureCompact.enabled` 门禁限制,且可按次传 `keepSessions` 在启用前预览假设的保留数量。
|
|
15
15
|
|
|
16
16
|
## 笔记 id
|
|
17
17
|
|
package/lib/index.js
CHANGED
|
@@ -400,7 +400,7 @@ export function apply(ctx, config) {
|
|
|
400
400
|
const provenance = pickProvenance(args);
|
|
401
401
|
ctx.logger?.debug(`memory-curator: capture target=${finalId} conflicts=${conflicts.length} writeMode=${writeMode} requireExisting=${requireExisting}`);
|
|
402
402
|
const overwrite = appending ? undefined : overwriteFrontmatter(selectedNote, args.title, tags, now, provenance);
|
|
403
|
-
const headingPrefix = args.summary.trimStart()
|
|
403
|
+
const headingPrefix = /^#\s/.test(args.summary.trimStart()) ? '' : `# ${args.title}\n\n`;
|
|
404
404
|
const content = appending
|
|
405
405
|
? appendContent
|
|
406
406
|
: `---\n${yaml.dump(overwrite).trim()}\n---\n\n${headingPrefix}${appendContent}`;
|
|
@@ -466,7 +466,7 @@ export function apply(ctx, config) {
|
|
|
466
466
|
...correctionProvenance,
|
|
467
467
|
};
|
|
468
468
|
const details = args.details ? `\n\n## Details\n\n${args.details}` : '';
|
|
469
|
-
const headingPrefix = args.summary.trimStart()
|
|
469
|
+
const headingPrefix = /^#\s/.test(args.summary.trimStart()) ? '' : `# ${title}\n\n`;
|
|
470
470
|
const content = `---\n${yaml.dump(frontmatter).trim()}\n---\n\n${headingPrefix}${args.summary}${details}\n`;
|
|
471
471
|
const written = await callTool(ctx, exec, 'wiki_write', {
|
|
472
472
|
id: args.id, content, mode: 'overwrite', requireExisting: true, baseVersion: args.baseVersion,
|
|
@@ -481,11 +481,12 @@ export function apply(ctx, config) {
|
|
|
481
481
|
})));
|
|
482
482
|
ctx.effect(() => ctx.tools.register(defineTool({
|
|
483
483
|
name: 'memory_compact',
|
|
484
|
-
description: 'Archive old per-turn auto-capture notes, keeping only the most recent sessions. This reduces search noise while preserving every capture in git history. Disabled by default; enable via autoCaptureCompact in the curator config. Returns { compacted, kept, archived, archivedIds } when active, or { compacted: false, reason } when disabled. Pass dryRun: true to preview the same selection without archiving anything. With scope: \'stale\', archives indexed notes whose last modification is older than maxAgeDays and that have no inbound explicit links; dryRun previews that selection too.',
|
|
484
|
+
description: 'Archive old per-turn auto-capture notes, keeping only the most recent sessions. This reduces search noise while preserving every capture in git history. Disabled by default; enable via autoCaptureCompact in the curator config. Returns { compacted, kept, archived, archivedIds } when active, or { compacted: false, reason } when disabled. Pass dryRun: true to preview the same selection without archiving anything — dryRun is not gated by autoCaptureCompact.enabled, and keepSessions may be passed per call to preview a hypothetical retention before enabling the feature. With scope: \'stale\', archives indexed notes whose last modification is older than maxAgeDays and that have no inbound explicit links; dryRun previews that selection too.',
|
|
485
485
|
parameters: {
|
|
486
486
|
dryRun: { type: 'boolean', description: 'Preview which notes would be archived without writing. Defaults to false.' },
|
|
487
487
|
scope: { type: 'string', enum: ['auto-capture', 'stale'], description: "What to compact: 'auto-capture' (default) prunes old capture sessions; 'stale' archives notes older than maxAgeDays with no inbound explicit links." },
|
|
488
488
|
maxAgeDays: { type: 'number', description: "Required when scope is 'stale': notes whose recorded mtime is older than this many days are candidates." },
|
|
489
|
+
keepSessions: { type: 'number', description: "For scope 'auto-capture': preview-time override of the configured keepSessions, so dryRun can preview a hypothetical setting before autoCaptureCompact is enabled." },
|
|
489
490
|
},
|
|
490
491
|
output: {
|
|
491
492
|
schema: { type: 'json' },
|
|
@@ -554,10 +555,13 @@ export function apply(ctx, config) {
|
|
|
554
555
|
};
|
|
555
556
|
}
|
|
556
557
|
const compact = resolved.autoCaptureCompact;
|
|
557
|
-
|
|
558
|
+
// A dry-run previews the selection, so it must work before (or without)
|
|
559
|
+
// enabling compaction; only a real archive pass is gated by `enabled`.
|
|
560
|
+
if (!compact.enabled && args.dryRun !== true) {
|
|
558
561
|
return { compacted: false, reason: 'auto-capture compaction is disabled in curator config' };
|
|
559
562
|
}
|
|
560
|
-
const
|
|
563
|
+
const keepOverride = typeof args.keepSessions === 'number' ? Math.floor(args.keepSessions) : undefined;
|
|
564
|
+
const keep = keepOverride ?? (typeof compact.keepSessions === 'number' && compact.keepSessions >= 1 ? Math.floor(compact.keepSessions) : 0);
|
|
561
565
|
if (keep < 1) {
|
|
562
566
|
return { compacted: false, reason: 'autoCaptureCompact.keepSessions must be >= 1' };
|
|
563
567
|
}
|
|
@@ -565,13 +569,20 @@ export function apply(ctx, config) {
|
|
|
565
569
|
const captures = dedupeHits(search.hits.filter(hit => isAutoCapture(hit.id)))
|
|
566
570
|
.sort((a, b) => b.id.localeCompare(a.id));
|
|
567
571
|
if (captures.length <= keep) {
|
|
568
|
-
return {
|
|
572
|
+
return {
|
|
573
|
+
compacted: true,
|
|
574
|
+
...(args.dryRun === true ? { dryRun: true, enabled: compact.enabled, wouldArchive: [] } : {}),
|
|
575
|
+
kept: captures.length,
|
|
576
|
+
archived: 0,
|
|
577
|
+
archivedIds: [],
|
|
578
|
+
};
|
|
569
579
|
}
|
|
570
580
|
const toArchive = captures.slice(keep);
|
|
571
581
|
if (args.dryRun === true) {
|
|
572
582
|
return {
|
|
573
583
|
compacted: true,
|
|
574
584
|
dryRun: true,
|
|
585
|
+
enabled: compact.enabled,
|
|
575
586
|
kept: keep,
|
|
576
587
|
archived: 0,
|
|
577
588
|
archivedIds: [],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jacklika/dsh-memory-curator",
|
|
3
3
|
"description": "Curator tools for the DSH memory vault: memory_recall before acting and memory_capture after significant work, with conflict detection and optional user approval.",
|
|
4
|
-
"version": "0.1.0-alpha.
|
|
4
|
+
"version": "0.1.0-alpha.21",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"@deepseek-ai/dsh-util-values": ">=0.1.7-rc.1 <0.3.0-0 || >=0.2.0-rc.1 <0.3.0-0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@jacklika/dsh-memory-git": "^0.1.0-alpha.9",
|
|
48
|
-
"@jacklika/dsh-tool-memory-filesystem": "^0.1.3-alpha.19",
|
|
49
47
|
"@jacklika/dsh-memory-scope": "^0.1.0-alpha.4",
|
|
48
|
+
"@jacklika/dsh-tool-memory-filesystem": "^0.1.3-alpha.19",
|
|
49
|
+
"@jacklika/dsh-memory-git": "^0.1.0-alpha.9",
|
|
50
50
|
"@jacklika/dsh-tool-memory-graph": "^0.1.0-alpha.13"
|
|
51
51
|
}
|
|
52
52
|
}
|