@zooique/memora 0.3.0 → 2.0.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/README.md +8 -8
- package/dist/agent/agent.d.ts +69 -92
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +267 -197
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +3 -0
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +14 -4
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +1 -1
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +5 -4
- package/dist/agent/builtinToolHandlers.js.map +1 -1
- package/dist/agent/guardrail.d.ts +47 -0
- package/dist/agent/guardrail.d.ts.map +1 -0
- package/dist/agent/guardrail.js +51 -0
- package/dist/agent/guardrail.js.map +1 -0
- package/dist/agent/loop.d.ts +79 -18
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +317 -231
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/chatLockManager.d.ts +116 -0
- package/dist/agent/managers/chatLockManager.d.ts.map +1 -0
- package/dist/agent/managers/chatLockManager.js +191 -0
- package/dist/agent/managers/chatLockManager.js.map +1 -0
- package/dist/agent/managers/insightExtractor.d.ts +34 -69
- package/dist/agent/managers/insightExtractor.d.ts.map +1 -1
- package/dist/agent/managers/insightExtractor.js +133 -189
- package/dist/agent/managers/insightExtractor.js.map +1 -1
- package/dist/agent/managers/memoryAdvisor.d.ts +102 -2
- package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -1
- package/dist/agent/managers/memoryAdvisor.js +262 -4
- package/dist/agent/managers/memoryAdvisor.js.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.d.ts +85 -0
- package/dist/agent/managers/memoryDecayScheduler.d.ts.map +1 -1
- package/dist/agent/managers/memoryDecayScheduler.js +215 -0
- package/dist/agent/managers/memoryDecayScheduler.js.map +1 -1
- package/dist/agent/managers/memoryInspector.d.ts +230 -64
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +439 -81
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/relationBuilder.d.ts +131 -0
- package/dist/agent/managers/relationBuilder.d.ts.map +1 -0
- package/dist/agent/managers/relationBuilder.js +192 -0
- package/dist/agent/managers/relationBuilder.js.map +1 -0
- package/dist/agent/managers/sessionArchiver.d.ts +6 -0
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +68 -8
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +9 -17
- package/dist/agent/managers/sessionManager.js.map +1 -1
- package/dist/agent/managers/textPolishManager.d.ts +62 -0
- package/dist/agent/managers/textPolishManager.d.ts.map +1 -0
- package/dist/agent/managers/textPolishManager.js +99 -0
- package/dist/agent/managers/textPolishManager.js.map +1 -0
- package/dist/agent/personaMatcher.d.ts +29 -0
- package/dist/agent/personaMatcher.d.ts.map +1 -0
- package/dist/agent/personaMatcher.js +60 -0
- package/dist/agent/personaMatcher.js.map +1 -0
- package/dist/agent/toolExecutor.d.ts +2 -2
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +2 -1
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/tracer.d.ts +31 -0
- package/dist/agent/tracer.d.ts.map +1 -1
- package/dist/agent/tracer.js +31 -0
- package/dist/agent/tracer.js.map +1 -1
- package/dist/agent/types.d.ts +132 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +38 -0
- package/dist/agent/types.js.map +1 -1
- package/dist/config/loader.d.ts +52 -40
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +52 -32
- package/dist/config/loader.js.map +1 -1
- package/dist/eval/evalRunner.d.ts +94 -0
- package/dist/eval/evalRunner.d.ts.map +1 -0
- package/dist/eval/evalRunner.js +141 -0
- package/dist/eval/evalRunner.js.map +1 -0
- package/dist/eval/evalTypes.d.ts +33 -3
- package/dist/eval/evalTypes.d.ts.map +1 -1
- package/dist/eval/evalTypes.js +18 -2
- package/dist/eval/evalTypes.js.map +1 -1
- package/dist/eval/scenarios.d.ts +33 -0
- package/dist/eval/scenarios.d.ts.map +1 -0
- package/dist/eval/scenarios.js +109 -0
- package/dist/eval/scenarios.js.map +1 -0
- package/dist/index.d.ts +51 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -6
- package/dist/index.js.map +1 -1
- package/dist/llm/abortSignal.d.ts +27 -0
- package/dist/llm/abortSignal.d.ts.map +1 -0
- package/dist/llm/abortSignal.js +44 -0
- package/dist/llm/abortSignal.js.map +1 -0
- package/dist/llm/embedding.d.ts +7 -2
- package/dist/llm/embedding.d.ts.map +1 -1
- package/dist/llm/embedding.js +66 -46
- package/dist/llm/embedding.js.map +1 -1
- package/dist/llm/factory.js +1 -1
- package/dist/llm/factory.js.map +1 -1
- package/dist/llm/openaiCompatible.d.ts.map +1 -1
- package/dist/llm/openaiCompatible.js +26 -27
- package/dist/llm/openaiCompatible.js.map +1 -1
- package/dist/llm/provider.d.ts +0 -14
- package/dist/llm/provider.d.ts.map +1 -1
- package/dist/llm/provider.js.map +1 -1
- package/dist/logging/logger.d.ts +1 -0
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +43 -37
- package/dist/logging/logger.js.map +1 -1
- package/dist/memory/inMemoryStorage.d.ts.map +1 -1
- package/dist/memory/inMemoryStorage.js +8 -7
- package/dist/memory/inMemoryStorage.js.map +1 -1
- package/dist/memory/lockManager.d.ts +48 -0
- package/dist/memory/lockManager.d.ts.map +1 -0
- package/dist/memory/lockManager.js +159 -0
- package/dist/memory/lockManager.js.map +1 -0
- package/dist/memory/projectManager.d.ts +23 -53
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +46 -227
- package/dist/memory/projectManager.js.map +1 -1
- package/dist/memory/projectRegistry.d.ts +62 -0
- package/dist/memory/projectRegistry.d.ts.map +1 -0
- package/dist/memory/projectRegistry.js +158 -0
- package/dist/memory/projectRegistry.js.map +1 -0
- package/dist/memory/recall.d.ts +3 -3
- package/dist/memory/recall.d.ts.map +1 -1
- package/dist/memory/recall.js +3 -3
- package/dist/memory/recall.js.map +1 -1
- package/dist/memory/sourceValidation.d.ts +49 -0
- package/dist/memory/sourceValidation.d.ts.map +1 -0
- package/dist/memory/sourceValidation.js +141 -0
- package/dist/memory/sourceValidation.js.map +1 -0
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +2 -1
- package/dist/memory/store.js.map +1 -1
- package/dist/memory/types.d.ts +0 -47
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +0 -138
- package/dist/memory/types.js.map +1 -1
- package/dist/memory/vectorStore.d.ts +82 -7
- package/dist/memory/vectorStore.d.ts.map +1 -1
- package/dist/memory/vectorStore.js +12 -8
- package/dist/memory/vectorStore.js.map +1 -1
- package/dist/persona/personaManager.d.ts +30 -4
- package/dist/persona/personaManager.d.ts.map +1 -1
- package/dist/persona/personaManager.js +47 -14
- package/dist/persona/personaManager.js.map +1 -1
- package/dist/security/pathGuard.d.ts.map +1 -1
- package/dist/security/pathGuard.js +3 -1
- package/dist/security/pathGuard.js.map +1 -1
- package/dist/skill/skillManager.d.ts.map +1 -1
- package/dist/skill/skillManager.js +2 -1
- package/dist/skill/skillManager.js.map +1 -1
- package/dist/utils/array.d.ts +24 -0
- package/dist/utils/array.d.ts.map +1 -0
- package/dist/utils/array.js +24 -0
- package/dist/utils/array.js.map +1 -0
- package/dist/utils/errors.d.ts +10 -8
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +12 -9
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +7 -0
- package/dist/utils/eventEmitter.d.ts.map +1 -1
- package/dist/utils/eventEmitter.js.map +1 -1
- package/dist/utils/objects.d.ts +17 -0
- package/dist/utils/objects.d.ts.map +1 -0
- package/dist/utils/objects.js +19 -0
- package/dist/utils/objects.js.map +1 -0
- package/dist/utils/segmenter.d.ts +17 -0
- package/dist/utils/segmenter.d.ts.map +1 -1
- package/dist/utils/segmenter.js +26 -0
- package/dist/utils/segmenter.js.map +1 -1
- package/dist/utils/strings.d.ts +22 -1
- package/dist/utils/strings.d.ts.map +1 -1
- package/dist/utils/strings.js +29 -1
- package/dist/utils/strings.js.map +1 -1
- package/dist/utils/time.d.ts +18 -3
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +24 -8
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/toError.d.ts +8 -4
- package/dist/utils/toError.d.ts.map +1 -1
- package/dist/utils/toError.js +25 -5
- package/dist/utils/toError.js.map +1 -1
- package/package.json +11 -1
|
@@ -1,88 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 项目管理器 —
|
|
2
|
+
* 项目管理器 — 多项目生命周期编排(瘦身后)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
6
|
-
* - 锁文件机制(.memora/.lock)防止同项目并发写入导致数据损坏
|
|
4
|
+
* 核心职责(聚焦编排):
|
|
5
|
+
* - 项目初始化编排(关闭旧项目 → 加锁 → 加载资源 → 构建上下文)
|
|
7
6
|
* - Agent 级资源管理(memora.db 全局共享,不随项目切换重建)
|
|
8
7
|
* - 两层记忆加载:项目级(projectPath/.memora/)→ Agent 级(configDir)
|
|
9
8
|
* - 项目切换(只更新 projectPath + security + 重新加载项目 rules/skills)
|
|
10
9
|
*
|
|
10
|
+
* 已拆分至专职模块(1.0 接口稳定化):
|
|
11
|
+
* - ProjectRegistry(src/memory/projectRegistry.ts):注册表读写 + 条目管理
|
|
12
|
+
* - LockManager(src/memory/lockManager.ts):锁文件获取/释放 + 残留锁检测
|
|
13
|
+
*
|
|
11
14
|
* 设计原则(单 Agent 模型):
|
|
12
15
|
* - memora.db 只有一个(Agent 级),所有项目共享同一记忆数据库
|
|
13
16
|
* - 项目切换不重建数据库,只更新安全守卫 + 重新扫描项目规则
|
|
14
17
|
* - 项目级 .memora/ 仅存放 rules/ 和 skills/(无 memora.db)
|
|
15
18
|
*
|
|
16
|
-
* 锁文件策略:
|
|
17
|
-
* - 打开项目时创建 .lock 文件(含 PID + 时间戳 + 主机名)
|
|
18
|
-
* - 关闭/切换项目时删除 .lock 文件
|
|
19
|
-
* - 检测到残留锁时:判断进程是否存活 → 存活则警告 / 已死则清理
|
|
20
|
-
* - 不强制阻止并发(CLI-first,用户决定)
|
|
21
|
-
*
|
|
22
19
|
* 详见 ADR-008 · 目录结构按"职责分层"
|
|
23
20
|
*/
|
|
24
21
|
import { resolve, join } from 'node:path';
|
|
25
|
-
import {
|
|
26
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
|
|
27
|
-
import { mkdir, readFile, writeFile, unlink } from 'node:fs/promises';
|
|
22
|
+
import { mkdir } from 'node:fs/promises';
|
|
28
23
|
import { FileStore } from '../memory/store.js';
|
|
29
24
|
import { InMemoryStorage } from '../memory/inMemoryStorage.js';
|
|
30
25
|
import { MemoryLoader } from '../memory/loader.js';
|
|
31
26
|
import { logger } from '../logging/logger.js';
|
|
32
|
-
import { toError } from '../utils/toError.js';
|
|
33
27
|
import { expandHome } from '../utils/path.js';
|
|
34
28
|
import { SOURCE_LABELS } from '../memory/types.js';
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
/**
|
|
39
|
-
* 判断值是否为非数组对象(排除 null)
|
|
40
|
-
*
|
|
41
|
-
* @param value 待校验的值
|
|
42
|
-
* @returns true 表示是普通对象
|
|
43
|
-
*/
|
|
44
|
-
function isPlainObject(value) {
|
|
45
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* 判断值是否为 LockInfo(锁文件结构)
|
|
49
|
-
*
|
|
50
|
-
* @param value 待校验的值
|
|
51
|
-
* @returns true 表示符合 LockInfo 结构
|
|
52
|
-
*/
|
|
53
|
-
function isLockInfo(value) {
|
|
54
|
-
if (!isPlainObject(value))
|
|
55
|
-
return false;
|
|
56
|
-
return (typeof value['pid'] === 'number' &&
|
|
57
|
-
typeof value['acquiredAt'] === 'string' &&
|
|
58
|
-
typeof value['hostname'] === 'string');
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* 判断值是否为 ProjectEntry(项目注册表条目)
|
|
62
|
-
*
|
|
63
|
-
* @param value 待校验的值
|
|
64
|
-
* @returns true 表示符合 ProjectEntry 结构
|
|
65
|
-
*/
|
|
66
|
-
function isProjectEntry(value) {
|
|
67
|
-
if (!isPlainObject(value))
|
|
68
|
-
return false;
|
|
69
|
-
return (typeof value['path'] === 'string' &&
|
|
70
|
-
typeof value['name'] === 'string' &&
|
|
71
|
-
typeof value['lastOpened'] === 'string');
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* 判断值是否为 ProjectEntry 数组
|
|
75
|
-
*
|
|
76
|
-
* 过滤掉不符合结构的条目,仅保留合法条目
|
|
77
|
-
*
|
|
78
|
-
* @param value 待校验的值
|
|
79
|
-
* @returns 解析后的合法条目数组(损坏时返回空数组)
|
|
80
|
-
*/
|
|
81
|
-
function asProjectEntryArray(value) {
|
|
82
|
-
if (!Array.isArray(value))
|
|
83
|
-
return [];
|
|
84
|
-
return value.filter(isProjectEntry);
|
|
85
|
-
}
|
|
29
|
+
import { ProjectRegistry } from '../memory/projectRegistry.js';
|
|
30
|
+
import { LockManager } from '../memory/lockManager.js';
|
|
31
|
+
// ─── 类 ──────────────────────────────────────────────────
|
|
86
32
|
/**
|
|
87
33
|
* 项目管理器
|
|
88
34
|
*
|
|
@@ -90,33 +36,38 @@ function asProjectEntryArray(value) {
|
|
|
90
36
|
* 1. 初始化当前项目(加锁 + 加载两层配置)
|
|
91
37
|
* 2. /project <name> 切换到新项目(解锁旧项目 + 加锁新项目)
|
|
92
38
|
* 3. 退出时清理锁文件
|
|
39
|
+
*
|
|
40
|
+
* 注册表/锁文件实现委托给 ProjectRegistry / LockManager,
|
|
41
|
+
* 本类聚焦生命周期编排。
|
|
93
42
|
*/
|
|
94
43
|
export class ProjectManager {
|
|
95
|
-
/** 项目注册表路径 */
|
|
96
|
-
registryPath;
|
|
97
44
|
/** Agent 级数据目录(memora.db 所在目录) */
|
|
98
45
|
agentDataDir;
|
|
99
46
|
/** Agent 级存储实例(全局共享,不随项目切换重建) */
|
|
100
47
|
agentIndex = null;
|
|
101
48
|
/** 当前打开的项目路径 */
|
|
102
49
|
currentProjectPath = null;
|
|
103
|
-
/** 当前持有的锁文件路径 */
|
|
104
|
-
currentLockPath = null;
|
|
105
50
|
/** 外部注入的存储实例(可选,不传则内部创建 InMemoryStorage 兜底) */
|
|
106
51
|
externalStorage;
|
|
107
52
|
/** SecurityGuard 工厂函数(由 Agent 层注入) */
|
|
108
53
|
createSecurityGuard;
|
|
54
|
+
/** 项目注册表(专职管理 projects.json) */
|
|
55
|
+
registry;
|
|
56
|
+
/** 锁文件管理器(专职管理 .memora/.lock) */
|
|
57
|
+
lockManager;
|
|
109
58
|
constructor(options) {
|
|
110
59
|
const { dataDir, storage, registryDir, createSecurityGuard } = options;
|
|
111
60
|
const memoraHome = resolve(expandHome(dataDir));
|
|
112
61
|
this.agentDataDir = memoraHome;
|
|
113
62
|
// 注册表目录:优先使用宿主指定的用户级路径,避免每项目重复存储
|
|
114
63
|
const registryHome = registryDir ? resolve(expandHome(registryDir)) : memoraHome;
|
|
115
|
-
this.registryPath = join(registryHome, 'projects.json');
|
|
116
64
|
// 保存外部注入的存储实例(宿主项目注入时使用)
|
|
117
65
|
this.externalStorage = storage ?? null;
|
|
118
66
|
// 保存 SecurityGuard 工厂函数
|
|
119
67
|
this.createSecurityGuard = createSecurityGuard;
|
|
68
|
+
// 委托注册表/锁文件管理给专职模块
|
|
69
|
+
this.registry = new ProjectRegistry(join(registryHome, 'projects.json'));
|
|
70
|
+
this.lockManager = new LockManager();
|
|
120
71
|
}
|
|
121
72
|
/**
|
|
122
73
|
* 确保 Agent 级资源已初始化(存储实例)
|
|
@@ -164,11 +115,10 @@ export class ProjectManager {
|
|
|
164
115
|
if (this.currentProjectPath) {
|
|
165
116
|
await this.closeProject();
|
|
166
117
|
}
|
|
167
|
-
// 2) 解析 memoraDir +
|
|
118
|
+
// 2) 解析 memoraDir + 获取项目级锁(委托给 LockManager)
|
|
168
119
|
const memoraDir = this.resolveMemoraDir(projectPath);
|
|
169
|
-
await this.
|
|
120
|
+
await this.lockManager.acquire(memoraDir);
|
|
170
121
|
this.currentProjectPath = projectPath;
|
|
171
|
-
this.currentLockPath = join(memoraDir, '.lock');
|
|
172
122
|
// 后续步骤失败时释放锁并重置状态,避免锁文件残留导致下次启动检测失败
|
|
173
123
|
try {
|
|
174
124
|
// 3) 确保项目目录 + 加载两层资源
|
|
@@ -179,11 +129,10 @@ export class ProjectManager {
|
|
|
179
129
|
}
|
|
180
130
|
catch (err) {
|
|
181
131
|
// 后续步骤失败时释放锁并重置状态,避免锁文件残留导致下次启动检测失败
|
|
182
|
-
await this.
|
|
132
|
+
await this.lockManager.release().catch((releaseErr) => {
|
|
183
133
|
logger.warn({ err: releaseErr }, '释放项目锁失败');
|
|
184
134
|
});
|
|
185
135
|
this.currentProjectPath = null;
|
|
186
|
-
this.currentLockPath = null;
|
|
187
136
|
throw err;
|
|
188
137
|
}
|
|
189
138
|
}
|
|
@@ -242,9 +191,9 @@ export class ProjectManager {
|
|
|
242
191
|
const security = this.createSecurityGuard
|
|
243
192
|
? this.createSecurityGuard(projectPath, memoraDir, configDir, this.agentDataDir)
|
|
244
193
|
: null;
|
|
245
|
-
//
|
|
246
|
-
const name = projectName ||
|
|
247
|
-
this.
|
|
194
|
+
// 注册到项目表(委托给 ProjectRegistry)
|
|
195
|
+
const name = projectName || ProjectRegistry.inferProjectName(projectPath);
|
|
196
|
+
this.registry.register(projectPath, name);
|
|
248
197
|
logger.info({
|
|
249
198
|
projectPath,
|
|
250
199
|
projectName: name,
|
|
@@ -270,9 +219,8 @@ export class ProjectManager {
|
|
|
270
219
|
*/
|
|
271
220
|
async closeProject() {
|
|
272
221
|
// Agent 级 index/sessionStore 不关闭——它们是共享的,在整个 Agent 生命周期内持久存在
|
|
273
|
-
await this.
|
|
222
|
+
await this.lockManager.release();
|
|
274
223
|
this.currentProjectPath = null;
|
|
275
|
-
this.currentLockPath = null;
|
|
276
224
|
}
|
|
277
225
|
/**
|
|
278
226
|
* 完全关闭:释放项目锁 + 关闭 Agent 级数据库
|
|
@@ -294,45 +242,41 @@ export class ProjectManager {
|
|
|
294
242
|
}
|
|
295
243
|
/**
|
|
296
244
|
* 列出已注册的项目(IX-02:统一为 getter 风格,与 persona/skill 一致)
|
|
245
|
+
*
|
|
246
|
+
* 委托给 ProjectRegistry。
|
|
297
247
|
*/
|
|
298
248
|
get list() {
|
|
299
|
-
return this.
|
|
249
|
+
return this.registry.list;
|
|
300
250
|
}
|
|
301
251
|
/**
|
|
302
252
|
* 列出已注册的项目
|
|
303
|
-
*
|
|
253
|
+
*
|
|
254
|
+
* v1.0 公共 API(CHANGELOG 迁移路径:`agent.listProjects()` → `agent.projects.listProjects()`)。
|
|
255
|
+
* 与 `.list` getter 等价,保留方法形式以兼容 0.3 迁移路径。
|
|
304
256
|
*/
|
|
305
257
|
listProjects() {
|
|
306
|
-
return this.
|
|
258
|
+
return this.registry.list;
|
|
307
259
|
}
|
|
308
260
|
/**
|
|
309
261
|
* 注册项目到注册表
|
|
262
|
+
*
|
|
263
|
+
* 委托给 ProjectRegistry。
|
|
264
|
+
*
|
|
265
|
+
* @param projectPath 项目根目录
|
|
266
|
+
* @param name 项目名称
|
|
310
267
|
*/
|
|
311
268
|
registerProject(projectPath, name) {
|
|
312
|
-
|
|
313
|
-
// Windows 文件系统不区分大小写,路径大小写不同视为同一项目
|
|
314
|
-
const existing = registry.findIndex((e) => e.path.toLowerCase() === projectPath.toLowerCase());
|
|
315
|
-
const entry = {
|
|
316
|
-
path: projectPath,
|
|
317
|
-
name,
|
|
318
|
-
lastOpened: nowIso(),
|
|
319
|
-
};
|
|
320
|
-
if (existing >= 0) {
|
|
321
|
-
registry[existing] = entry;
|
|
322
|
-
}
|
|
323
|
-
else {
|
|
324
|
-
registry.push(entry);
|
|
325
|
-
}
|
|
326
|
-
this.writeRegistry(registry);
|
|
269
|
+
this.registry.register(projectPath, name);
|
|
327
270
|
}
|
|
328
271
|
/**
|
|
329
272
|
* 从注册表移除项目
|
|
273
|
+
*
|
|
274
|
+
* 委托给 ProjectRegistry。
|
|
275
|
+
*
|
|
276
|
+
* @param projectPath 项目根目录
|
|
330
277
|
*/
|
|
331
278
|
unregisterProject(projectPath) {
|
|
332
|
-
|
|
333
|
-
// Windows 文件系统不区分大小写,大小写不同视为同一项目
|
|
334
|
-
const filtered = registry.filter((e) => e.path.toLowerCase() !== projectPath.toLowerCase());
|
|
335
|
-
this.writeRegistry(filtered);
|
|
279
|
+
this.registry.unregister(projectPath);
|
|
336
280
|
}
|
|
337
281
|
/**
|
|
338
282
|
* 获取当前项目路径
|
|
@@ -340,86 +284,6 @@ export class ProjectManager {
|
|
|
340
284
|
get currentProject() {
|
|
341
285
|
return this.currentProjectPath;
|
|
342
286
|
}
|
|
343
|
-
/**
|
|
344
|
-
* 获取锁文件
|
|
345
|
-
* 如果锁文件存在且进程存活,发出警告但不阻止
|
|
346
|
-
* 如果锁文件存在但进程已死,清理残留锁
|
|
347
|
-
*/
|
|
348
|
-
async acquireLock(memoraDir) {
|
|
349
|
-
const lockPath = join(memoraDir, '.lock');
|
|
350
|
-
try {
|
|
351
|
-
// 尝试读取锁文件(存在时)
|
|
352
|
-
const raw = await readFile(lockPath, 'utf-8');
|
|
353
|
-
// QC-24 使用类型守卫校验 JSON.parse 结果,替代 `as LockInfo` 类型断言
|
|
354
|
-
const parsed = JSON.parse(raw);
|
|
355
|
-
if (!isLockInfo(parsed)) {
|
|
356
|
-
// 锁文件结构损坏,清理后重新获取
|
|
357
|
-
logger.warn({ path: lockPath }, '锁文件结构损坏,清理残留');
|
|
358
|
-
await this.safeUnlink(lockPath);
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
const info = parsed;
|
|
362
|
-
// 检查进程是否存活
|
|
363
|
-
if (this.isProcessAlive(info.pid)) {
|
|
364
|
-
logger.warn({ pid: info.pid, acquiredAt: info.acquiredAt, hostname: info.hostname }, '项目已被其他进程打开(锁文件存在),继续操作可能导致数据冲突');
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
// 残留锁,清理
|
|
368
|
-
logger.info({ pid: info.pid }, '清理残留锁文件(进程已退出)');
|
|
369
|
-
await this.safeUnlink(lockPath);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
catch (err) {
|
|
373
|
-
// 锁文件不存在或损坏,清理:记录 debug 日志便于排查(不存在属正常首次启动)
|
|
374
|
-
logger.debug({ path: lockPath, err: toError(err).message }, '锁文件读取失败,清理残留');
|
|
375
|
-
await this.safeUnlink(lockPath);
|
|
376
|
-
}
|
|
377
|
-
// 写入新锁
|
|
378
|
-
const lockInfo = {
|
|
379
|
-
pid: process.pid,
|
|
380
|
-
acquiredAt: nowIso(),
|
|
381
|
-
hostname: hostname(),
|
|
382
|
-
};
|
|
383
|
-
await mkdir(memoraDir, { recursive: true });
|
|
384
|
-
await writeFile(lockPath, JSON.stringify(lockInfo, null, 2), 'utf-8');
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* 释放锁文件
|
|
388
|
-
*/
|
|
389
|
-
async releaseLock() {
|
|
390
|
-
if (this.currentLockPath) {
|
|
391
|
-
await this.safeUnlink(this.currentLockPath);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* 安全删除文件(忽略不存在的错误)
|
|
396
|
-
*/
|
|
397
|
-
async safeUnlink(filePath) {
|
|
398
|
-
try {
|
|
399
|
-
await unlink(filePath);
|
|
400
|
-
}
|
|
401
|
-
catch (err) {
|
|
402
|
-
logger.debug({ path: filePath, err: toError(err).message }, 'safeUnlink 忽略删除失败');
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* 检查进程是否存活
|
|
407
|
-
*
|
|
408
|
-
* 跨平台统一使用 process.kill(pid, 0) 探测进程存活
|
|
409
|
-
* (Windows 上 process.kill(pid, 0) 同样有效)
|
|
410
|
-
*/
|
|
411
|
-
isProcessAlive(pid) {
|
|
412
|
-
try {
|
|
413
|
-
// 发送信号 0 检查进程是否存在(POSIX 兼容)
|
|
414
|
-
// Windows 上 process.kill(pid, 0) 也会抛出错误如果进程不存在
|
|
415
|
-
process.kill(pid, 0);
|
|
416
|
-
return true;
|
|
417
|
-
}
|
|
418
|
-
catch {
|
|
419
|
-
logger.debug({ pid }, '进程不存在');
|
|
420
|
-
return false;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
287
|
/**
|
|
424
288
|
* 解析项目的 .memora/ 目录路径
|
|
425
289
|
* 每个项目有独立的 .memora/ 目录(在项目根目录下)
|
|
@@ -428,50 +292,5 @@ export class ProjectManager {
|
|
|
428
292
|
resolveMemoraDir(projectPath) {
|
|
429
293
|
return resolve(projectPath, '.memora');
|
|
430
294
|
}
|
|
431
|
-
/**
|
|
432
|
-
* 从项目路径推断项目名称
|
|
433
|
-
* 取路径最后一段目录名
|
|
434
|
-
*/
|
|
435
|
-
inferProjectName(projectPath) {
|
|
436
|
-
const parts = projectPath.replace(/[/\\]+$/, '').split(/[/\\]/);
|
|
437
|
-
return parts[parts.length - 1] || 'unnamed';
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* 读取项目注册表
|
|
441
|
-
*
|
|
442
|
-
* 同步读取:list getter 契约要求同步返回,注册表操作低频,同步 I/O 影响可控
|
|
443
|
-
* 损坏时返回空数组并记录警告日志,避免静默吞错掩盖磁盘故障
|
|
444
|
-
*/
|
|
445
|
-
readRegistry() {
|
|
446
|
-
if (!existsSync(this.registryPath)) {
|
|
447
|
-
return [];
|
|
448
|
-
}
|
|
449
|
-
try {
|
|
450
|
-
const raw = readFileSync(this.registryPath, 'utf-8');
|
|
451
|
-
// QC-24 使用类型守卫校验 JSON.parse 结果,替代 `as ProjectEntry[]` 类型断言
|
|
452
|
-
// 过滤掉不符合结构的条目,仅保留合法条目
|
|
453
|
-
const parsed = JSON.parse(raw);
|
|
454
|
-
const entries = asProjectEntryArray(parsed);
|
|
455
|
-
if (entries.length === 0 && Array.isArray(parsed) && parsed.length > 0) {
|
|
456
|
-
// 数组存在但所有条目都不合法,记录警告
|
|
457
|
-
logger.warn({ path: this.registryPath, totalEntries: parsed.length }, '项目注册表所有条目结构不合法,返回空列表');
|
|
458
|
-
}
|
|
459
|
-
return entries;
|
|
460
|
-
}
|
|
461
|
-
catch (err) {
|
|
462
|
-
// 注册表损坏:记录警告日志便于排查(不存在属正常首次启动,损坏需排查)
|
|
463
|
-
logger.warn({ path: this.registryPath, err: toError(err).message }, '项目注册表解析失败,返回空列表');
|
|
464
|
-
return [];
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* 写入项目注册表
|
|
469
|
-
*/
|
|
470
|
-
writeRegistry(entries) {
|
|
471
|
-
// 确保目录存在
|
|
472
|
-
const dir = this.registryPath.replace(/[/\\][^/\\]+$/, '');
|
|
473
|
-
mkdirSync(dir, { recursive: true });
|
|
474
|
-
writeFileSync(this.registryPath, JSON.stringify(entries, null, 2), 'utf-8');
|
|
475
|
-
}
|
|
476
295
|
}
|
|
477
296
|
//# sourceMappingURL=projectManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectManager.js","sourceRoot":"","sources":["../../src/memory/projectManager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"projectManager.js","sourceRoot":"","sources":["../../src/memory/projectManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAyDtD,2DAA2D;AAE3D;;;;;;;;;;GAUG;AACH,MAAM,OAAO,cAAc;IACzB,kCAAkC;IACjB,YAAY,CAAS;IACtC,iCAAiC;IACzB,UAAU,GAA0B,IAAI,CAAC;IACjD,gBAAgB;IACR,kBAAkB,GAAkB,IAAI,CAAC;IACjD,+CAA+C;IACvC,eAAe,CAAwB;IAC/C,sCAAsC;IACrB,mBAAmB,CAKjB;IACnB,gCAAgC;IACf,QAAQ,CAAkB;IAC3C,iCAAiC;IAChB,WAAW,CAAc;IAE1C,YAAY,OAA8B;QACxC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC;QACvE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QAC/B,iCAAiC;QACjC,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QACjF,yBAAyB;QACzB,IAAI,CAAC,eAAe,GAAG,OAAO,IAAI,IAAI,CAAC;QACvC,wBAAwB;QACxB,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,mBAAmB;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IACvC,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,oBAAoB;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEpD,gBAAgB;YAChB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACN,yCAAyC;gBACzC,mCAAmC;gBACnC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,+CAA+C,CAAC,CAAC;gBACpF,IAAI,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,WAAW,CACf,WAAmB,EACnB,WAAoB,EACpB,SAAkB;QAElB,kCAAkC;QAClC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;QAED,4CAA4C;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;QAEtC,oCAAoC;QACpC,IAAI,CAAC;YACH,qBAAqB;YACrB,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACzE,SAAS,EACT,SAAS,CACV,CAAC;YAEF,gBAAgB;YAChB,OAAO,IAAI,CAAC,mBAAmB,CAC7B,WAAW,EACX,WAAW,EACX,SAAS,EACT,KAAK,EACL,gBAAgB,EAChB,UAAU,EACV,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oCAAoC;YACpC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,UAAmB,EAAE,EAAE;gBAC7D,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,SAAS,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC/B,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,gBAAgB,CAC5B,SAAiB,EACjB,SAAkB;QAMlB,8BAA8B;QAC9B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAEpD,iBAAiB;QACjB,MAAM,UAAU,GAAe,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAErE,+DAA+D;QAC/D,MAAM,gBAAgB,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,IAAI,YAAY,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,cAAc,EAAE,CAAC;QAC3D,UAAU,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC;QAC1C,UAAU,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC;QAC5C,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;QAEhD,wEAAwE;QACxE,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,eAAe,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,cAAc,EAAE,CAAC;YACzD,UAAU,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC;YACzC,UAAU,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC;YAC3C,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,mBAAmB,CACzB,WAAmB,EACnB,WAA+B,EAC/B,SAAiB,EACjB,KAAqB,EACrB,gBAA2B,EAC3B,UAAsB,EACtB,SAA6B;QAE7B,6EAA6E;QAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,iBAAiB,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC;QAEhD,iDAAiD;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB;YACvC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC;YAChF,CAAC,CAAC,IAAI,CAAC;QAET,8BAA8B;QAC9B,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC1E,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAE1C,MAAM,CAAC,IAAI,CACT;YACE,WAAW;YACX,WAAW,EAAE,IAAI;YACjB,SAAS;YACT,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,cAAc,EAAE,iBAAiB,CAAC,MAAM;SACzC,EACD,SAAS,CACV,CAAC;QAEF,OAAO;YACL,WAAW;YACX,WAAW,EAAE,IAAI;YACjB,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;YAC5C,SAAS,EAAE,gBAAgB;YAC3B,KAAK;YACL,QAAQ;YACR,iBAAiB;YACjB,UAAU;SACX,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY;QAChB,6DAA6D;QAC7D,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;YAC5B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,WAAmB,EAAE,IAAY;QAC/C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB,CAAC,WAAmB;QACnC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACK,gBAAgB,CAAC,WAAmB;QAC1C,OAAO,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 项目注册表条目
|
|
3
|
+
*/
|
|
4
|
+
export interface ProjectEntry {
|
|
5
|
+
/** 项目根目录的绝对路径 */
|
|
6
|
+
path: string;
|
|
7
|
+
/** 项目名称(用户自定义或目录名) */
|
|
8
|
+
name: string;
|
|
9
|
+
/** 最后打开时间 */
|
|
10
|
+
lastOpened: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 项目注册表
|
|
14
|
+
*
|
|
15
|
+
* 管理 projects.json 文件的读写和条目维护。
|
|
16
|
+
* Windows 文件系统不区分大小写,路径大小写不同视为同一项目。
|
|
17
|
+
*/
|
|
18
|
+
export declare class ProjectRegistry {
|
|
19
|
+
private readonly registryPath;
|
|
20
|
+
/**
|
|
21
|
+
* @param registryPath - 注册表文件绝对路径(projects.json)
|
|
22
|
+
*/
|
|
23
|
+
constructor(registryPath: string);
|
|
24
|
+
/**
|
|
25
|
+
* 列出已注册的项目(同步读取,契约要求 getter 风格)
|
|
26
|
+
*/
|
|
27
|
+
get list(): ProjectEntry[];
|
|
28
|
+
/**
|
|
29
|
+
* 注册项目到注册表
|
|
30
|
+
*
|
|
31
|
+
* Windows 文件系统不区分大小写,路径大小写不同视为同一项目(更新而非新增)。
|
|
32
|
+
*
|
|
33
|
+
* @param projectPath - 项目根目录绝对路径
|
|
34
|
+
* @param name - 项目名称
|
|
35
|
+
*/
|
|
36
|
+
register(projectPath: string, name: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* 从注册表移除项目
|
|
39
|
+
*
|
|
40
|
+
* @param projectPath - 项目根目录绝对路径
|
|
41
|
+
*/
|
|
42
|
+
unregister(projectPath: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* 从项目路径推断项目名称(取路径最后一段目录名)
|
|
45
|
+
*
|
|
46
|
+
* @param projectPath - 项目根目录绝对路径
|
|
47
|
+
* @returns 项目名称(目录名,无法推断时返回 'unnamed')
|
|
48
|
+
*/
|
|
49
|
+
static inferProjectName(projectPath: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* 读取项目注册表
|
|
52
|
+
*
|
|
53
|
+
* 同步读取:list getter 契约要求同步返回,注册表操作低频,同步 I/O 影响可控。
|
|
54
|
+
* 损坏时返回空数组并记录警告日志,避免静默吞错掩盖磁盘故障。
|
|
55
|
+
*/
|
|
56
|
+
private read;
|
|
57
|
+
/**
|
|
58
|
+
* 写入项目注册表
|
|
59
|
+
*/
|
|
60
|
+
private write;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=projectRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectRegistry.d.ts","sourceRoot":"","sources":["../../src/memory/projectRegistry.ts"],"names":[],"mappings":"AA4BA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAkCD;;;;;GAKG;AACH,qBAAa,eAAe;IAId,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHzC;;OAEG;gBAC0B,YAAY,EAAE,MAAM;IAEjD;;OAEG;IACH,IAAI,IAAI,IAAI,YAAY,EAAE,CAEzB;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAsBjD;;;;OAIG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IASrC;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAKpD;;;;;OAKG;IACH,OAAO,CAAC,IAAI;IA6BZ;;OAEG;IACH,OAAO,CAAC,KAAK;CAMd"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 项目注册表 — 多项目注册信息持久化
|
|
3
|
+
*
|
|
4
|
+
* 从 ProjectManager 拆分出来,专职管理 projects.json 注册表:
|
|
5
|
+
* - 读写项目注册表(~/.memora/projects.json 或宿主指定 registryDir)
|
|
6
|
+
* - 注册/注销项目条目(Windows 大小写不敏感去重)
|
|
7
|
+
* - 从路径推断项目名称
|
|
8
|
+
* - 不可信磁盘 JSON 的运行时类型校验(QC-24,替代 `as` 类型断言)
|
|
9
|
+
*
|
|
10
|
+
* 设计原则:
|
|
11
|
+
* - 纯文件系统操作,无锁机制(锁由 LockManager 负责)
|
|
12
|
+
* - 同步 I/O(list getter 契约要求同步返回;注册表操作低频,影响可控)
|
|
13
|
+
* - 损坏降级:解析失败返回空列表 + 警告日志,不抛异常
|
|
14
|
+
*
|
|
15
|
+
* 与 ProjectManager 的分工(1.0 接口稳定化):
|
|
16
|
+
* - ProjectRegistry:注册表读写 + 条目管理 + 名称推断
|
|
17
|
+
* - ProjectManager:项目生命周期编排(加锁 + 资源加载 + 上下文构建)
|
|
18
|
+
*
|
|
19
|
+
* 详见 ADR-008 · 目录结构按"职责分层"
|
|
20
|
+
*/
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
22
|
+
import { logger } from '../logging/logger.js';
|
|
23
|
+
import { toError } from '../utils/toError.js';
|
|
24
|
+
import { nowIso } from '../utils/time.js';
|
|
25
|
+
import { isPlainObject } from '../utils/objects.js';
|
|
26
|
+
// ─── 类型守卫(QC-24,对不可信磁盘 JSON 运行时校验) ─────
|
|
27
|
+
/**
|
|
28
|
+
* 判断值是否为 ProjectEntry(项目注册表条目)
|
|
29
|
+
*
|
|
30
|
+
* @param value 待校验的值
|
|
31
|
+
* @returns true 表示符合 ProjectEntry 结构
|
|
32
|
+
*/
|
|
33
|
+
function isProjectEntry(value) {
|
|
34
|
+
if (!isPlainObject(value))
|
|
35
|
+
return false;
|
|
36
|
+
return (typeof value['path'] === 'string' &&
|
|
37
|
+
typeof value['name'] === 'string' &&
|
|
38
|
+
typeof value['lastOpened'] === 'string');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 判断值是否为 ProjectEntry 数组
|
|
42
|
+
*
|
|
43
|
+
* 过滤掉不符合结构的条目,仅保留合法条目
|
|
44
|
+
*
|
|
45
|
+
* @param value 待校验的值
|
|
46
|
+
* @returns 解析后的合法条目数组(损坏时返回空数组)
|
|
47
|
+
*/
|
|
48
|
+
function asProjectEntryArray(value) {
|
|
49
|
+
if (!Array.isArray(value))
|
|
50
|
+
return [];
|
|
51
|
+
return value.filter(isProjectEntry);
|
|
52
|
+
}
|
|
53
|
+
// ─── 类 ──────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* 项目注册表
|
|
56
|
+
*
|
|
57
|
+
* 管理 projects.json 文件的读写和条目维护。
|
|
58
|
+
* Windows 文件系统不区分大小写,路径大小写不同视为同一项目。
|
|
59
|
+
*/
|
|
60
|
+
export class ProjectRegistry {
|
|
61
|
+
registryPath;
|
|
62
|
+
/**
|
|
63
|
+
* @param registryPath - 注册表文件绝对路径(projects.json)
|
|
64
|
+
*/
|
|
65
|
+
constructor(registryPath) {
|
|
66
|
+
this.registryPath = registryPath;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 列出已注册的项目(同步读取,契约要求 getter 风格)
|
|
70
|
+
*/
|
|
71
|
+
get list() {
|
|
72
|
+
return this.read();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 注册项目到注册表
|
|
76
|
+
*
|
|
77
|
+
* Windows 文件系统不区分大小写,路径大小写不同视为同一项目(更新而非新增)。
|
|
78
|
+
*
|
|
79
|
+
* @param projectPath - 项目根目录绝对路径
|
|
80
|
+
* @param name - 项目名称
|
|
81
|
+
*/
|
|
82
|
+
register(projectPath, name) {
|
|
83
|
+
const registry = this.read();
|
|
84
|
+
// Windows 文件系统不区分大小写,路径大小写不同视为同一项目
|
|
85
|
+
const existing = registry.findIndex((e) => e.path.toLowerCase() === projectPath.toLowerCase());
|
|
86
|
+
const entry = {
|
|
87
|
+
path: projectPath,
|
|
88
|
+
name,
|
|
89
|
+
lastOpened: nowIso(),
|
|
90
|
+
};
|
|
91
|
+
if (existing >= 0) {
|
|
92
|
+
registry[existing] = entry;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
registry.push(entry);
|
|
96
|
+
}
|
|
97
|
+
this.write(registry);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 从注册表移除项目
|
|
101
|
+
*
|
|
102
|
+
* @param projectPath - 项目根目录绝对路径
|
|
103
|
+
*/
|
|
104
|
+
unregister(projectPath) {
|
|
105
|
+
const registry = this.read();
|
|
106
|
+
// Windows 文件系统不区分大小写,大小写不同视为同一项目
|
|
107
|
+
const filtered = registry.filter((e) => e.path.toLowerCase() !== projectPath.toLowerCase());
|
|
108
|
+
this.write(filtered);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 从项目路径推断项目名称(取路径最后一段目录名)
|
|
112
|
+
*
|
|
113
|
+
* @param projectPath - 项目根目录绝对路径
|
|
114
|
+
* @returns 项目名称(目录名,无法推断时返回 'unnamed')
|
|
115
|
+
*/
|
|
116
|
+
static inferProjectName(projectPath) {
|
|
117
|
+
const parts = projectPath.replace(/[/\\]+$/, '').split(/[/\\]/);
|
|
118
|
+
return parts[parts.length - 1] || 'unnamed';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 读取项目注册表
|
|
122
|
+
*
|
|
123
|
+
* 同步读取:list getter 契约要求同步返回,注册表操作低频,同步 I/O 影响可控。
|
|
124
|
+
* 损坏时返回空数组并记录警告日志,避免静默吞错掩盖磁盘故障。
|
|
125
|
+
*/
|
|
126
|
+
read() {
|
|
127
|
+
if (!existsSync(this.registryPath)) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const raw = readFileSync(this.registryPath, 'utf-8');
|
|
132
|
+
// QC-24 使用类型守卫校验 JSON.parse 结果,替代 `as ProjectEntry[]` 类型断言
|
|
133
|
+
// 过滤掉不符合结构的条目,仅保留合法条目
|
|
134
|
+
const parsed = JSON.parse(raw);
|
|
135
|
+
const entries = asProjectEntryArray(parsed);
|
|
136
|
+
if (entries.length === 0 && Array.isArray(parsed) && parsed.length > 0) {
|
|
137
|
+
// 数组存在但所有条目都不合法,记录警告
|
|
138
|
+
logger.warn({ path: this.registryPath, totalEntries: parsed.length }, '项目注册表所有条目结构不合法,返回空列表');
|
|
139
|
+
}
|
|
140
|
+
return entries;
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
// 注册表损坏:记录警告日志便于排查(不存在属正常首次启动,损坏需排查)
|
|
144
|
+
logger.warn({ path: this.registryPath, err: toError(err).message }, '项目注册表解析失败,返回空列表');
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 写入项目注册表
|
|
150
|
+
*/
|
|
151
|
+
write(entries) {
|
|
152
|
+
// 确保目录存在
|
|
153
|
+
const dir = this.registryPath.replace(/[/\\][^/\\]+$/, '');
|
|
154
|
+
mkdirSync(dir, { recursive: true });
|
|
155
|
+
writeFileSync(this.registryPath, JSON.stringify(entries, null, 2), 'utf-8');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=projectRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectRegistry.js","sourceRoot":"","sources":["../../src/memory/projectRegistry.ts"],"names":[],"mappings":"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"}
|