@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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/persona/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export type Permission = 'owner' | 'guest';
|
|
2
|
+
export type WriteDecision = 'confirmed' | 'declined' | 'auto-approved' | 'auto-denied';
|
|
3
|
+
export interface AuditEvent {
|
|
4
|
+
/** 事件类型 */
|
|
5
|
+
type: 'path-allow' | 'path-deny' | 'write-confirm' | 'write-decline' | 'write-auto';
|
|
6
|
+
/** 涉及的绝对路径 */
|
|
7
|
+
path: string;
|
|
8
|
+
/** 工具名(read_file / write_file / 自定义工具名) */
|
|
9
|
+
tool?: string;
|
|
10
|
+
/** S-02: 调用链来源(builtin / custom / system),标记安全检查的触发方 */
|
|
11
|
+
source?: 'builtin' | 'custom' | 'system';
|
|
12
|
+
/** 用户决策(写入二次确认场景) */
|
|
13
|
+
decision?: WriteDecision;
|
|
14
|
+
/** 拒绝原因 */
|
|
15
|
+
reason?: string;
|
|
16
|
+
/** 时间戳(ISO 8601) */
|
|
17
|
+
timestamp: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 审计日志订阅器
|
|
21
|
+
* 默认输出到 pino logger;可被业务层重定向到独立审计文件
|
|
22
|
+
*/
|
|
23
|
+
export type AuditListener = (event: AuditEvent) => void;
|
|
24
|
+
/**
|
|
25
|
+
* 写入确认请求
|
|
26
|
+
*
|
|
27
|
+
* 宿主程序在非交互式环境(WebUI/桌宠/无终端服务)需要自定义确认 UI。
|
|
28
|
+
* 注入此回调后,SecurityGuard.requestWriteConfirmation() 会调用它而不是直接读 stdin。
|
|
29
|
+
*
|
|
30
|
+
* 返回 true 确认写入,false 拒绝写入。
|
|
31
|
+
* 抛错视为拒绝(fail-closed,安全优先)。
|
|
32
|
+
*/
|
|
33
|
+
export type WriteConfirmationRequest = (info: WriteConfirmationInfo) => Promise<boolean>;
|
|
34
|
+
/** 写入确认请求的载荷 */
|
|
35
|
+
export interface WriteConfirmationInfo {
|
|
36
|
+
/** 目标文件绝对路径 */
|
|
37
|
+
targetPath: string;
|
|
38
|
+
/** 工具名(如 write_file) */
|
|
39
|
+
tool: string;
|
|
40
|
+
/** 人类可读的描述("写入 100 字符到 foo.md") */
|
|
41
|
+
description?: string;
|
|
42
|
+
/** 权限模式(owner / guest) */
|
|
43
|
+
permission: Permission;
|
|
44
|
+
/** 是否需要确认(owner + confirmWrites=false 时为 false,宿主可跳过弹窗) */
|
|
45
|
+
needsConfirm: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare class SecurityGuard {
|
|
48
|
+
/** owner 是否启用写入二次确认;guest 强制开启 */
|
|
49
|
+
readonly confirmWrites: boolean;
|
|
50
|
+
/** 权限模式 */
|
|
51
|
+
readonly permission: Permission;
|
|
52
|
+
private readonly listeners;
|
|
53
|
+
/** 审计事件缓冲(最近 N 条,供调试与回溯) */
|
|
54
|
+
private readonly auditBuffer;
|
|
55
|
+
private readonly bufferLimit;
|
|
56
|
+
/**
|
|
57
|
+
* 注入式写入确认回调。
|
|
58
|
+
* 宿主注册后,requestWriteConfirmation() 走自定义 UI;
|
|
59
|
+
* 不注册时回退到终端 readline(CLI 场景)。
|
|
60
|
+
*/
|
|
61
|
+
private confirmationHandler;
|
|
62
|
+
/** 允许访问的根目录列表(白名单) */
|
|
63
|
+
private readonly allowedRoots;
|
|
64
|
+
constructor(projectPath: string, memoraDir: string, extraAllowedPaths?: string[],
|
|
65
|
+
/** owner 是否启用写入二次确认;guest 强制开启 */
|
|
66
|
+
confirmWrites?: boolean,
|
|
67
|
+
/** 权限模式 */
|
|
68
|
+
permission?: Permission,
|
|
69
|
+
/** Agent 级配置目录(personas/rules/skills 所在目录) */
|
|
70
|
+
configDir?: string,
|
|
71
|
+
/** Agent 级数据目录(memora.db/vectors 所在目录) */
|
|
72
|
+
agentDataDir?: string);
|
|
73
|
+
/**
|
|
74
|
+
* 注册自定义写入确认回调(宿主程序接入)
|
|
75
|
+
*
|
|
76
|
+
* 适用于 WebUI/桌宠/无终端服务。注册后,requestWriteConfirmation()
|
|
77
|
+
* 不再直接读 stdin,而是回调此函数让宿主决定如何提示用户。
|
|
78
|
+
*
|
|
79
|
+
* 取消注册:传入 null。
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* securityGuard.onWriteConfirmation(async (info) => {
|
|
83
|
+
* return await showConfirmDialog(info.targetPath, info.description);
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
onWriteConfirmation(handler: WriteConfirmationRequest | null): void;
|
|
87
|
+
/**
|
|
88
|
+
* 订阅审计事件
|
|
89
|
+
* @returns 取消订阅函数
|
|
90
|
+
*/
|
|
91
|
+
onAudit(listener: AuditListener): () => void;
|
|
92
|
+
/**
|
|
93
|
+
* 获取最近的审计事件(深拷贝,外部不可修改内部缓冲)
|
|
94
|
+
*/
|
|
95
|
+
getRecentAudits(limit?: number): AuditEvent[];
|
|
96
|
+
/**
|
|
97
|
+
* 断言路径允许访问
|
|
98
|
+
* @throws Error 不在白名单时
|
|
99
|
+
* @param source S-02: 调用链来源标记
|
|
100
|
+
*/
|
|
101
|
+
assertPathAllowed(absolutePath: string, tool?: string, source?: 'builtin' | 'custom' | 'system'): void;
|
|
102
|
+
/**
|
|
103
|
+
* 写入操作前请求用户确认(M-101)
|
|
104
|
+
*
|
|
105
|
+
* 规则:
|
|
106
|
+
* - guest 模式:始终要求确认
|
|
107
|
+
* - owner + confirmWrites=true:要求确认
|
|
108
|
+
* - owner + confirmWrites=false:自动批准
|
|
109
|
+
*
|
|
110
|
+
* 优先走 confirmationHandler 注入式回调(宿主程序),
|
|
111
|
+
* 未注册时回退到 readline + stdin(CLI 场景)。
|
|
112
|
+
*
|
|
113
|
+
* @returns true 确认通过;false 用户拒绝
|
|
114
|
+
*/
|
|
115
|
+
requestWriteConfirmation(targetPath: string, tool: string, description?: string): Promise<boolean>;
|
|
116
|
+
/**
|
|
117
|
+
* 触发审计事件 + 写入日志 + 通知订阅者
|
|
118
|
+
*/
|
|
119
|
+
private emitAudit;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=pathGuard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"AAkCA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAC3C,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,GAAG,aAAa,CAAC;AAEvF,MAAM,WAAW,UAAU;IACzB,WAAW;IACX,IAAI,EAAE,YAAY,GAAG,WAAW,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAC;IACpF,cAAc;IACd,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzC,qBAAqB;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,WAAW;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEzF,gBAAgB;AAChB,MAAM,WAAW,qBAAqB;IACpC,eAAe;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,2DAA2D;IAC3D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,aAAa;IAmBtB,kCAAkC;aAClB,aAAa,EAAE,OAAO;IACtC,WAAW;aACK,UAAU,EAAE,UAAU;IArBxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,4BAA4B;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;IACnC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB,CAAyC;IAEpE,sBAAsB;IACtB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;gBAGtC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,MAAM,EAAO;IAChC,kCAAkC;IAClB,aAAa,GAAE,OAAe;IAC9C,WAAW;IACK,UAAU,GAAE,UAAoB;IAChD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM;IAClB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM;IAkBvB;;;;;;;;;;;;OAYG;IACH,mBAAmB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,GAAG,IAAI;IAInE;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI;IAQ5C;;OAEG;IACH,eAAe,CAAC,KAAK,SAAK,GAAG,UAAU,EAAE;IAIzC;;;;OAIG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAoDtG;;;;;;;;;;;;OAYG;IACG,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC;IAoFnB;;OAEG;IACH,OAAO,CAAC,SAAS;CAuBlB"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路径白名单 + 审计日志
|
|
3
|
+
*
|
|
4
|
+
* 4 类允许 + 12 类禁止
|
|
5
|
+
* 详见 ADR-006 · 安全模型
|
|
6
|
+
* 阶段二新增:M-101 写入二次确认 + M-105 审计日志
|
|
7
|
+
*/
|
|
8
|
+
import { resolve, sep } from 'node:path';
|
|
9
|
+
import { createInterface } from 'node:readline/promises';
|
|
10
|
+
import { stdin, stdout } from 'node:process';
|
|
11
|
+
import { logger } from '../logging/logger.js';
|
|
12
|
+
import { securityError, toError } from '../utils/errors.js';
|
|
13
|
+
import { expandHome } from '../utils/path.js';
|
|
14
|
+
const BLOCKED_PATTERNS = [
|
|
15
|
+
// 系统凭证
|
|
16
|
+
/(^|[\\/])\.ssh([\\/]|$)/i,
|
|
17
|
+
/(^|[\\/])\.gnupg([\\/]|$)/i,
|
|
18
|
+
/(^|[\\/])\.netrc$/i,
|
|
19
|
+
/(^|[\\/])\.pgpass$/i,
|
|
20
|
+
/[\\/]etc[\\/]passwd/i,
|
|
21
|
+
// 云服务凭证
|
|
22
|
+
/(^|[\\/])\.aws([\\/]|$)/i,
|
|
23
|
+
/(^|[\\/])\.azure([\\/]|$)/i,
|
|
24
|
+
/(^|[\\/])\.docker([\\/]|$)/i,
|
|
25
|
+
/(^|[\\/])\.kube([\\/]|$)/i,
|
|
26
|
+
/[\\/]gcloud([\\/]|$)/i,
|
|
27
|
+
// 仅拦截纯 `.env`、`.env.<name>`(name 不含 .)。
|
|
28
|
+
/(^|[\\/])\.env$|(^|[\\/])\.env\.[^\\/.]+$/i,
|
|
29
|
+
// 系统目录
|
|
30
|
+
/[\\/]system32([\\/]|$)/i,
|
|
31
|
+
/[\\/]Windows[\\/]System/i,
|
|
32
|
+
];
|
|
33
|
+
export class SecurityGuard {
|
|
34
|
+
confirmWrites;
|
|
35
|
+
permission;
|
|
36
|
+
listeners = [];
|
|
37
|
+
/** 审计事件缓冲(最近 N 条,供调试与回溯) */
|
|
38
|
+
auditBuffer = [];
|
|
39
|
+
bufferLimit = 100;
|
|
40
|
+
/**
|
|
41
|
+
* 注入式写入确认回调。
|
|
42
|
+
* 宿主注册后,requestWriteConfirmation() 走自定义 UI;
|
|
43
|
+
* 不注册时回退到终端 readline(CLI 场景)。
|
|
44
|
+
*/
|
|
45
|
+
confirmationHandler = null;
|
|
46
|
+
/** 允许访问的根目录列表(白名单) */
|
|
47
|
+
allowedRoots;
|
|
48
|
+
constructor(projectPath, memoraDir, extraAllowedPaths = [],
|
|
49
|
+
/** owner 是否启用写入二次确认;guest 强制开启 */
|
|
50
|
+
confirmWrites = false,
|
|
51
|
+
/** 权限模式 */
|
|
52
|
+
permission = 'owner',
|
|
53
|
+
/** Agent 级配置目录(personas/rules/skills 所在目录) */
|
|
54
|
+
configDir,
|
|
55
|
+
/** Agent 级数据目录(memora.db/vectors 所在目录) */
|
|
56
|
+
agentDataDir) {
|
|
57
|
+
this.confirmWrites = confirmWrites;
|
|
58
|
+
this.permission = permission;
|
|
59
|
+
// 构建白名单根目录列表
|
|
60
|
+
this.allowedRoots = [
|
|
61
|
+
resolve(projectPath),
|
|
62
|
+
resolve(expandHome(memoraDir)),
|
|
63
|
+
];
|
|
64
|
+
if (configDir) {
|
|
65
|
+
this.allowedRoots.push(resolve(expandHome(configDir)));
|
|
66
|
+
}
|
|
67
|
+
if (agentDataDir) {
|
|
68
|
+
this.allowedRoots.push(resolve(expandHome(agentDataDir)));
|
|
69
|
+
}
|
|
70
|
+
for (const p of extraAllowedPaths) {
|
|
71
|
+
this.allowedRoots.push(resolve(expandHome(p)));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 注册自定义写入确认回调(宿主程序接入)
|
|
76
|
+
*
|
|
77
|
+
* 适用于 WebUI/桌宠/无终端服务。注册后,requestWriteConfirmation()
|
|
78
|
+
* 不再直接读 stdin,而是回调此函数让宿主决定如何提示用户。
|
|
79
|
+
*
|
|
80
|
+
* 取消注册:传入 null。
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* securityGuard.onWriteConfirmation(async (info) => {
|
|
84
|
+
* return await showConfirmDialog(info.targetPath, info.description);
|
|
85
|
+
* });
|
|
86
|
+
*/
|
|
87
|
+
onWriteConfirmation(handler) {
|
|
88
|
+
this.confirmationHandler = handler;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 订阅审计事件
|
|
92
|
+
* @returns 取消订阅函数
|
|
93
|
+
*/
|
|
94
|
+
onAudit(listener) {
|
|
95
|
+
this.listeners.push(listener);
|
|
96
|
+
return () => {
|
|
97
|
+
const i = this.listeners.indexOf(listener);
|
|
98
|
+
if (i >= 0)
|
|
99
|
+
this.listeners.splice(i, 1);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 获取最近的审计事件(深拷贝,外部不可修改内部缓冲)
|
|
104
|
+
*/
|
|
105
|
+
getRecentAudits(limit = 10) {
|
|
106
|
+
return this.auditBuffer.slice(-limit).map((e) => ({ ...e }));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 断言路径允许访问
|
|
110
|
+
* @throws Error 不在白名单时
|
|
111
|
+
* @param source S-02: 调用链来源标记
|
|
112
|
+
*/
|
|
113
|
+
assertPathAllowed(absolutePath, tool, source) {
|
|
114
|
+
// SEC-05: NFKC 规范化,防止全角字符(如 ../)绕过黑名单正则
|
|
115
|
+
const normalized = absolutePath.normalize('NFKC');
|
|
116
|
+
const resolved = resolve(normalized);
|
|
117
|
+
// 1. 黑名单优先
|
|
118
|
+
for (const pattern of BLOCKED_PATTERNS) {
|
|
119
|
+
if (pattern.test(resolved)) {
|
|
120
|
+
this.emitAudit({
|
|
121
|
+
type: 'path-deny',
|
|
122
|
+
path: resolved,
|
|
123
|
+
tool,
|
|
124
|
+
source,
|
|
125
|
+
reason: `命中黑名单规则 (${pattern})`,
|
|
126
|
+
timestamp: new Date().toISOString(),
|
|
127
|
+
});
|
|
128
|
+
throw securityError('禁止访问:路径命中黑名单', `路径 ${resolved} 命中黑名单规则 (${pattern})`, ['检查路径是否正确', '如需访问该路径,请联系管理员添加白名单']);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// 2. 白名单:遍历所有允许的根目录(严格前缀匹配,追加 sep 防止兄弟目录绕过)
|
|
132
|
+
for (const allowedRoot of this.allowedRoots) {
|
|
133
|
+
if (resolved === allowedRoot || resolved.startsWith(allowedRoot + sep)) {
|
|
134
|
+
this.emitAudit({
|
|
135
|
+
type: 'path-allow',
|
|
136
|
+
path: resolved,
|
|
137
|
+
tool,
|
|
138
|
+
source,
|
|
139
|
+
timestamp: new Date().toISOString(),
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.emitAudit({
|
|
145
|
+
type: 'path-deny',
|
|
146
|
+
path: resolved,
|
|
147
|
+
tool,
|
|
148
|
+
source,
|
|
149
|
+
reason: '路径越界,不在白名单内',
|
|
150
|
+
timestamp: new Date().toISOString(),
|
|
151
|
+
});
|
|
152
|
+
throw securityError('路径越界', `${resolved} 不在白名单内`, [
|
|
153
|
+
'检查路径是否在项目目录内',
|
|
154
|
+
'在配置文件中添加该路径到 allowedPaths',
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 写入操作前请求用户确认(M-101)
|
|
159
|
+
*
|
|
160
|
+
* 规则:
|
|
161
|
+
* - guest 模式:始终要求确认
|
|
162
|
+
* - owner + confirmWrites=true:要求确认
|
|
163
|
+
* - owner + confirmWrites=false:自动批准
|
|
164
|
+
*
|
|
165
|
+
* 优先走 confirmationHandler 注入式回调(宿主程序),
|
|
166
|
+
* 未注册时回退到 readline + stdin(CLI 场景)。
|
|
167
|
+
*
|
|
168
|
+
* @returns true 确认通过;false 用户拒绝
|
|
169
|
+
*/
|
|
170
|
+
async requestWriteConfirmation(targetPath, tool, description) {
|
|
171
|
+
const needConfirm = this.permission === 'guest' || this.confirmWrites;
|
|
172
|
+
if (!needConfirm) {
|
|
173
|
+
this.emitAudit({
|
|
174
|
+
type: 'write-auto',
|
|
175
|
+
path: targetPath,
|
|
176
|
+
tool,
|
|
177
|
+
decision: 'auto-approved',
|
|
178
|
+
timestamp: new Date().toISOString(),
|
|
179
|
+
});
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
const info = {
|
|
183
|
+
targetPath,
|
|
184
|
+
tool,
|
|
185
|
+
description,
|
|
186
|
+
permission: this.permission,
|
|
187
|
+
needsConfirm: needConfirm,
|
|
188
|
+
};
|
|
189
|
+
if (this.confirmationHandler) {
|
|
190
|
+
try {
|
|
191
|
+
const ok = await this.confirmationHandler(info);
|
|
192
|
+
this.emitAudit({
|
|
193
|
+
type: ok ? 'write-confirm' : 'write-decline',
|
|
194
|
+
path: targetPath,
|
|
195
|
+
tool,
|
|
196
|
+
decision: ok ? 'confirmed' : 'declined',
|
|
197
|
+
timestamp: new Date().toISOString(),
|
|
198
|
+
});
|
|
199
|
+
return ok;
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
// 抛错视为拒绝(fail-closed 安全优先)
|
|
203
|
+
logger.warn({ err, targetPath }, '写入确认回调异常,视为拒绝');
|
|
204
|
+
this.emitAudit({
|
|
205
|
+
type: 'write-decline',
|
|
206
|
+
path: targetPath,
|
|
207
|
+
tool,
|
|
208
|
+
decision: 'declined',
|
|
209
|
+
reason: `回调异常:${toError(err).message}`,
|
|
210
|
+
timestamp: new Date().toISOString(),
|
|
211
|
+
});
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// 回退:CLI 场景直接走终端 readline
|
|
216
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
217
|
+
try {
|
|
218
|
+
const lines = [
|
|
219
|
+
`\n🔒 写入二次确认 [${this.permission}]`,
|
|
220
|
+
` 工具: ${tool}`,
|
|
221
|
+
` 路径: ${targetPath}`,
|
|
222
|
+
...(description ? [` 说明: ${description}`] : []),
|
|
223
|
+
` 确认写入?(y/N) `,
|
|
224
|
+
];
|
|
225
|
+
const answer = (await rl.question(lines.join('\n'))).trim().toLowerCase();
|
|
226
|
+
if (answer === 'y' || answer === 'yes') {
|
|
227
|
+
this.emitAudit({
|
|
228
|
+
type: 'write-confirm',
|
|
229
|
+
path: targetPath,
|
|
230
|
+
tool,
|
|
231
|
+
decision: 'confirmed',
|
|
232
|
+
timestamp: new Date().toISOString(),
|
|
233
|
+
});
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
this.emitAudit({
|
|
237
|
+
type: 'write-decline',
|
|
238
|
+
path: targetPath,
|
|
239
|
+
tool,
|
|
240
|
+
decision: 'declined',
|
|
241
|
+
timestamp: new Date().toISOString(),
|
|
242
|
+
});
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
rl.close();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* 触发审计事件 + 写入日志 + 通知订阅者
|
|
251
|
+
*/
|
|
252
|
+
emitAudit(event) {
|
|
253
|
+
// 缓冲
|
|
254
|
+
this.auditBuffer.push(event);
|
|
255
|
+
if (this.auditBuffer.length > this.bufferLimit) {
|
|
256
|
+
this.auditBuffer.shift();
|
|
257
|
+
}
|
|
258
|
+
// 写到 pino(结构化日志,方便后续检索)
|
|
259
|
+
if (event.type === 'path-deny' || event.type === 'write-decline') {
|
|
260
|
+
logger.warn({ audit: event }, '安全审计:拒绝');
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
logger.info({ audit: event }, '安全审计:通过');
|
|
264
|
+
}
|
|
265
|
+
// 通知订阅者(业务层可重定向到独立审计文件)
|
|
266
|
+
for (const listener of this.listeners) {
|
|
267
|
+
try {
|
|
268
|
+
listener(event);
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
logger.error({ err }, '审计订阅者执行失败');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=pathGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathGuard.js","sourceRoot":"","sources":["../../src/security/pathGuard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { IMemoryStorage } from '../memory/storageInterface.js';
|
|
2
|
+
import type { SkillEntry, SkillMatch } from '../skill/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* 技能管理器
|
|
5
|
+
*/
|
|
6
|
+
export declare class SkillManager {
|
|
7
|
+
private readonly configDir?;
|
|
8
|
+
private readonly index?;
|
|
9
|
+
/** 技能列表缓存(启动时扫描一次) */
|
|
10
|
+
private skills;
|
|
11
|
+
/**
|
|
12
|
+
* @param configDir 配置目录(技能文件在 <configDir>/skills/ 下)
|
|
13
|
+
* @param index SQLite 索引(用于写入 skill 记忆)
|
|
14
|
+
*/
|
|
15
|
+
constructor(configDir?: string | undefined, index?: IMemoryStorage | undefined);
|
|
16
|
+
/**
|
|
17
|
+
* 启动时加载:扫描技能目录
|
|
18
|
+
*
|
|
19
|
+
* @returns 加载的技能数量
|
|
20
|
+
*/
|
|
21
|
+
load(): Promise<number>;
|
|
22
|
+
/**
|
|
23
|
+
* 根据用户输入匹配最合适的技能
|
|
24
|
+
*
|
|
25
|
+
* 匹配流程:
|
|
26
|
+
* 1. 先检查所有 trigger 正则,命中直接返回(最高优先级)
|
|
27
|
+
* 2. 再检查关键词匹配(TF 计分,得分排序)
|
|
28
|
+
* 3. 若匹配多项但得分相同 → 取第一个
|
|
29
|
+
* 4. 无任何匹配 → 返回 null
|
|
30
|
+
*
|
|
31
|
+
* @param userInput 用户输入文本
|
|
32
|
+
* @returns 匹配结果,无匹配返回 null
|
|
33
|
+
*/
|
|
34
|
+
match(userInput: string): SkillMatch | null;
|
|
35
|
+
/**
|
|
36
|
+
* 根据技能名获取技能
|
|
37
|
+
*
|
|
38
|
+
* @param name 技能名
|
|
39
|
+
* @returns 技能条目,不存在返回 null
|
|
40
|
+
*/
|
|
41
|
+
get(name: string): SkillEntry | null;
|
|
42
|
+
/**
|
|
43
|
+
* 获取所有技能列表
|
|
44
|
+
*/
|
|
45
|
+
get list(): SkillEntry[];
|
|
46
|
+
/**
|
|
47
|
+
* 注册运行时注入的技能
|
|
48
|
+
*
|
|
49
|
+
* 供 Agent.addSkill() 调用:宿主程序可在 init() 之后动态注入技能。
|
|
50
|
+
* 重复注册同名技能会被拒绝(与文件加载的技能冲突时也按"先到先得"判断)。
|
|
51
|
+
*
|
|
52
|
+
* @param skill 技能条目
|
|
53
|
+
* @throws 技能名已存在时抛错
|
|
54
|
+
*/
|
|
55
|
+
register(skill: SkillEntry): void;
|
|
56
|
+
/**
|
|
57
|
+
* 构建 system prompt 中的技能段
|
|
58
|
+
*
|
|
59
|
+
* 格式:
|
|
60
|
+
* 【当前技能】技能名
|
|
61
|
+
* 技能 prompt 正文...
|
|
62
|
+
*
|
|
63
|
+
* @param name 技能名(可选,不传返回空)
|
|
64
|
+
*/
|
|
65
|
+
buildSystemPrompt(name?: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* 将所有技能写入 SQLite 索引
|
|
68
|
+
*/
|
|
69
|
+
private writeAllToIndex;
|
|
70
|
+
/**
|
|
71
|
+
* 将单个技能写入 SQLite 索引
|
|
72
|
+
*/
|
|
73
|
+
private writeSkillToIndex;
|
|
74
|
+
/**
|
|
75
|
+
* 扫描 configDir/skills/ 目录
|
|
76
|
+
*
|
|
77
|
+
* 宿主负责将全局+项目级技能汇总到 configDir,
|
|
78
|
+
* 内核只扫描一个目录,不做路径假设。
|
|
79
|
+
*/
|
|
80
|
+
private scanSkills;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=skillManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillManager.d.ts","sourceRoot":"","sources":["../../src/skill/skillManager.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG/D;;GAEG;AACH,qBAAa,YAAY;IASrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IATzB,sBAAsB;IACtB,OAAO,CAAC,MAAM,CAAoB;IAElC;;;OAGG;gBAEgB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,KAAK,CAAC,EAAE,cAAc,YAAA;IAGzC;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAa7B;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAgC3C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAIpC;;OAEG;IACH,IAAI,IAAI,IAAI,UAAU,EAAE,CAEvB;IAED;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAYjC;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAUxC;;OAEG;YACW,eAAe;IAQ7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;;;;OAKG;YACW,UAAU;CAuBzB"}
|