@coralai/sps-cli 0.89.21 → 0.90.0
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/assembly/base.yml +0 -7
- package/dist/commands/agentCommand.d.ts.map +1 -1
- package/dist/commands/agentCommand.js +2 -1
- package/dist/commands/agentCommand.js.map +1 -1
- package/dist/commands/cardDashboard.js +1 -1
- package/dist/commands/cardDashboard.js.map +1 -1
- package/dist/commands/cardMarkComplete.d.ts +24 -0
- package/dist/commands/cardMarkComplete.d.ts.map +1 -1
- package/dist/commands/cardMarkComplete.js +1 -1
- package/dist/commands/cardMarkComplete.js.map +1 -1
- package/dist/commands/cardMarkStarted.d.ts +23 -0
- package/dist/commands/cardMarkStarted.d.ts.map +1 -1
- package/dist/commands/cardMarkStarted.js +1 -1
- package/dist/commands/cardMarkStarted.js.map +1 -1
- package/dist/commands/hookCommand.js +1 -1
- package/dist/commands/hookCommand.js.map +1 -1
- package/dist/commands/memoryCommand.d.ts.map +1 -1
- package/dist/commands/memoryCommand.js +45 -34
- package/dist/commands/memoryCommand.js.map +1 -1
- package/dist/commands/pipelineTick.js +1 -1
- package/dist/commands/pipelineTick.js.map +1 -1
- package/dist/commands/qaTick.js +1 -1
- package/dist/commands/qaTick.js.map +1 -1
- package/dist/commands/tick.d.ts.map +1 -1
- package/dist/commands/tick.js +3 -2
- package/dist/commands/tick.js.map +1 -1
- package/dist/commands/workerLaunch.js +1 -1
- package/dist/commands/workerLaunch.js.map +1 -1
- package/dist/console/index.js +3 -3
- package/dist/console/index.js.map +1 -1
- package/dist/console/routes/chat.d.ts.map +1 -1
- package/dist/console/routes/chat.js +1 -1
- package/dist/console/routes/chat.js.map +1 -1
- package/dist/console/routes/help.js +1 -1
- package/dist/console/routes/help.js.map +1 -1
- package/dist/console/routes/projectConfig.js +1 -1
- package/dist/console/routes/projectConfig.js.map +1 -1
- package/dist/core/memory2/capture.d.ts +15 -12
- package/dist/core/memory2/capture.d.ts.map +1 -1
- package/dist/core/memory2/capture.js +32 -22
- package/dist/core/memory2/capture.js.map +1 -1
- package/dist/core/memory2/config.d.ts +3 -7
- package/dist/core/memory2/config.d.ts.map +1 -1
- package/dist/core/memory2/config.js +3 -13
- package/dist/core/memory2/config.js.map +1 -1
- package/dist/core/memory2/digest.d.ts +20 -14
- package/dist/core/memory2/digest.d.ts.map +1 -1
- package/dist/core/memory2/digest.js +15 -44
- package/dist/core/memory2/digest.js.map +1 -1
- package/dist/core/memory2/fakeStore.d.ts +26 -0
- package/dist/core/memory2/fakeStore.d.ts.map +1 -0
- package/dist/core/memory2/fakeStore.js +36 -0
- package/dist/core/memory2/fakeStore.js.map +1 -0
- package/dist/core/memory2/inject.d.ts +21 -2
- package/dist/core/memory2/inject.d.ts.map +1 -1
- package/dist/core/memory2/inject.js +4 -18
- package/dist/core/memory2/inject.js.map +1 -1
- package/dist/core/memory2/types.d.ts +8 -47
- package/dist/core/memory2/types.d.ts.map +1 -1
- package/dist/core/memory2/types.js +10 -10
- package/dist/core/memory2/types.js.map +1 -1
- package/dist/engines/MonitorEngine.d.ts.map +1 -1
- package/dist/engines/MonitorEngine.js +1 -1
- package/dist/engines/MonitorEngine.js.map +1 -1
- package/dist/engines/StageEngine.d.ts.map +1 -1
- package/dist/engines/StageEngine.js +4 -2
- package/dist/engines/StageEngine.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/manager/worker-manager-impl.d.ts +1 -1
- package/dist/manager/worker-manager-impl.d.ts.map +1 -1
- package/dist/manager/worker-manager-impl.js +12 -10
- package/dist/manager/worker-manager-impl.js.map +1 -1
- package/dist/providers/mcp/spsMcpServer.d.ts.map +1 -1
- package/dist/providers/mcp/spsMcpServer.js +124 -116
- package/dist/providers/mcp/spsMcpServer.js.map +1 -1
- package/dist/providers/media/mediaProviders.js +1 -1
- package/dist/providers/media/mediaProviders.js.map +1 -1
- package/dist/seams/memory/index.d.ts +83 -28
- package/dist/seams/memory/index.d.ts.map +1 -1
- package/dist/seams/memory/index.js +103 -9
- package/dist/seams/memory/index.js.map +1 -1
- package/dist/seams/memory/optional.d.ts +38 -0
- package/dist/seams/memory/optional.d.ts.map +1 -0
- package/dist/seams/memory/optional.js +26 -0
- package/dist/seams/memory/optional.js.map +1 -0
- package/dist/services/MemoryService.d.ts +1 -2
- package/dist/services/MemoryService.d.ts.map +1 -1
- package/dist/services/MemoryService.js +67 -25
- package/dist/services/MemoryService.js.map +1 -1
- package/dist/services/SystemService.d.ts +6 -0
- package/dist/services/SystemService.d.ts.map +1 -1
- package/dist/services/SystemService.js +6 -0
- package/dist/services/SystemService.js.map +1 -1
- package/dist/services/container.d.ts.map +1 -1
- package/dist/services/container.js +1 -0
- package/dist/services/container.js.map +1 -1
- package/dist/services/executors.d.ts.map +1 -1
- package/dist/services/executors.js +1 -1
- package/dist/services/executors.js.map +1 -1
- package/dist/services/promptPreview.d.ts.map +1 -1
- package/dist/services/promptPreview.js +2 -1
- package/dist/services/promptPreview.js.map +1 -1
- package/docs/help/02-commands.md +2 -2
- package/docs/help/05-api.md +2 -2
- package/package.json +2 -1
- package/dist/core/memory2/claudeMdRule.d.ts +0 -7
- package/dist/core/memory2/claudeMdRule.d.ts.map +0 -1
- package/dist/core/memory2/claudeMdRule.js +0 -73
- package/dist/core/memory2/claudeMdRule.js.map +0 -1
- package/dist/core/memory2/ftsIndex.d.ts +0 -8
- package/dist/core/memory2/ftsIndex.d.ts.map +0 -1
- package/dist/core/memory2/ftsIndex.js +0 -172
- package/dist/core/memory2/ftsIndex.js.map +0 -1
- package/dist/core/memory2/gc.d.ts +0 -9
- package/dist/core/memory2/gc.d.ts.map +0 -1
- package/dist/core/memory2/gc.js +0 -45
- package/dist/core/memory2/gc.js.map +0 -1
- package/dist/core/memory2/lock.d.ts +0 -12
- package/dist/core/memory2/lock.d.ts.map +0 -1
- package/dist/core/memory2/lock.js +0 -61
- package/dist/core/memory2/lock.js.map +0 -1
- package/dist/core/memory2/migrate.d.ts +0 -12
- package/dist/core/memory2/migrate.d.ts.map +0 -1
- package/dist/core/memory2/migrate.js +0 -119
- package/dist/core/memory2/migrate.js.map +0 -1
- package/dist/core/memory2/recallResult.d.ts +0 -19
- package/dist/core/memory2/recallResult.d.ts.map +0 -1
- package/dist/core/memory2/recallResult.js +0 -33
- package/dist/core/memory2/recallResult.js.map +0 -1
- package/dist/core/memory2/redact.d.ts +0 -21
- package/dist/core/memory2/redact.d.ts.map +0 -1
- package/dist/core/memory2/redact.js +0 -116
- package/dist/core/memory2/redact.js.map +0 -1
- package/dist/core/memory2/retrieve.d.ts +0 -29
- package/dist/core/memory2/retrieve.d.ts.map +0 -1
- package/dist/core/memory2/retrieve.js +0 -79
- package/dist/core/memory2/retrieve.js.map +0 -1
- package/dist/core/memory2/store.d.ts +0 -35
- package/dist/core/memory2/store.d.ts.map +0 -1
- package/dist/core/memory2/store.js +0 -240
- package/dist/core/memory2/store.js.map +0 -1
- package/dist/seams/memory-local/client.js +0 -135
- package/dist/seams/memory-local/index.d.ts +0 -34
- package/dist/seams/memory-local/index.d.ts.map +0 -1
- package/dist/seams/memory-local/index.js +0 -58
- package/dist/seams/memory-local/index.js.map +0 -1
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/claudeMdRule
|
|
3
|
-
* @description 往项目 `.claude/CLAUDE.md` 幂等注入「本地记忆(memory_*)」托管块。与 codegraph
|
|
4
|
-
* 同机制:只管理 START..END 之间;用户内容原样保留;不存在→追加、已存在→更新、
|
|
5
|
-
* 无文件→新建。规则告诉 agent:开工先 memory_recall,收尾把可复用结论 memory_save。
|
|
6
|
-
* @layer core
|
|
7
|
-
* @boundedContext memory
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
|
-
import { dirname, join } from 'node:path';
|
|
11
|
-
const START = '<!-- sps:memory:start — auto-managed by sps (regenerated on init/doctor); edit outside these markers -->';
|
|
12
|
-
const END = '<!-- sps:memory:end -->';
|
|
13
|
-
/** 块内正文(不含标记)。改规则改这里,重跑 init/doctor 即更新到所有项目。 */
|
|
14
|
-
const RULE = `## Project memory — recall first, save what's reusable (MANDATORY)
|
|
15
|
-
|
|
16
|
-
This project has a **local memory**: conventions, decisions, gotchas, and patterns
|
|
17
|
-
that earlier workers on THIS project already learned. It has likely been built
|
|
18
|
-
before — the non-obvious decisions and the traps are already recorded. **Recalling
|
|
19
|
-
them is not optional; it is how you avoid repeating failures this project already
|
|
20
|
-
solved and re-deciding things already settled.** The prompt only tells you HOW MANY
|
|
21
|
-
memories exist — the content is NOT injected. You must pull it.
|
|
22
|
-
|
|
23
|
-
**Every task, follow this protocol:**
|
|
24
|
-
|
|
25
|
-
1. **Before writing any code — RECALL.** Call \`memory_recall\` with the key terms of
|
|
26
|
-
the card (mechanic/file names, the exact thing you're about to build). It returns
|
|
27
|
-
id + title + snippet for the top hits (project + global scope). Then
|
|
28
|
-
\`memory_read <id>\` the relevant ones for full text, and apply what you find.
|
|
29
|
-
2. **Hit a non-obvious problem mid-task — RECALL again** with the symptom (the error,
|
|
30
|
-
the surprising behavior). Someone may have already hit and solved it.
|
|
31
|
-
3. **Settled something reusable — SAVE.** After you (a) establish a convention,
|
|
32
|
-
(b) make a non-obvious decision, or (c) hit a gotcha worth not repeating, call
|
|
33
|
-
\`memory_save\` with a short \`title\` + concise \`body\` + \`category\`
|
|
34
|
-
(convention/decision/gotcha/pattern/reference/note). Default scope = this project;
|
|
35
|
-
only \`scope: "global"\` for something true across ALL projects.
|
|
36
|
-
|
|
37
|
-
A worker who recalls first is faster and never re-discovers a solved failure on the
|
|
38
|
-
user's time. Skipping recall = repeating known mistakes.
|
|
39
|
-
|
|
40
|
-
If the \`memory_*\` tools aren't in your session, use the shell:
|
|
41
|
-
\`sps memory recall <project> "<query>"\` / \`sps memory save <project> --title "…" --body "…"\`.
|
|
42
|
-
|
|
43
|
-
**Never save:** secrets/tokens/credentials, deploy addresses, customer data, full
|
|
44
|
-
paths with sensitive data, or anything the code/git history already records.`;
|
|
45
|
-
function escapeRegex(s) {
|
|
46
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* 幂等确保 `<repoDir>/.claude/CLAUDE.md` 含记忆托管块。
|
|
50
|
-
* @returns created=新建文件 / appended=追加块 / updated=更新块 / unchanged=已最新。
|
|
51
|
-
*/
|
|
52
|
-
export function ensureMemoryRuleBlock(repoDir) {
|
|
53
|
-
const claudeMd = join(repoDir, '.claude', 'CLAUDE.md');
|
|
54
|
-
const block = `${START}\n\n${RULE}\n\n${END}`;
|
|
55
|
-
if (!existsSync(claudeMd)) {
|
|
56
|
-
mkdirSync(dirname(claudeMd), { recursive: true });
|
|
57
|
-
writeFileSync(claudeMd, `# Project Rules (Claude Code Worker)\n\n${block}\n`);
|
|
58
|
-
return 'created';
|
|
59
|
-
}
|
|
60
|
-
const content = readFileSync(claudeMd, 'utf-8');
|
|
61
|
-
const re = new RegExp(`${escapeRegex(START)}[\\s\\S]*?${escapeRegex(END)}`);
|
|
62
|
-
if (re.test(content)) {
|
|
63
|
-
const next = content.replace(re, block);
|
|
64
|
-
if (next === content)
|
|
65
|
-
return 'unchanged';
|
|
66
|
-
writeFileSync(claudeMd, next);
|
|
67
|
-
return 'updated';
|
|
68
|
-
}
|
|
69
|
-
const sep = content.endsWith('\n') ? '\n' : '\n\n';
|
|
70
|
-
writeFileSync(claudeMd, `${content}${sep}${block}\n`);
|
|
71
|
-
return 'appended';
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=claudeMdRule.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claudeMdRule.js","sourceRoot":"","sources":["../../../src/core/memory2/claudeMdRule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,KAAK,GAAG,0GAA0G,CAAC;AACzH,MAAM,GAAG,GAAG,yBAAyB,CAAC;AAEtC,iDAAiD;AACjD,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EA8BgE,CAAC;AAE9E,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAID;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,GAAG,KAAK,OAAO,IAAI,OAAO,GAAG,EAAE,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,aAAa,CAAC,QAAQ,EAAE,2CAA2C,KAAK,IAAI,CAAC,CAAC;QAC9E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,aAAa,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5E,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,WAAW,CAAC;QACzC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD,aAAa,CAAC,QAAQ,EAAE,GAAG,OAAO,GAAG,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC;IACtD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type SearchHit, type SearchOpts } from './retrieve.js';
|
|
2
|
-
import type { ScopeRef } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* FTS5 检索。返回 SearchHit[] 表示"走了 DB 路";返回 null 表示"未启用/不可用"→ 调用方回退内存。
|
|
5
|
-
* 排序仍用内存 searchEntries(FTS 仅预筛候选),故结果与纯内存一致。
|
|
6
|
-
*/
|
|
7
|
-
export declare function ftsRecall(refs: ScopeRef[], query: string, opts?: SearchOpts): SearchHit[] | null;
|
|
8
|
-
//# sourceMappingURL=ftsIndex.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ftsIndex.d.ts","sourceRoot":"","sources":["../../../src/core/memory2/ftsIndex.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAA2B,MAAM,eAAe,CAAC;AAEzF,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAoHxD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,UAAe,GAAG,SAAS,EAAE,GAAG,IAAI,CAgCpG"}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/ftsIndex
|
|
3
|
-
* @description 可选 FTS5 加速层(设计 §4 第二级)。**markdown 仍是唯一真源**,本索引是**派生、可重建**的
|
|
4
|
-
* 只读加速器:大 store 时用 FTS5 把候选从几千缩到几十,排序仍交给内存 BM25(searchEntries)
|
|
5
|
-
* → 结果与纯内存一致、只更快。门控:node:sqlite 可用(Node 22.5+)+ 条目数 ≥ 阈值 +
|
|
6
|
-
* 未被 SPS_MEMORY_INDEX=off 关;任一不满足或任何异常 → 返回 null,调用方静默回退内存。
|
|
7
|
-
* 与 codegraph 共用 `node:sqlite`;索引落 `~/.coral/memory/index.db`。
|
|
8
|
-
* @layer core
|
|
9
|
-
* @boundedContext memory
|
|
10
|
-
*/
|
|
11
|
-
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
12
|
-
import { createRequire } from 'node:module';
|
|
13
|
-
import { join } from 'node:path';
|
|
14
|
-
import { searchEntries, tokenize } from './retrieve.js';
|
|
15
|
-
import { listAllScopes, listEntries, memoryRoot, scopeDir } from './store.js';
|
|
16
|
-
/** 条目数达到此阈值才值得用 FTS5('auto' 模式下);'on' 忽略阈值。 */
|
|
17
|
-
const INDEX_MIN_ENTRIES = 500;
|
|
18
|
-
function indexMode() {
|
|
19
|
-
const v = (process.env.SPS_MEMORY_INDEX ?? 'auto').toLowerCase();
|
|
20
|
-
return v === 'off' ? 'off' : v === 'on' ? 'on' : 'auto';
|
|
21
|
-
}
|
|
22
|
-
// node:sqlite 惰性探测(旧 Node < 22.5 不存在)。undefined=没试过,null=不可用。
|
|
23
|
-
const nodeRequire = createRequire(import.meta.url);
|
|
24
|
-
let DatabaseSyncCtor;
|
|
25
|
-
function loadSqlite() {
|
|
26
|
-
if (DatabaseSyncCtor === undefined) {
|
|
27
|
-
try {
|
|
28
|
-
DatabaseSyncCtor = nodeRequire('node:sqlite').DatabaseSync ?? null;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
DatabaseSyncCtor = null; // 旧 Node / 未编译 sqlite → 回退内存
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return DatabaseSyncCtor;
|
|
35
|
-
}
|
|
36
|
-
function indexPath() { return join(memoryRoot(), 'index.db'); }
|
|
37
|
-
/** 全库指纹(不解析正文,只 readdir+stat):文件总数 + 最新 mtime。变了就重建。 */
|
|
38
|
-
function fingerprint() {
|
|
39
|
-
let count = 0;
|
|
40
|
-
let maxMtime = 0;
|
|
41
|
-
for (const ref of listAllScopes()) {
|
|
42
|
-
const dir = join(scopeDir(ref), 'entries');
|
|
43
|
-
if (!existsSync(dir))
|
|
44
|
-
continue;
|
|
45
|
-
for (const name of readdirSync(dir)) {
|
|
46
|
-
if (!name.endsWith('.md'))
|
|
47
|
-
continue;
|
|
48
|
-
count++;
|
|
49
|
-
try {
|
|
50
|
-
const m = statSync(join(dir, name)).mtimeMs;
|
|
51
|
-
if (m > maxMtime)
|
|
52
|
-
maxMtime = m;
|
|
53
|
-
}
|
|
54
|
-
catch { /* 文件刚被删 */ }
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return { count, maxMtime };
|
|
58
|
-
}
|
|
59
|
-
function openDb() {
|
|
60
|
-
const Ctor = loadSqlite();
|
|
61
|
-
if (!Ctor)
|
|
62
|
-
return null;
|
|
63
|
-
try {
|
|
64
|
-
const db = new Ctor(indexPath());
|
|
65
|
-
db.exec(`
|
|
66
|
-
CREATE TABLE IF NOT EXISTS meta (k TEXT PRIMARY KEY, v TEXT);
|
|
67
|
-
CREATE TABLE IF NOT EXISTS entries (
|
|
68
|
-
id TEXT PRIMARY KEY, scope TEXT, project TEXT, agentId TEXT,
|
|
69
|
-
title TEXT, tags TEXT, category TEXT, source TEXT, salience INTEGER,
|
|
70
|
-
created TEXT, updated TEXT, body TEXT
|
|
71
|
-
);
|
|
72
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS fts USING fts5(id UNINDEXED, tokens);
|
|
73
|
-
`);
|
|
74
|
-
return db;
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
return null; // fts5 不可用 / 打不开 → 回退内存
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/** 若指纹变化则全量重建索引(markdown → DB)。 */
|
|
81
|
-
function ensureFresh(db) {
|
|
82
|
-
const fp = fingerprint();
|
|
83
|
-
const stored = db.prepare('SELECT v FROM meta WHERE k=?').get('fingerprint')?.v;
|
|
84
|
-
const cur = `${fp.count}:${Math.round(fp.maxMtime)}`;
|
|
85
|
-
if (stored === cur)
|
|
86
|
-
return;
|
|
87
|
-
db.exec('DELETE FROM entries; DELETE FROM fts;');
|
|
88
|
-
const insE = db.prepare(`INSERT INTO entries (id,scope,project,agentId,title,tags,category,source,salience,created,updated,body)
|
|
89
|
-
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)`);
|
|
90
|
-
const insF = db.prepare('INSERT INTO fts (id, tokens) VALUES (?, ?)');
|
|
91
|
-
for (const ref of listAllScopes()) {
|
|
92
|
-
for (const e of listEntries(ref)) {
|
|
93
|
-
insE.run(e.id, e.scope, e.project ?? null, ref.scope === 'agent' ? ref.agentId : null, e.title, JSON.stringify(e.tags), e.category, e.source, e.salience, e.created, e.updated, e.body);
|
|
94
|
-
insF.run(e.id, tokenize(`${e.title} ${e.tags.join(' ')} ${e.body}`).join(' '));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
db.prepare('INSERT OR REPLACE INTO meta (k,v) VALUES (?,?)').run('fingerprint', cur);
|
|
98
|
-
}
|
|
99
|
-
function rowToEntry(r) {
|
|
100
|
-
return {
|
|
101
|
-
id: String(r.id), title: String(r.title), scope: r.scope,
|
|
102
|
-
category: r.category, tags: JSON.parse(String(r.tags || '[]')),
|
|
103
|
-
salience: Number(r.salience), uses: Number(r.uses) || 0, source: r.source,
|
|
104
|
-
project: r.project ? String(r.project) : undefined,
|
|
105
|
-
created: String(r.created), updated: String(r.updated), body: String(r.body),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
/** 作用域集 → SQL WHERE 片段 + 参数(匹配任一 ref)。 */
|
|
109
|
-
function scopeWhere(refs) {
|
|
110
|
-
const clauses = [];
|
|
111
|
-
const params = [];
|
|
112
|
-
for (const r of refs) {
|
|
113
|
-
if (r.scope === 'global')
|
|
114
|
-
clauses.push("scope='global'");
|
|
115
|
-
else if (r.scope === 'project') {
|
|
116
|
-
clauses.push('(scope=\'project\' AND project=?)');
|
|
117
|
-
params.push(r.project);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
clauses.push('(scope=\'agent\' AND agentId=?)');
|
|
121
|
-
params.push(r.agentId);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return { sql: clauses.length ? `(${clauses.join(' OR ')})` : '0', params };
|
|
125
|
-
}
|
|
126
|
-
/** 总条目数(门控用;复用指纹的 count,不解析正文)。 */
|
|
127
|
-
function totalCount() { return fingerprint().count; }
|
|
128
|
-
/**
|
|
129
|
-
* FTS5 检索。返回 SearchHit[] 表示"走了 DB 路";返回 null 表示"未启用/不可用"→ 调用方回退内存。
|
|
130
|
-
* 排序仍用内存 searchEntries(FTS 仅预筛候选),故结果与纯内存一致。
|
|
131
|
-
*/
|
|
132
|
-
export function ftsRecall(refs, query, opts = {}) {
|
|
133
|
-
const mode = indexMode();
|
|
134
|
-
if (mode === 'off')
|
|
135
|
-
return null;
|
|
136
|
-
if (!loadSqlite())
|
|
137
|
-
return null;
|
|
138
|
-
if (mode === 'auto' && totalCount() < INDEX_MIN_ENTRIES)
|
|
139
|
-
return null;
|
|
140
|
-
const db = openDb();
|
|
141
|
-
if (!db)
|
|
142
|
-
return null;
|
|
143
|
-
try {
|
|
144
|
-
ensureFresh(db);
|
|
145
|
-
const where = scopeWhere(refs);
|
|
146
|
-
const qTokens = tokenize(query);
|
|
147
|
-
let rows;
|
|
148
|
-
if (qTokens.length === 0) {
|
|
149
|
-
// 空查询:该作用域全集交给 searchEntries 按 salience/新鲜度排(镜像内存路)。
|
|
150
|
-
rows = db.prepare(`SELECT * FROM entries WHERE ${where.sql}`).all(...where.params);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
// FTS MATCH 预筛:任一 token 命中即候选;取较宽候选(limit*40,上限 400)再交内存精排。
|
|
154
|
-
const match = qTokens.map((t) => `"${t.replace(/"/g, '')}"`).join(' OR ');
|
|
155
|
-
const cap = Math.min(400, (opts.limit ?? 6) * 40);
|
|
156
|
-
rows = db.prepare(`SELECT e.* FROM fts JOIN entries e ON e.id = fts.id
|
|
157
|
-
WHERE fts MATCH ? AND ${where.sql} ORDER BY bm25(fts) LIMIT ?`).all(match, ...where.params, cap);
|
|
158
|
-
}
|
|
159
|
-
const candidates = rows.map(rowToEntry);
|
|
160
|
-
return searchEntries(candidates, query, opts);
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
return null; // 任何 DB 异常 → 回退内存
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
try {
|
|
167
|
-
db.close();
|
|
168
|
-
}
|
|
169
|
-
catch { /* ignore */ }
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
//# sourceMappingURL=ftsIndex.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ftsIndex.js","sourceRoot":"","sources":["../../../src/core/memory2/ftsIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../../src/core/memory2/gc.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAUD,0BAA0B;AAC1B,wBAAsB,OAAO,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB7D"}
|
package/dist/core/memory2/gc.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/gc
|
|
3
|
-
* @description 记忆收敛(设计 §6 · §5):硬删 tombstone + 去重收敛(正文归一化相同 → 留最优、软删其余)。
|
|
4
|
-
* 变更类操作,持作用域锁串行(withScopeLock)避免读-判-删竞态。衰减暂不做(需调参,
|
|
5
|
-
* 避免过度设计;留待引入使用频次统计后再定)。
|
|
6
|
-
* @layer core
|
|
7
|
-
* @boundedContext memory
|
|
8
|
-
*/
|
|
9
|
-
import { normalizeForDedup } from './capture.js';
|
|
10
|
-
import { writeMemoryIndex } from './digest.js';
|
|
11
|
-
import { withScopeLock } from './lock.js';
|
|
12
|
-
import { deleteEntry, listEntries, purgeTombstones } from './store.js';
|
|
13
|
-
/** 挑一组重复里保留哪条:salience 高优先,再 updated 新,再 human>agent>capture。 */
|
|
14
|
-
function pickBest(group) {
|
|
15
|
-
const rank = (s) => (s === 'human' ? 2 : s === 'agent' ? 1 : 0);
|
|
16
|
-
return group.slice().sort((a, b) => b.salience - a.salience || b.updated.localeCompare(a.updated) || rank(b.source) - rank(a.source))[0];
|
|
17
|
-
}
|
|
18
|
-
/** 对单作用域做 gc(持锁)。返回统计。 */
|
|
19
|
-
export async function gcScope(ref) {
|
|
20
|
-
return withScopeLock(ref, () => {
|
|
21
|
-
const purged = purgeTombstones(ref);
|
|
22
|
-
const entries = listEntries(ref);
|
|
23
|
-
const groups = new Map();
|
|
24
|
-
for (const e of entries) {
|
|
25
|
-
const k = normalizeForDedup(e.body);
|
|
26
|
-
if (!k)
|
|
27
|
-
continue; // 空正文不参与去重
|
|
28
|
-
(groups.get(k) ?? groups.set(k, []).get(k)).push(e);
|
|
29
|
-
}
|
|
30
|
-
let deduped = 0;
|
|
31
|
-
for (const group of groups.values()) {
|
|
32
|
-
if (group.length < 2)
|
|
33
|
-
continue;
|
|
34
|
-
const keep = pickBest(group);
|
|
35
|
-
for (const e of group) {
|
|
36
|
-
if (e.id !== keep.id && deleteEntry(ref, e.id))
|
|
37
|
-
deduped++;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (deduped > 0 || purged > 0)
|
|
41
|
-
writeMemoryIndex(ref);
|
|
42
|
-
return { purged, deduped, kept: listEntries(ref).length };
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=gc.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../src/core/memory2/gc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASvE,iEAAiE;AACjE,SAAS,QAAQ,CAAC,KAAoB;IACpC,MAAM,IAAI,GAAG,CAAC,CAAwB,EAAU,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACjC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CACjG,CAAC,CAAC,CAAE,CAAC;AACR,CAAC;AAED,0BAA0B;AAC1B,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAa;IACzC,OAAO,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE;QAC7B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QAEpC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,CAAC,CAAC;gBAAE,SAAS,CAAC,WAAW;YAC7B,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;oBAAE,OAAO,EAAE,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC;YAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACrD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ScopeRef } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* 持作用域锁跑 fn。**等锁是 await,不是忙等**;fn 本身仍是同步的(临界区就是几个同步文件操作)。
|
|
4
|
-
* 拿不到锁则重试至 timeoutMs;超时抛错。fn 结束(含抛错)必释放锁。陈旧锁自动回收。
|
|
5
|
-
*
|
|
6
|
-
* 🔴 曾经是 `while (Date.now() < end) {}`,注释写着"避免引入 async 传染" ——
|
|
7
|
-
* 代价是**最坏单核跑满 5 秒且事件循环完全停摆**(审计 E11)。
|
|
8
|
-
* 实测生产调用方只有 `gcScope` 一个,而它的两个上游本来就在 async 里,
|
|
9
|
-
* 所谓的"传染"只有两处 `.map` 要改成 `Promise.all` —— 远比烧掉一个核便宜。
|
|
10
|
-
*/
|
|
11
|
-
export declare function withScopeLock<T>(ref: ScopeRef, fn: () => T, timeoutMs?: number): Promise<T>;
|
|
12
|
-
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/core/memory2/lock.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAO3C;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CA8BhG"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/lock
|
|
3
|
-
* @description 作用域级互斥锁(设计 §6):变更类操作(gc/promote/migrate 的批量搬移)串行化,
|
|
4
|
-
* 避免"读-判-删"竞态。基于 mkdir 原子性(POSIX)——目录建成即持锁;陈旧锁按 mtime 回收。
|
|
5
|
-
* 创建/单条 save 走无冲突的一条一文件,**不需**此锁;仅多步读改删才用。
|
|
6
|
-
* @layer core
|
|
7
|
-
* @boundedContext memory
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, mkdirSync, rmdirSync, statSync } from 'node:fs';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import { scopeDir } from './store.js';
|
|
12
|
-
const STALE_MS = 60_000; // 超 60s 的锁视为陈旧(持锁进程已死),强制回收
|
|
13
|
-
const RETRY_MS = 50;
|
|
14
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
15
|
-
/**
|
|
16
|
-
* 持作用域锁跑 fn。**等锁是 await,不是忙等**;fn 本身仍是同步的(临界区就是几个同步文件操作)。
|
|
17
|
-
* 拿不到锁则重试至 timeoutMs;超时抛错。fn 结束(含抛错)必释放锁。陈旧锁自动回收。
|
|
18
|
-
*
|
|
19
|
-
* 🔴 曾经是 `while (Date.now() < end) {}`,注释写着"避免引入 async 传染" ——
|
|
20
|
-
* 代价是**最坏单核跑满 5 秒且事件循环完全停摆**(审计 E11)。
|
|
21
|
-
* 实测生产调用方只有 `gcScope` 一个,而它的两个上游本来就在 async 里,
|
|
22
|
-
* 所谓的"传染"只有两处 `.map` 要改成 `Promise.all` —— 远比烧掉一个核便宜。
|
|
23
|
-
*/
|
|
24
|
-
export async function withScopeLock(ref, fn, timeoutMs = 5_000) {
|
|
25
|
-
const dir = scopeDir(ref);
|
|
26
|
-
mkdirSync(dir, { recursive: true });
|
|
27
|
-
const lockDir = join(dir, '.lock');
|
|
28
|
-
const deadline = Date.now() + timeoutMs;
|
|
29
|
-
for (;;) {
|
|
30
|
-
try {
|
|
31
|
-
mkdirSync(lockDir); // 原子:已存在则抛 EEXIST
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// 已被占:陈旧则回收,否则重试
|
|
36
|
-
try {
|
|
37
|
-
if (Date.now() - statSync(lockDir).mtimeMs > STALE_MS) {
|
|
38
|
-
rmdirSync(lockDir);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
continue; // 锁刚被别人释放 → 重试抢
|
|
44
|
-
}
|
|
45
|
-
if (Date.now() > deadline)
|
|
46
|
-
throw new Error(`memory scope lock timeout: ${dir}`);
|
|
47
|
-
await sleep(RETRY_MS);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
return fn();
|
|
52
|
-
}
|
|
53
|
-
finally {
|
|
54
|
-
try {
|
|
55
|
-
if (existsSync(lockDir))
|
|
56
|
-
rmdirSync(lockDir);
|
|
57
|
-
}
|
|
58
|
-
catch { /* best effort */ }
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=lock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../src/core/memory2/lock.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,4BAA4B;AACrD,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAEnF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,GAAa,EAAE,EAAW,EAAE,SAAS,GAAG,KAAK;IAClF,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,SAAS,CAAC;QACR,IAAI,CAAC;YACH,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB;YACtC,MAAM;QACR,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB;YACjB,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;oBACtD,SAAS,CAAC,OAAO,CAAC,CAAC;oBACnB,SAAS;gBACX,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,CAAC,gBAAgB;YAC5B,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;YAChF,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,IAAI,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAClF,CAAC;AACH,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ScopeRef } from './types.js';
|
|
2
|
-
/** 迁移一个旧作用域目录的根级 *.md(跳 MEMORY.md / entries/ 子目录)。返回迁移条数。 */
|
|
3
|
-
export declare function migrateOldDir(oldDir: string, ref: ScopeRef): number;
|
|
4
|
-
/** 迁移单个项目的旧记忆 → v2(projects/<project>/*.md → projects/<project>/entries/)。 */
|
|
5
|
-
export declare function migrateProject(project: string): number;
|
|
6
|
-
/** 迁移全部:旧 user → global;agents/<id> → agent scope;projects/<p> → project scope。 */
|
|
7
|
-
export declare function migrateAll(): {
|
|
8
|
-
global: number;
|
|
9
|
-
agents: number;
|
|
10
|
-
projects: number;
|
|
11
|
-
};
|
|
12
|
-
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/core/memory2/migrate.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAa3D,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,MAAM,CA8BnE;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,mFAAmF;AACnF,wBAAgB,UAAU,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CA2CjF"}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/migrate
|
|
3
|
-
* @description 把旧文件记忆(~/.coral/memory/{user,agents/<id>,projects/<p>}/*.md,frontmatter
|
|
4
|
-
* name/description/type)迁到 v2 entry 格式,内容不丢。设计 §8。
|
|
5
|
-
* 旧文件在作用域目录根;v2 entry 写进 <scope>/entries/ —— 同目录不冲突。
|
|
6
|
-
* @layer core
|
|
7
|
-
* @boundedContext memory
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
10
|
-
import { join } from 'node:path';
|
|
11
|
-
import { parseFrontmatter } from '../flatfile/frontmatter.js';
|
|
12
|
-
import { writeMemoryIndex } from './digest.js';
|
|
13
|
-
import { memoryRoot, saveEntry, scopeDir } from './store.js';
|
|
14
|
-
/** 旧 type → v2 category。 */
|
|
15
|
-
function mapCategory(type) {
|
|
16
|
-
switch (type) {
|
|
17
|
-
case 'convention': return 'convention';
|
|
18
|
-
case 'decision': return 'decision';
|
|
19
|
-
case 'reference': return 'reference';
|
|
20
|
-
case 'lesson': return 'note';
|
|
21
|
-
default: return 'note';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/** 迁移一个旧作用域目录的根级 *.md(跳 MEMORY.md / entries/ 子目录)。返回迁移条数。 */
|
|
25
|
-
export function migrateOldDir(oldDir, ref) {
|
|
26
|
-
if (!existsSync(oldDir))
|
|
27
|
-
return 0;
|
|
28
|
-
let n = 0;
|
|
29
|
-
for (const name of readdirSync(oldDir)) {
|
|
30
|
-
if (!name.endsWith('.md') || name === 'MEMORY.md')
|
|
31
|
-
continue;
|
|
32
|
-
const p = join(oldDir, name);
|
|
33
|
-
try {
|
|
34
|
-
if (statSync(p).isDirectory())
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
const { data, body } = parseFrontmatter(readFileSync(p, 'utf-8'));
|
|
41
|
-
const title = typeof data.name === 'string' && data.name ? data.name : name.replace(/\.md$/, '');
|
|
42
|
-
const desc = typeof data.description === 'string' ? data.description : '';
|
|
43
|
-
const cat = mapCategory(data.type);
|
|
44
|
-
const text = body.trim() || desc || title;
|
|
45
|
-
try {
|
|
46
|
-
saveEntry(ref, {
|
|
47
|
-
title,
|
|
48
|
-
body: desc && !text.includes(desc) ? `${desc}\n\n${text}` : text,
|
|
49
|
-
category: cat,
|
|
50
|
-
salience: cat === 'convention' || cat === 'reference' ? 4 : 3,
|
|
51
|
-
source: 'human',
|
|
52
|
-
});
|
|
53
|
-
n++;
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
// 命中高危脱敏被丢弃 → 跳过这条,不阻断整体迁移。
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return n;
|
|
60
|
-
}
|
|
61
|
-
/** 迁移单个项目的旧记忆 → v2(projects/<project>/*.md → projects/<project>/entries/)。 */
|
|
62
|
-
export function migrateProject(project) {
|
|
63
|
-
const ref = { scope: 'project', project };
|
|
64
|
-
const n = migrateOldDir(scopeDir(ref), ref);
|
|
65
|
-
if (n > 0)
|
|
66
|
-
writeMemoryIndex(ref);
|
|
67
|
-
return n;
|
|
68
|
-
}
|
|
69
|
-
/** 迁移全部:旧 user → global;agents/<id> → agent scope;projects/<p> → project scope。 */
|
|
70
|
-
export function migrateAll() {
|
|
71
|
-
const root = memoryRoot();
|
|
72
|
-
let global = 0;
|
|
73
|
-
let agents = 0;
|
|
74
|
-
let projects = 0;
|
|
75
|
-
// 旧 user → global
|
|
76
|
-
const userDir = join(root, 'user');
|
|
77
|
-
if (existsSync(userDir)) {
|
|
78
|
-
const ref = { scope: 'global' };
|
|
79
|
-
global += migrateOldDir(userDir, ref);
|
|
80
|
-
if (global)
|
|
81
|
-
writeMemoryIndex(ref);
|
|
82
|
-
}
|
|
83
|
-
// agents/<id>(旧根级 *.md → 该 agent scope entries/)
|
|
84
|
-
const agentsDir = join(root, 'agents');
|
|
85
|
-
if (existsSync(agentsDir)) {
|
|
86
|
-
for (const id of readdirSync(agentsDir)) {
|
|
87
|
-
const dir = join(agentsDir, id);
|
|
88
|
-
try {
|
|
89
|
-
if (!statSync(dir).isDirectory())
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
const ref = { scope: 'agent', agentId: id };
|
|
96
|
-
const c = migrateOldDir(dir, ref);
|
|
97
|
-
if (c)
|
|
98
|
-
writeMemoryIndex(ref);
|
|
99
|
-
agents += c;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// projects/<p>
|
|
103
|
-
const projectsDir = join(root, 'projects');
|
|
104
|
-
if (existsSync(projectsDir)) {
|
|
105
|
-
for (const p of readdirSync(projectsDir)) {
|
|
106
|
-
const dir = join(projectsDir, p);
|
|
107
|
-
try {
|
|
108
|
-
if (!statSync(dir).isDirectory())
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
projects += migrateProject(p);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return { global, agents, projects };
|
|
118
|
-
}
|
|
119
|
-
//# sourceMappingURL=migrate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../src/core/memory2/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ScopeRef } from './types.js';
|
|
2
|
-
export interface RecallHit {
|
|
3
|
-
/** `<backend>:<原始 id>`。今天只有 `local:`。 */
|
|
4
|
-
id: string;
|
|
5
|
-
source: 'local';
|
|
6
|
-
title: string;
|
|
7
|
-
snippet: string;
|
|
8
|
-
score: number;
|
|
9
|
-
scope?: string;
|
|
10
|
-
project?: string;
|
|
11
|
-
category?: string;
|
|
12
|
-
tags?: string[];
|
|
13
|
-
}
|
|
14
|
-
/** 按 scope 召回,转成对外形状。**同步实现,签名保持 async** —— 调用方三处都在 await。 */
|
|
15
|
-
export declare function recallHits(refs: ScopeRef[], query: string, opts?: {
|
|
16
|
-
tags?: string[];
|
|
17
|
-
limit?: number;
|
|
18
|
-
}): Promise<RecallHit[]>;
|
|
19
|
-
//# sourceMappingURL=recallResult.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"recallResult.d.ts","sourceRoot":"","sources":["../../../src/core/memory2/recallResult.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,8DAA8D;AAC9D,wBAAsB,UAAU,CAC9B,IAAI,EAAE,QAAQ,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,SAAS,EAAE,CAAC,CActB"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/recallResult
|
|
3
|
-
* @description 召回结果的对外形状 —— 带来源标记与 `<backend>:<id>` 前缀。
|
|
4
|
-
*
|
|
5
|
-
* @layer core
|
|
6
|
-
* @boundedContext memory
|
|
7
|
-
*
|
|
8
|
-
* 🔴 **为什么保留 `source` 与 id 前缀,即使今天只有本地一个后端**:
|
|
9
|
-
* 它们不是给"多后端"用的装饰,是给**调用方**用的 ——
|
|
10
|
-
* `memory_read` 拿到一个 id 要知道去哪儿读回全文。去掉前缀就得靠猜。
|
|
11
|
-
*
|
|
12
|
-
* ⚠️ 这个形状此前长在 `external/federate.ts` 里(agentmemory 那次接入的产物),
|
|
13
|
-
* 随它一起被删会连累三个调用点改签名。**结果形状是本地的事,不该住在外部适配器里** ——
|
|
14
|
-
* 这正是那次接入没设计好的一个具体样本。
|
|
15
|
-
*/
|
|
16
|
-
import { recall } from './retrieve.js';
|
|
17
|
-
/** 按 scope 召回,转成对外形状。**同步实现,签名保持 async** —— 调用方三处都在 await。 */
|
|
18
|
-
export async function recallHits(refs, query, opts = {}) {
|
|
19
|
-
const limit = opts.limit ?? 6;
|
|
20
|
-
const hits = recall(refs, query, { ...(opts.tags ? { tags: opts.tags } : {}), limit });
|
|
21
|
-
return hits.slice(0, limit).map((h) => ({
|
|
22
|
-
id: `local:${h.entry.id}`,
|
|
23
|
-
source: 'local',
|
|
24
|
-
title: h.entry.title,
|
|
25
|
-
snippet: h.entry.body.slice(0, 200),
|
|
26
|
-
score: h.score,
|
|
27
|
-
scope: h.entry.scope,
|
|
28
|
-
...(h.entry.project ? { project: h.entry.project } : {}),
|
|
29
|
-
category: h.entry.category,
|
|
30
|
-
tags: h.entry.tags,
|
|
31
|
-
}));
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=recallResult.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"recallResult.js","sourceRoot":"","sources":["../../../src/core/memory2/recallResult.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAgBvC,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAgB,EAChB,KAAa,EACb,OAA4C,EAAE;IAE9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtC,EAAE,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE;QACzB,MAAM,EAAE,OAAgB;QACxB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;QACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;QACnC,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK;QACpB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ;QAC1B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;KACnB,CAAC,CAAC,CAAC;AACN,CAAC"}
|