@zooique/memora 0.1.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/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/agent/agent.d.ts +343 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +893 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/assembler.d.ts +77 -0
- package/dist/agent/assembler.d.ts.map +1 -0
- package/dist/agent/assembler.js +115 -0
- package/dist/agent/assembler.js.map +1 -0
- package/dist/agent/builtinToolHandlers.d.ts +96 -0
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -0
- package/dist/agent/builtinToolHandlers.js +388 -0
- package/dist/agent/builtinToolHandlers.js.map +1 -0
- package/dist/agent/builtinTools.d.ts +35 -0
- package/dist/agent/builtinTools.d.ts.map +1 -0
- package/dist/agent/builtinTools.js +75 -0
- package/dist/agent/builtinTools.js.map +1 -0
- package/dist/agent/constants.d.ts +67 -0
- package/dist/agent/constants.d.ts.map +1 -0
- package/dist/agent/constants.js +67 -0
- package/dist/agent/constants.js.map +1 -0
- package/dist/agent/contextManager.d.ts +130 -0
- package/dist/agent/contextManager.d.ts.map +1 -0
- package/dist/agent/contextManager.js +287 -0
- package/dist/agent/contextManager.js.map +1 -0
- package/dist/agent/loop.d.ts +288 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +756 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/managers/autoConfigRefiner.d.ts +39 -0
- package/dist/agent/managers/autoConfigRefiner.d.ts.map +1 -0
- package/dist/agent/managers/autoConfigRefiner.js +150 -0
- package/dist/agent/managers/autoConfigRefiner.js.map +1 -0
- package/dist/agent/managers/configManager.d.ts +114 -0
- package/dist/agent/managers/configManager.d.ts.map +1 -0
- package/dist/agent/managers/configManager.js +186 -0
- package/dist/agent/managers/configManager.js.map +1 -0
- package/dist/agent/managers/insightExtractor.d.ts +141 -0
- package/dist/agent/managers/insightExtractor.d.ts.map +1 -0
- package/dist/agent/managers/insightExtractor.js +420 -0
- package/dist/agent/managers/insightExtractor.js.map +1 -0
- package/dist/agent/managers/memoryAdvisor.d.ts +96 -0
- package/dist/agent/managers/memoryAdvisor.d.ts.map +1 -0
- package/dist/agent/managers/memoryAdvisor.js +198 -0
- package/dist/agent/managers/memoryAdvisor.js.map +1 -0
- package/dist/agent/managers/memoryInspector.d.ts +231 -0
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -0
- package/dist/agent/managers/memoryInspector.js +327 -0
- package/dist/agent/managers/memoryInspector.js.map +1 -0
- package/dist/agent/managers/sessionManager.d.ts +89 -0
- package/dist/agent/managers/sessionManager.d.ts.map +1 -0
- package/dist/agent/managers/sessionManager.js +178 -0
- package/dist/agent/managers/sessionManager.js.map +1 -0
- package/dist/agent/managers/userFactExtractor.d.ts +25 -0
- package/dist/agent/managers/userFactExtractor.d.ts.map +1 -0
- package/dist/agent/managers/userFactExtractor.js +81 -0
- package/dist/agent/managers/userFactExtractor.js.map +1 -0
- package/dist/agent/managers/workProjection.d.ts +117 -0
- package/dist/agent/managers/workProjection.d.ts.map +1 -0
- package/dist/agent/managers/workProjection.js +290 -0
- package/dist/agent/managers/workProjection.js.map +1 -0
- package/dist/agent/messageHistory.d.ts +157 -0
- package/dist/agent/messageHistory.d.ts.map +1 -0
- package/dist/agent/messageHistory.js +288 -0
- package/dist/agent/messageHistory.js.map +1 -0
- package/dist/agent/toolExecutor.d.ts +137 -0
- package/dist/agent/toolExecutor.d.ts.map +1 -0
- package/dist/agent/toolExecutor.js +209 -0
- package/dist/agent/toolExecutor.js.map +1 -0
- package/dist/agent/tracer.d.ts +122 -0
- package/dist/agent/tracer.d.ts.map +1 -0
- package/dist/agent/tracer.js +64 -0
- package/dist/agent/tracer.js.map +1 -0
- package/dist/agent/types.d.ts +98 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +19 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/config/loader.d.ts +229 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +194 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/eval/evalTypes.d.ts +118 -0
- package/dist/eval/evalTypes.d.ts.map +1 -0
- package/dist/eval/evalTypes.js +102 -0
- package/dist/eval/evalTypes.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/embedding.d.ts +62 -0
- package/dist/llm/embedding.d.ts.map +1 -0
- package/dist/llm/embedding.js +162 -0
- package/dist/llm/embedding.js.map +1 -0
- package/dist/llm/factory.d.ts +39 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +108 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/openaiCompatible.d.ts +63 -0
- package/dist/llm/openaiCompatible.d.ts.map +1 -0
- package/dist/llm/openaiCompatible.js +340 -0
- package/dist/llm/openaiCompatible.js.map +1 -0
- package/dist/llm/provider.d.ts +91 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +14 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +25 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +7 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/logging/logger.d.ts +39 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +279 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/loggerInterface.d.ts +33 -0
- package/dist/logging/loggerInterface.d.ts.map +1 -0
- package/dist/logging/loggerInterface.js +2 -0
- package/dist/logging/loggerInterface.js.map +1 -0
- package/dist/memory/inMemoryRelationStore.d.ts +51 -0
- package/dist/memory/inMemoryRelationStore.d.ts.map +1 -0
- package/dist/memory/inMemoryRelationStore.js +65 -0
- package/dist/memory/inMemoryRelationStore.js.map +1 -0
- package/dist/memory/inMemoryStorage.d.ts +97 -0
- package/dist/memory/inMemoryStorage.d.ts.map +1 -0
- package/dist/memory/inMemoryStorage.js +177 -0
- package/dist/memory/inMemoryStorage.js.map +1 -0
- package/dist/memory/loader.d.ts +49 -0
- package/dist/memory/loader.d.ts.map +1 -0
- package/dist/memory/loader.js +93 -0
- package/dist/memory/loader.js.map +1 -0
- package/dist/memory/projectManager.d.ts +182 -0
- package/dist/memory/projectManager.d.ts.map +1 -0
- package/dist/memory/projectManager.js +441 -0
- package/dist/memory/projectManager.js.map +1 -0
- package/dist/memory/recall.d.ts +77 -0
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/recall.js +147 -0
- package/dist/memory/recall.js.map +1 -0
- package/dist/memory/relationStore.d.ts +78 -0
- package/dist/memory/relationStore.d.ts.map +1 -0
- package/dist/memory/relationStore.js +2 -0
- package/dist/memory/relationStore.js.map +1 -0
- package/dist/memory/sessionStore.d.ts +84 -0
- package/dist/memory/sessionStore.d.ts.map +1 -0
- package/dist/memory/sessionStore.js +2 -0
- package/dist/memory/sessionStore.js.map +1 -0
- package/dist/memory/storageInterface.d.ts +107 -0
- package/dist/memory/storageInterface.d.ts.map +1 -0
- package/dist/memory/storageInterface.js +2 -0
- package/dist/memory/storageInterface.js.map +1 -0
- package/dist/memory/store.d.ts +50 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +160 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.d.ts +189 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +230 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/userProfile.d.ts +156 -0
- package/dist/memory/userProfile.d.ts.map +1 -0
- package/dist/memory/userProfile.js +315 -0
- package/dist/memory/userProfile.js.map +1 -0
- package/dist/memory/vectorStore.d.ts +75 -0
- package/dist/memory/vectorStore.d.ts.map +1 -0
- package/dist/memory/vectorStore.js +144 -0
- package/dist/memory/vectorStore.js.map +1 -0
- package/dist/persona/personaManager.d.ts +121 -0
- package/dist/persona/personaManager.d.ts.map +1 -0
- package/dist/persona/personaManager.js +349 -0
- package/dist/persona/personaManager.js.map +1 -0
- package/dist/persona/types.d.ts +32 -0
- package/dist/persona/types.d.ts.map +1 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/types.js.map +1 -0
- package/dist/security/pathGuard.d.ts +121 -0
- package/dist/security/pathGuard.d.ts.map +1 -0
- package/dist/security/pathGuard.js +276 -0
- package/dist/security/pathGuard.js.map +1 -0
- package/dist/skill/skillManager.d.ts +82 -0
- package/dist/skill/skillManager.d.ts.map +1 -0
- package/dist/skill/skillManager.js +198 -0
- package/dist/skill/skillManager.js.map +1 -0
- package/dist/skill/types.d.ts +28 -0
- package/dist/skill/types.d.ts.map +1 -0
- package/dist/skill/types.js +5 -0
- package/dist/skill/types.js.map +1 -0
- package/dist/utils/errors.d.ts +86 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +143 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/eventEmitter.d.ts +87 -0
- package/dist/utils/eventEmitter.d.ts.map +1 -0
- package/dist/utils/eventEmitter.js +79 -0
- package/dist/utils/eventEmitter.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +24 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +44 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/json.d.ts +20 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +65 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/loggerHolder.d.ts +37 -0
- package/dist/utils/loggerHolder.d.ts.map +1 -0
- package/dist/utils/loggerHolder.js +49 -0
- package/dist/utils/loggerHolder.js.map +1 -0
- package/dist/utils/math.d.ts +5 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +19 -0
- package/dist/utils/math.js.map +1 -0
- package/dist/utils/path.d.ts +28 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +33 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/safeTimer.d.ts +26 -0
- package/dist/utils/safeTimer.d.ts.map +1 -0
- package/dist/utils/safeTimer.js +49 -0
- package/dist/utils/safeTimer.js.map +1 -0
- package/dist/utils/scanner.d.ts +54 -0
- package/dist/utils/scanner.d.ts.map +1 -0
- package/dist/utils/scanner.js +115 -0
- package/dist/utils/scanner.js.map +1 -0
- package/dist/utils/segmenter.d.ts +30 -0
- package/dist/utils/segmenter.d.ts.map +1 -0
- package/dist/utils/segmenter.js +80 -0
- package/dist/utils/segmenter.js.map +1 -0
- package/dist/utils/strings.d.ts +18 -0
- package/dist/utils/strings.d.ts.map +1 -0
- package/dist/utils/strings.js +25 -0
- package/dist/utils/strings.js.map +1 -0
- package/dist/utils/time.d.ts +23 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +31 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/toError.d.ts +13 -0
- package/dist/utils/toError.d.ts.map +1 -0
- package/dist/utils/toError.js +22 -0
- package/dist/utils/toError.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter 通用解析/序列化工具
|
|
3
|
+
*
|
|
4
|
+
* 为 memory/store.ts、persona/personaManager.ts、skill/skillManager.ts 提供共享的 frontmatter 处理
|
|
5
|
+
* 详见 ADR-004 · 记忆统一为"类型 + 永久性标记"模型
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 解析 frontmatter 块为键值对
|
|
9
|
+
*
|
|
10
|
+
* @param raw 完整 markdown 内容(含 `---` 包围的 frontmatter)
|
|
11
|
+
* @returns `{ frontmatter, body }`——frontmatter 为键值对对象,body 为 frontmatter 之后的内容
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseFrontmatter(raw: string): {
|
|
14
|
+
frontmatter: Record<string, string>;
|
|
15
|
+
body: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* 序列化 frontmatter 为 YAML 块内容(不含 `---` 包围符)
|
|
19
|
+
*
|
|
20
|
+
* @param frontmatter 键值对对象
|
|
21
|
+
* @returns 可拼接进 `---\n${result}\n---\n${body}` 的字符串
|
|
22
|
+
*/
|
|
23
|
+
export declare function serializeFrontmatter(frontmatter: Record<string, string>): string;
|
|
24
|
+
//# sourceMappingURL=frontmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAC7C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd,CAkBA;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAKhF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter 通用解析/序列化工具
|
|
3
|
+
*
|
|
4
|
+
* 为 memory/store.ts、persona/personaManager.ts、skill/skillManager.ts 提供共享的 frontmatter 处理
|
|
5
|
+
* 详见 ADR-004 · 记忆统一为"类型 + 永久性标记"模型
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 解析 frontmatter 块为键值对
|
|
9
|
+
*
|
|
10
|
+
* @param raw 完整 markdown 内容(含 `---` 包围的 frontmatter)
|
|
11
|
+
* @returns `{ frontmatter, body }`——frontmatter 为键值对对象,body 为 frontmatter 之后的内容
|
|
12
|
+
*/
|
|
13
|
+
export function parseFrontmatter(raw) {
|
|
14
|
+
const normalized = raw.replace(/\r\n/g, '\n');
|
|
15
|
+
const match = normalized.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
16
|
+
if (!match || !match[1] || !match[2]) {
|
|
17
|
+
return { frontmatter: {}, body: raw };
|
|
18
|
+
}
|
|
19
|
+
const [, fmBlock, body] = match;
|
|
20
|
+
const frontmatter = {};
|
|
21
|
+
for (const line of fmBlock.split('\n')) {
|
|
22
|
+
const idx = line.indexOf(':');
|
|
23
|
+
if (idx < 0)
|
|
24
|
+
continue;
|
|
25
|
+
const k = line.slice(0, idx).trim();
|
|
26
|
+
const v = line.slice(idx + 1).trim();
|
|
27
|
+
if (k && v)
|
|
28
|
+
frontmatter[k] = v;
|
|
29
|
+
}
|
|
30
|
+
return { frontmatter, body };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 序列化 frontmatter 为 YAML 块内容(不含 `---` 包围符)
|
|
34
|
+
*
|
|
35
|
+
* @param frontmatter 键值对对象
|
|
36
|
+
* @returns 可拼接进 `---\n${result}\n---\n${body}` 的字符串
|
|
37
|
+
*/
|
|
38
|
+
export function serializeFrontmatter(frontmatter) {
|
|
39
|
+
return Object.entries(frontmatter)
|
|
40
|
+
.filter(([, v]) => v !== undefined && v !== null)
|
|
41
|
+
.map(([k, v]) => `${k}: ${v}`)
|
|
42
|
+
.join('\n');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAI1C,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACpE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;IAChC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,GAAG,CAAC;YAAE,SAAS;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC;YAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmC;IACtE,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;SAC7B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON 工具函数
|
|
3
|
+
*
|
|
4
|
+
* 从 InsightExtractor 和 WorkProjectionManager 提取的公共 JSON 解析函数,
|
|
5
|
+
* 统一 LLM 输出的 JSON 解析策略。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 从 LLM 输出中解析 JSON
|
|
9
|
+
*
|
|
10
|
+
* 解析策略(逐级回退):
|
|
11
|
+
* 1. 直接 JSON.parse
|
|
12
|
+
* 2. 剥离 markdown 代码块标记后重试
|
|
13
|
+
* 3. 修复常见错误(单引号、尾逗号)后重试
|
|
14
|
+
* 4. 正则提取首个 JSON 对象
|
|
15
|
+
*
|
|
16
|
+
* @param raw - LLM 原始输出文本
|
|
17
|
+
* @returns 解析结果,解析失败返回 null
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseLlmJson<T = unknown>(raw: string): T | null;
|
|
20
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/utils/json.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CA6C/D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON 工具函数
|
|
3
|
+
*
|
|
4
|
+
* 从 InsightExtractor 和 WorkProjectionManager 提取的公共 JSON 解析函数,
|
|
5
|
+
* 统一 LLM 输出的 JSON 解析策略。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 从 LLM 输出中解析 JSON
|
|
9
|
+
*
|
|
10
|
+
* 解析策略(逐级回退):
|
|
11
|
+
* 1. 直接 JSON.parse
|
|
12
|
+
* 2. 剥离 markdown 代码块标记后重试
|
|
13
|
+
* 3. 修复常见错误(单引号、尾逗号)后重试
|
|
14
|
+
* 4. 正则提取首个 JSON 对象
|
|
15
|
+
*
|
|
16
|
+
* @param raw - LLM 原始输出文本
|
|
17
|
+
* @returns 解析结果,解析失败返回 null
|
|
18
|
+
*/
|
|
19
|
+
export function parseLlmJson(raw) {
|
|
20
|
+
const trimmed = raw.trim();
|
|
21
|
+
if (!trimmed || trimmed === 'null')
|
|
22
|
+
return null;
|
|
23
|
+
// 1. 直接解析
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(trimmed);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// 继续
|
|
29
|
+
}
|
|
30
|
+
// 2. 剥离 markdown 代码块标记(```json ... ```)
|
|
31
|
+
const codeBlockMatch = trimmed.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
|
|
32
|
+
if (codeBlockMatch?.[1]) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(codeBlockMatch[1].trim());
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// 继续
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 3. 修复常见错误后重试
|
|
41
|
+
// 只替换作为 JSON key/value 定界符的单引号,不替换字符串内容中的单引号
|
|
42
|
+
// 匹配模式:单引号紧跟在 {, [, :, , 后面(定界符位置),或紧靠在 }, ], ,, : 前面
|
|
43
|
+
const fixed = trimmed
|
|
44
|
+
.replace(/(?<=[{\[:,\s])'|'(?=[}\]:,\s])/g, '"')
|
|
45
|
+
.replace(/,\s*}/g, '}')
|
|
46
|
+
.replace(/,\s*]/g, ']');
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(fixed);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// 继续
|
|
52
|
+
}
|
|
53
|
+
// 4. 正则提取首个 JSON 对象
|
|
54
|
+
const objectMatch = trimmed.match(/\{[\s\S]*\}/);
|
|
55
|
+
if (objectMatch) {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(objectMatch[0]);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// 放弃
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/utils/json.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAc,GAAW;IACnD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAEhD,UAAU;IACV,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,KAAK;IACP,CAAC;IAED,wCAAwC;IACxC,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC9E,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAM,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,KAAK;QACP,CAAC;IACH,CAAC;IAED,eAAe;IACf,6CAA6C;IAC7C,sDAAsD;IACtD,MAAM,KAAK,GAAG,OAAO;SAClB,OAAO,CAAC,iCAAiC,EAAE,GAAG,CAAC;SAC/C,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,KAAK;IACP,CAAC;IAED,oBAAoB;IACpB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACjD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAM,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,KAAK;QACP,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* utils 层日志持有器 — 解耦 utils → logging 的运行时依赖
|
|
3
|
+
*
|
|
4
|
+
* 设计动机:
|
|
5
|
+
* utils 是最底层工具层,不应运行时依赖 logging/(业务层)。
|
|
6
|
+
* 但 utils 中的错误日志、事件容错、扫描诊断需要日志能力。
|
|
7
|
+
* 通过 holder 模式,utils 运行时只依赖此模块(同层),
|
|
8
|
+
* 实际 logger 实例由 logging/ 在模块加载时注入。
|
|
9
|
+
*
|
|
10
|
+
* 依赖方向:
|
|
11
|
+
* - utils/* → utils/loggerHolder.ts(同层,运行时)
|
|
12
|
+
* - utils/loggerHolder.ts → logging/loggerInterface.ts(type-only,编译时擦除)
|
|
13
|
+
* - logging/logger.ts → utils/loggerHolder.ts(运行时,桥接注入)
|
|
14
|
+
*
|
|
15
|
+
* 使用方式:
|
|
16
|
+
* // utils 内部使用
|
|
17
|
+
* import { getLogger } from './loggerHolder.js';
|
|
18
|
+
* getLogger().warn({ dir }, '扫描目录失败');
|
|
19
|
+
*
|
|
20
|
+
* // logging 层桥接(自动执行,无需手动调用)
|
|
21
|
+
* // logging/logger.ts 模块加载时自动调用 setLogger(logger)
|
|
22
|
+
*/
|
|
23
|
+
import type { ILogger } from '../logging/loggerInterface.js';
|
|
24
|
+
/**
|
|
25
|
+
* 获取当前 logger 实例
|
|
26
|
+
*
|
|
27
|
+
* utils 模块统一通过此函数获取 logger,而非直接 import logging/logger.ts。
|
|
28
|
+
* 在 logging/logger.ts 模块加载前,返回 noopLogger(不输出日志)。
|
|
29
|
+
*/
|
|
30
|
+
export declare function getLogger(): ILogger;
|
|
31
|
+
/**
|
|
32
|
+
* 注入 logger 实例(由 logging/logger.ts 自动调用)
|
|
33
|
+
*
|
|
34
|
+
* 传入 undefined 则恢复为 noopLogger。
|
|
35
|
+
*/
|
|
36
|
+
export declare function setLogger(logger: ILogger | undefined): void;
|
|
37
|
+
//# sourceMappingURL=loggerHolder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggerHolder.d.ts","sourceRoot":"","sources":["../../src/utils/loggerHolder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAa5D;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAE3D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* utils 层日志持有器 — 解耦 utils → logging 的运行时依赖
|
|
3
|
+
*
|
|
4
|
+
* 设计动机:
|
|
5
|
+
* utils 是最底层工具层,不应运行时依赖 logging/(业务层)。
|
|
6
|
+
* 但 utils 中的错误日志、事件容错、扫描诊断需要日志能力。
|
|
7
|
+
* 通过 holder 模式,utils 运行时只依赖此模块(同层),
|
|
8
|
+
* 实际 logger 实例由 logging/ 在模块加载时注入。
|
|
9
|
+
*
|
|
10
|
+
* 依赖方向:
|
|
11
|
+
* - utils/* → utils/loggerHolder.ts(同层,运行时)
|
|
12
|
+
* - utils/loggerHolder.ts → logging/loggerInterface.ts(type-only,编译时擦除)
|
|
13
|
+
* - logging/logger.ts → utils/loggerHolder.ts(运行时,桥接注入)
|
|
14
|
+
*
|
|
15
|
+
* 使用方式:
|
|
16
|
+
* // utils 内部使用
|
|
17
|
+
* import { getLogger } from './loggerHolder.js';
|
|
18
|
+
* getLogger().warn({ dir }, '扫描目录失败');
|
|
19
|
+
*
|
|
20
|
+
* // logging 层桥接(自动执行,无需手动调用)
|
|
21
|
+
* // logging/logger.ts 模块加载时自动调用 setLogger(logger)
|
|
22
|
+
*/
|
|
23
|
+
/** 空操作 logger — 默认实现,不输出任何日志 */
|
|
24
|
+
const noopLogger = {
|
|
25
|
+
debug: () => { },
|
|
26
|
+
info: () => { },
|
|
27
|
+
warn: () => { },
|
|
28
|
+
error: () => { },
|
|
29
|
+
};
|
|
30
|
+
/** 当前注入的 logger 实例(默认 noop,由 logging/logger.ts 桥接注入) */
|
|
31
|
+
let currentLogger = noopLogger;
|
|
32
|
+
/**
|
|
33
|
+
* 获取当前 logger 实例
|
|
34
|
+
*
|
|
35
|
+
* utils 模块统一通过此函数获取 logger,而非直接 import logging/logger.ts。
|
|
36
|
+
* 在 logging/logger.ts 模块加载前,返回 noopLogger(不输出日志)。
|
|
37
|
+
*/
|
|
38
|
+
export function getLogger() {
|
|
39
|
+
return currentLogger;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 注入 logger 实例(由 logging/logger.ts 自动调用)
|
|
43
|
+
*
|
|
44
|
+
* 传入 undefined 则恢复为 noopLogger。
|
|
45
|
+
*/
|
|
46
|
+
export function setLogger(logger) {
|
|
47
|
+
currentLogger = logger ?? noopLogger;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=loggerHolder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggerHolder.js","sourceRoot":"","sources":["../../src/utils/loggerHolder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,gCAAgC;AAChC,MAAM,UAAU,GAAY;IAC1B,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AAEF,wDAAwD;AACxD,IAAI,aAAa,GAAY,UAAU,CAAC;AAExC;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAA2B;IACnD,aAAa,GAAG,MAAM,IAAI,UAAU,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/utils/math.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAajE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数学工具函数
|
|
3
|
+
*/
|
|
4
|
+
export function cosineSimilarity(a, b) {
|
|
5
|
+
if (a.length !== b.length)
|
|
6
|
+
return 0;
|
|
7
|
+
let dot = 0;
|
|
8
|
+
let normA = 0;
|
|
9
|
+
let normB = 0;
|
|
10
|
+
for (let i = 0; i < a.length; i++) {
|
|
11
|
+
// QC-17 移除非空断言:循环条件保证索引有效,用 ?? 0 兜底(数学上 0 不影响点积)
|
|
12
|
+
dot += (a[i] ?? 0) * (b[i] ?? 0);
|
|
13
|
+
normA += (a[i] ?? 0) * (a[i] ?? 0);
|
|
14
|
+
normB += (b[i] ?? 0) * (b[i] ?? 0);
|
|
15
|
+
}
|
|
16
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
17
|
+
return denominator === 0 ? 0 : dot / denominator;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=math.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/utils/math.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAW,EAAE,CAAW;IACvD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACpC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,iDAAiD;QACjD,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,WAAW,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路径工具函数
|
|
3
|
+
*
|
|
4
|
+
* 从 workProjection.ts 提取的公共路径处理函数,
|
|
5
|
+
* 消除跨模块 `filePath.split(/[/\\]/).pop()` 内联重复。
|
|
6
|
+
* 跨平台兼容(同时处理 / 和 \ 分隔符)。
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 提取路径的 basename(最后一段)
|
|
10
|
+
*
|
|
11
|
+
* 跨平台兼容:同时处理 Unix `/` 和 Windows `\` 分隔符。
|
|
12
|
+
* 空路径或纯分隔符路径返回空字符串。
|
|
13
|
+
*
|
|
14
|
+
* @param filePath 文件路径
|
|
15
|
+
* @returns basename,如 "/a/b/c.txt" → "c.txt"
|
|
16
|
+
*/
|
|
17
|
+
export declare function basename(filePath: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* 展开路径中的 `~` 为用户家目录
|
|
20
|
+
*
|
|
21
|
+
* 仅处理开头的 `~`,不处理 `~otheruser` 等形式。
|
|
22
|
+
* 不含 `~` 的路径原样返回。
|
|
23
|
+
*
|
|
24
|
+
* @param p 可能包含 `~` 的路径字符串
|
|
25
|
+
* @returns 展开后的路径,如 "~/data" → "C:\\Users\\SJ\\data"
|
|
26
|
+
*/
|
|
27
|
+
export declare function expandHome(p: string): string;
|
|
28
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路径工具函数
|
|
3
|
+
*
|
|
4
|
+
* 从 workProjection.ts 提取的公共路径处理函数,
|
|
5
|
+
* 消除跨模块 `filePath.split(/[/\\]/).pop()` 内联重复。
|
|
6
|
+
* 跨平台兼容(同时处理 / 和 \ 分隔符)。
|
|
7
|
+
*/
|
|
8
|
+
import { homedir } from 'node:os';
|
|
9
|
+
/**
|
|
10
|
+
* 提取路径的 basename(最后一段)
|
|
11
|
+
*
|
|
12
|
+
* 跨平台兼容:同时处理 Unix `/` 和 Windows `\` 分隔符。
|
|
13
|
+
* 空路径或纯分隔符路径返回空字符串。
|
|
14
|
+
*
|
|
15
|
+
* @param filePath 文件路径
|
|
16
|
+
* @returns basename,如 "/a/b/c.txt" → "c.txt"
|
|
17
|
+
*/
|
|
18
|
+
export function basename(filePath) {
|
|
19
|
+
return filePath.split(/[/\\]/).pop() ?? '';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 展开路径中的 `~` 为用户家目录
|
|
23
|
+
*
|
|
24
|
+
* 仅处理开头的 `~`,不处理 `~otheruser` 等形式。
|
|
25
|
+
* 不含 `~` 的路径原样返回。
|
|
26
|
+
*
|
|
27
|
+
* @param p 可能包含 `~` 的路径字符串
|
|
28
|
+
* @returns 展开后的路径,如 "~/data" → "C:\\Users\\SJ\\data"
|
|
29
|
+
*/
|
|
30
|
+
export function expandHome(p) {
|
|
31
|
+
return p.replace(/^~/, homedir());
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 安全定时器工具 — 提供可追踪的生命周期管理
|
|
3
|
+
*
|
|
4
|
+
* 原生 setTimeout / setInterval 不跟踪定时器 ID,
|
|
5
|
+
* 如果忘记清理可能导致内存泄漏。本模块提供轻量包装,
|
|
6
|
+
* 统一管理定时器的创建和清理。
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 安全的 setTimeout 包装
|
|
10
|
+
* 返回的 timer ID 可用于 clearSafeTimeout 清理
|
|
11
|
+
*/
|
|
12
|
+
export declare function safeSetTimeout(callback: () => void, ms: number): ReturnType<typeof setTimeout>;
|
|
13
|
+
/**
|
|
14
|
+
* 安全的 setInterval 包装
|
|
15
|
+
* 返回的 timer ID 可用于 clearSafeInterval 清理
|
|
16
|
+
*/
|
|
17
|
+
export declare function safeSetInterval(callback: () => void, ms: number): ReturnType<typeof setInterval>;
|
|
18
|
+
/**
|
|
19
|
+
* 清理安全的 setTimeout
|
|
20
|
+
*/
|
|
21
|
+
export declare function clearSafeTimeout(id: ReturnType<typeof setTimeout> | null): void;
|
|
22
|
+
/**
|
|
23
|
+
* 清理安全的 setInterval
|
|
24
|
+
*/
|
|
25
|
+
export declare function clearSafeInterval(id: ReturnType<typeof setInterval> | null): void;
|
|
26
|
+
//# sourceMappingURL=safeTimer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeTimer.d.ts","sourceRoot":"","sources":["../../src/utils/safeTimer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,IAAI,EACpB,EAAE,EAAE,MAAM,GACT,UAAU,CAAC,OAAO,UAAU,CAAC,CAO/B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,IAAI,EACpB,EAAE,EAAE,MAAM,GACT,UAAU,CAAC,OAAO,WAAW,CAAC,CAIhC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,GAAG,IAAI,CAK/E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,IAAI,GAAG,IAAI,CAKjF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 安全定时器工具 — 提供可追踪的生命周期管理
|
|
3
|
+
*
|
|
4
|
+
* 原生 setTimeout / setInterval 不跟踪定时器 ID,
|
|
5
|
+
* 如果忘记清理可能导致内存泄漏。本模块提供轻量包装,
|
|
6
|
+
* 统一管理定时器的创建和清理。
|
|
7
|
+
*/
|
|
8
|
+
/** 定时器注册表,用于跟踪所有活跃定时器 */
|
|
9
|
+
const activeTimers = new Set();
|
|
10
|
+
/**
|
|
11
|
+
* 安全的 setTimeout 包装
|
|
12
|
+
* 返回的 timer ID 可用于 clearSafeTimeout 清理
|
|
13
|
+
*/
|
|
14
|
+
export function safeSetTimeout(callback, ms) {
|
|
15
|
+
const id = setTimeout(() => {
|
|
16
|
+
activeTimers.delete(id);
|
|
17
|
+
callback();
|
|
18
|
+
}, ms);
|
|
19
|
+
activeTimers.add(id);
|
|
20
|
+
return id;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 安全的 setInterval 包装
|
|
24
|
+
* 返回的 timer ID 可用于 clearSafeInterval 清理
|
|
25
|
+
*/
|
|
26
|
+
export function safeSetInterval(callback, ms) {
|
|
27
|
+
const id = setInterval(callback, ms);
|
|
28
|
+
activeTimers.add(id);
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 清理安全的 setTimeout
|
|
33
|
+
*/
|
|
34
|
+
export function clearSafeTimeout(id) {
|
|
35
|
+
if (id !== null) {
|
|
36
|
+
clearTimeout(id);
|
|
37
|
+
activeTimers.delete(id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 清理安全的 setInterval
|
|
42
|
+
*/
|
|
43
|
+
export function clearSafeInterval(id) {
|
|
44
|
+
if (id !== null) {
|
|
45
|
+
clearInterval(id);
|
|
46
|
+
activeTimers.delete(id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=safeTimer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeTimer.js","sourceRoot":"","sources":["../../src/utils/safeTimer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yBAAyB;AACzB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkE,CAAC;AAE/F;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAoB,EACpB,EAAU;IAEV,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE;QACzB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,QAAQ,EAAE,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAoB,EACpB,EAAU;IAEV,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACrC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAwC;IACvE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,YAAY,CAAC,EAAE,CAAC,CAAC;QACjB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAyC;IACzE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,aAAa,CAAC,EAAE,CAAC,CAAC;QAClB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown 目录扫描工具
|
|
3
|
+
*
|
|
4
|
+
* 从 PersonaManager / SkillManager 提取的公共目录扫描逻辑,
|
|
5
|
+
* 消除跨模块重复的"扫描 *.md → 解析 frontmatter → 提取字段"代码。
|
|
6
|
+
*
|
|
7
|
+
* 使用异步 I/O(与 FileStore / ToolExecutor 保持一致)。
|
|
8
|
+
*/
|
|
9
|
+
/** 扫描结果条目(通用 frontmatter 解析产物) */
|
|
10
|
+
export interface ScannedMarkdownEntry {
|
|
11
|
+
/** 名称(frontmatter name 字段或文件名去 .md) */
|
|
12
|
+
name: string;
|
|
13
|
+
/** frontmatter 原始键值对 */
|
|
14
|
+
frontmatter: Record<string, string>;
|
|
15
|
+
/** frontmatter 之后的正文 */
|
|
16
|
+
body: string;
|
|
17
|
+
/** 文件绝对路径 */
|
|
18
|
+
filePath: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 扫描目录下的 *.md 文件,解析 frontmatter
|
|
22
|
+
*
|
|
23
|
+
* 排除规则:
|
|
24
|
+
* - 文件名以 `.` 开头的隐藏文件
|
|
25
|
+
* - 文件名以 `_` 前缀的私有文件
|
|
26
|
+
* - README.md / CHANGELOG.md / LICENSE
|
|
27
|
+
*
|
|
28
|
+
* @param dir 目录路径
|
|
29
|
+
* @returns 解析后的条目列表
|
|
30
|
+
*/
|
|
31
|
+
export declare function scanMarkdownDir(dir: string): Promise<ScannedMarkdownEntry[]>;
|
|
32
|
+
/**
|
|
33
|
+
* 从 frontmatter 中解析逗号分隔的关键词列表
|
|
34
|
+
*
|
|
35
|
+
* @param fm frontmatter 键值对
|
|
36
|
+
* @param key 关键词字段名(默认 'keywords')
|
|
37
|
+
* @returns 关键词数组
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseKeywords(fm: Record<string, string>, key?: string): string[];
|
|
40
|
+
/**
|
|
41
|
+
* 从 frontmatter 中解析正则触发器
|
|
42
|
+
*
|
|
43
|
+
* 支持格式:/pattern/flags 或纯 pattern(默认 'i' flag)
|
|
44
|
+
*
|
|
45
|
+
* @param fm frontmatter 键值对
|
|
46
|
+
* @param key 触发器字段名(默认 'trigger')
|
|
47
|
+
* @returns 正则表达式,解析失败返回 undefined
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseTrigger(fm: Record<string, string>, key?: string): RegExp | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* 解析目录路径:如果 configDir 存在则 resolve 子目录,否则返回 undefined
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveSubdir(configDir: string | undefined, sub: string): string | undefined;
|
|
54
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/utils/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA0ClF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,SAAa,GAAG,MAAM,EAAE,CAOpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,SAAY,GAAG,MAAM,GAAG,SAAS,CAgB5F;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5F"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown 目录扫描工具
|
|
3
|
+
*
|
|
4
|
+
* 从 PersonaManager / SkillManager 提取的公共目录扫描逻辑,
|
|
5
|
+
* 消除跨模块重复的"扫描 *.md → 解析 frontmatter → 提取字段"代码。
|
|
6
|
+
*
|
|
7
|
+
* 使用异步 I/O(与 FileStore / ToolExecutor 保持一致)。
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, readdir, access } from 'node:fs/promises';
|
|
10
|
+
import { resolve, join, basename } from 'node:path';
|
|
11
|
+
import { parseFrontmatter } from '../utils/frontmatter.js';
|
|
12
|
+
import { getLogger } from '../utils/loggerHolder.js';
|
|
13
|
+
/** 排除的文件名(README / CHANGELOG / LICENSE 不纳入扫描) */
|
|
14
|
+
const EXCLUDED_FILES = new Set(['README.md', 'CHANGELOG.md', 'LICENSE']);
|
|
15
|
+
/**
|
|
16
|
+
* 扫描目录下的 *.md 文件,解析 frontmatter
|
|
17
|
+
*
|
|
18
|
+
* 排除规则:
|
|
19
|
+
* - 文件名以 `.` 开头的隐藏文件
|
|
20
|
+
* - 文件名以 `_` 前缀的私有文件
|
|
21
|
+
* - README.md / CHANGELOG.md / LICENSE
|
|
22
|
+
*
|
|
23
|
+
* @param dir 目录路径
|
|
24
|
+
* @returns 解析后的条目列表
|
|
25
|
+
*/
|
|
26
|
+
export async function scanMarkdownDir(dir) {
|
|
27
|
+
try {
|
|
28
|
+
await access(dir);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
getLogger().debug({ dir }, '扫描目录不存在,跳过');
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
let files;
|
|
35
|
+
try {
|
|
36
|
+
files = (await readdir(dir)).filter((f) => f.endsWith('.md') &&
|
|
37
|
+
!f.startsWith('.') &&
|
|
38
|
+
!f.startsWith('_') &&
|
|
39
|
+
!EXCLUDED_FILES.has(f));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
getLogger().warn({ dir }, '扫描目录失败');
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const entries = [];
|
|
46
|
+
for (const file of files) {
|
|
47
|
+
try {
|
|
48
|
+
const filePath = join(dir, file);
|
|
49
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
50
|
+
const { frontmatter: fm, body } = parseFrontmatter(raw);
|
|
51
|
+
entries.push({
|
|
52
|
+
name: fm['name'] ?? basename(file, '.md'),
|
|
53
|
+
frontmatter: fm,
|
|
54
|
+
body,
|
|
55
|
+
filePath,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
getLogger().warn({ file, err }, '解析 Markdown 文件失败');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return entries;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 从 frontmatter 中解析逗号分隔的关键词列表
|
|
66
|
+
*
|
|
67
|
+
* @param fm frontmatter 键值对
|
|
68
|
+
* @param key 关键词字段名(默认 'keywords')
|
|
69
|
+
* @returns 关键词数组
|
|
70
|
+
*/
|
|
71
|
+
export function parseKeywords(fm, key = 'keywords') {
|
|
72
|
+
const raw = fm[key];
|
|
73
|
+
if (!raw)
|
|
74
|
+
return [];
|
|
75
|
+
return String(raw)
|
|
76
|
+
.split(',')
|
|
77
|
+
.map((s) => s.trim())
|
|
78
|
+
.filter(Boolean);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 从 frontmatter 中解析正则触发器
|
|
82
|
+
*
|
|
83
|
+
* 支持格式:/pattern/flags 或纯 pattern(默认 'i' flag)
|
|
84
|
+
*
|
|
85
|
+
* @param fm frontmatter 键值对
|
|
86
|
+
* @param key 触发器字段名(默认 'trigger')
|
|
87
|
+
* @returns 正则表达式,解析失败返回 undefined
|
|
88
|
+
*/
|
|
89
|
+
export function parseTrigger(fm, key = 'trigger') {
|
|
90
|
+
const raw = fm[key];
|
|
91
|
+
if (!raw)
|
|
92
|
+
return undefined;
|
|
93
|
+
try {
|
|
94
|
+
const pattern = String(raw).trim();
|
|
95
|
+
const match = pattern.match(/^\/(.+)\/([gimsuy]*)$/);
|
|
96
|
+
// QC-17 移除非空断言:使用空值合并回退到 pattern(与 match 为 null 时逻辑一致)
|
|
97
|
+
const clean = match?.[1] ?? pattern;
|
|
98
|
+
// 修复 UTIL-02:使用捕获的 flags(默认 'i'),原实现硬编码 'i' 丢弃了声明的 flags
|
|
99
|
+
const flags = match?.[2] || 'i';
|
|
100
|
+
return new RegExp(clean, flags);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
getLogger().warn({ trigger: raw }, '触发正则无效,已忽略');
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 解析目录路径:如果 configDir 存在则 resolve 子目录,否则返回 undefined
|
|
109
|
+
*/
|
|
110
|
+
export function resolveSubdir(configDir, sub) {
|
|
111
|
+
if (!configDir)
|
|
112
|
+
return undefined;
|
|
113
|
+
return resolve(configDir, sub);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/utils/scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,iDAAiD;AACjD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC;AAczE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YACjB,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAClB,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAClB,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CACzB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAExD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;gBACzC,WAAW,EAAE,EAA4B;gBACzC,IAAI;gBACJ,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,EAA0B,EAAE,GAAG,GAAG,UAAU;IACxE,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,MAAM,CAAC,GAAG,CAAC;SACf,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,EAA0B,EAAE,GAAG,GAAG,SAAS;IACtE,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACrD,uDAAuD;QACvD,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;QACpC,yDAAyD;QACzD,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QAChC,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;QACjD,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,SAA6B,EAAE,GAAW;IACtE,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC"}
|