@hddz/plugin-harness 0.1.19 → 0.2.1
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.
Potentially problematic release.
This version of @hddz/plugin-harness might be problematic. Click here for more details.
- package/README.md +97 -114
- package/dist/core/auditors/index.d.ts +2 -0
- package/dist/core/auditors/index.js +7 -0
- package/dist/core/auditors/skill-auditor.d.ts +72 -0
- package/dist/core/auditors/skill-auditor.js +488 -0
- package/dist/core/index.d.ts +22 -0
- package/dist/core/index.js +47 -0
- package/dist/core/loggers/config-logger.d.ts +25 -0
- package/dist/core/loggers/config-logger.js +139 -0
- package/dist/core/loggers/index.d.ts +4 -0
- package/dist/core/loggers/index.js +9 -0
- package/dist/core/loggers/operation-logger.d.ts +23 -0
- package/dist/core/loggers/operation-logger.js +125 -0
- package/dist/core/middleware/context-injector.d.ts +25 -0
- package/dist/core/middleware/context-injector.js +174 -0
- package/dist/core/middleware/index.d.ts +5 -0
- package/dist/core/middleware/index.js +11 -0
- package/dist/core/middleware/loop-detector.d.ts +18 -0
- package/dist/core/middleware/loop-detector.js +125 -0
- package/dist/core/middleware/trace-logger.d.ts +34 -0
- package/dist/core/middleware/trace-logger.js +141 -0
- package/dist/core/utils/file.d.ts +28 -0
- package/dist/core/utils/file.js +104 -0
- package/dist/core/utils/format.d.ts +16 -0
- package/dist/core/utils/format.js +60 -0
- package/dist/core/utils/index.d.ts +2 -0
- package/dist/core/utils/index.js +14 -0
- package/dist/core/validators/config-validator.d.ts +25 -0
- package/dist/core/validators/config-validator.js +235 -0
- package/dist/core/validators/index.d.ts +2 -0
- package/dist/core/validators/index.js +7 -0
- package/dist/file-watcher.d.ts +37 -0
- package/dist/file-watcher.js +151 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +166 -106
- package/dist/src/file-watcher.d.ts +37 -0
- package/dist/src/file-watcher.js +151 -0
- package/dist/src/index.d.ts +70 -0
- package/dist/src/index.js +192 -0
- package/package.json +4 -12
- package/openclaw.plugin.json +0 -39
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// src/index.ts - Harness Plugin 主入口
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
|
|
4
|
+
exports.HarnessPlugin = void 0;
|
|
5
|
+
exports.createPlugin = createPlugin;
|
|
6
|
+
const core_1 = require("./core");
|
|
5
7
|
const DEFAULT_CONFIG = {
|
|
6
8
|
autoValidateConfig: true,
|
|
7
9
|
autoAuditSkill: true,
|
|
@@ -14,119 +16,177 @@ const DEFAULT_CONFIG = {
|
|
|
14
16
|
'MEMORY.md',
|
|
15
17
|
'openclaw.json',
|
|
16
18
|
],
|
|
17
|
-
logsDir: '
|
|
19
|
+
logsDir: 'logs/harness', // 相对 workspace 的路径
|
|
18
20
|
};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
register(api) {
|
|
36
|
-
const workspacePath = api.workspacePath || process.cwd();
|
|
37
|
-
const config = { ...DEFAULT_CONFIG, ...api.config };
|
|
21
|
+
class HarnessPlugin {
|
|
22
|
+
name = 'harness';
|
|
23
|
+
version = '0.1.0';
|
|
24
|
+
config;
|
|
25
|
+
workspacePath;
|
|
26
|
+
configValidator;
|
|
27
|
+
skillAuditor;
|
|
28
|
+
loopDetector;
|
|
29
|
+
configLogger;
|
|
30
|
+
operationLogger;
|
|
31
|
+
traceLogger;
|
|
32
|
+
constructor(workspacePath, config = {}) {
|
|
33
|
+
this.workspacePath = workspacePath;
|
|
34
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
38
35
|
// 初始化工具
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
api.logger.error('❌ [Harness] 配置验证失败:');
|
|
53
|
-
result.errors.forEach((e) => api.logger.error(` - ${e}`));
|
|
54
|
-
configLogger.log({
|
|
55
|
-
sessionId: sessionId || 'unknown',
|
|
56
|
-
modifier: 'AI Agent',
|
|
57
|
-
file: 'openclaw.json',
|
|
58
|
-
changes: [],
|
|
59
|
-
reason: '配置修改(验证失败)',
|
|
60
|
-
verified: false,
|
|
61
|
-
gatewayRestarted: false,
|
|
62
|
-
});
|
|
63
|
-
throw new Error(`配置验证失败:${result.errors.join(', ')}`);
|
|
64
|
-
}
|
|
65
|
-
configLogger.log({
|
|
66
|
-
sessionId: sessionId || 'unknown',
|
|
67
|
-
modifier: 'AI Agent',
|
|
68
|
-
file: 'openclaw.json',
|
|
69
|
-
changes: [],
|
|
70
|
-
reason: '配置修改',
|
|
71
|
-
verified: true,
|
|
72
|
-
gatewayRestarted: true,
|
|
73
|
-
});
|
|
74
|
-
api.logger.info('✅ [Harness] 配置验证通过');
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
// Hook: Skill 安装前审核
|
|
78
|
-
if (config.autoAuditSkill) {
|
|
79
|
-
api.onSkillInstall?.(async (skillPath) => {
|
|
80
|
-
api.logger.info('🔍 [Harness] 审核 Skill:', skillPath);
|
|
81
|
-
const auditResult = await skillAuditor.audit(skillPath, 'local');
|
|
82
|
-
if (!auditResult.passed) {
|
|
83
|
-
api.logger.error('❌ [Harness] Skill 审核失败:');
|
|
84
|
-
auditResult.warnings.forEach((w) => api.logger.error(` - ${w.message}`));
|
|
85
|
-
throw new Error(`Skill 审核失败:${auditResult.warnings.map((w) => w.message).join(', ')}`);
|
|
86
|
-
}
|
|
87
|
-
api.logger.info('✅ [Harness] Skill 审核通过');
|
|
88
|
-
});
|
|
36
|
+
this.configValidator = new core_1.ConfigValidator(workspacePath);
|
|
37
|
+
this.skillAuditor = new core_1.SkillAuditor(workspacePath);
|
|
38
|
+
this.loopDetector = new core_1.LoopDetector(workspacePath);
|
|
39
|
+
this.configLogger = new core_1.ConfigLogger(workspacePath);
|
|
40
|
+
this.operationLogger = new core_1.OperationLogger(workspacePath);
|
|
41
|
+
this.traceLogger = new core_1.TraceLogger(workspacePath);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Hook: 配置修改前验证
|
|
45
|
+
*/
|
|
46
|
+
async onConfigChange(newConfig, sessionId) {
|
|
47
|
+
if (!this.config.autoValidateConfig) {
|
|
48
|
+
return { valid: true };
|
|
89
49
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
50
|
+
console.log('🔍 [Harness] 验证配置变更...');
|
|
51
|
+
const result = this.configValidator.validateContent(newConfig);
|
|
52
|
+
if (!result.valid) {
|
|
53
|
+
console.error('❌ [Harness] 配置验证失败:');
|
|
54
|
+
result.errors.forEach(e => console.error(` - ${e}`));
|
|
55
|
+
// 记录配置变更失败
|
|
56
|
+
this.configLogger.log({
|
|
57
|
+
sessionId: sessionId || 'unknown',
|
|
58
|
+
modifier: 'AI Agent',
|
|
59
|
+
file: 'openclaw.json',
|
|
60
|
+
reason: '配置修改(验证失败)',
|
|
61
|
+
verified: false,
|
|
62
|
+
gatewayRestarted: false,
|
|
63
|
+
changes: [],
|
|
100
64
|
});
|
|
65
|
+
return { valid: false, errors: result.errors };
|
|
101
66
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
67
|
+
console.log('✅ [Harness] 配置验证通过');
|
|
68
|
+
// 记录配置变更成功
|
|
69
|
+
this.configLogger.log({
|
|
70
|
+
sessionId: sessionId || 'unknown',
|
|
71
|
+
modifier: 'AI Agent',
|
|
72
|
+
file: 'openclaw.json',
|
|
73
|
+
reason: '配置修改',
|
|
74
|
+
verified: true,
|
|
75
|
+
gatewayRestarted: true,
|
|
76
|
+
changes: [],
|
|
109
77
|
});
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
78
|
+
return { valid: true };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 公开方法:记录配置变更
|
|
82
|
+
*/
|
|
83
|
+
logConfigChange(entry) {
|
|
84
|
+
this.configLogger.log(entry);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Hook: Skill 安装前审核
|
|
88
|
+
*/
|
|
89
|
+
async onSkillInstall(skillPath, source, sessionId) {
|
|
90
|
+
if (!this.config.autoAuditSkill) {
|
|
91
|
+
return { passed: true };
|
|
92
|
+
}
|
|
93
|
+
console.log(`🔍 [Harness] 审核 Skill: ${skillPath}`);
|
|
94
|
+
const result = await this.skillAuditor.audit(skillPath, source || 'unknown');
|
|
95
|
+
if (!result.passed) {
|
|
96
|
+
console.error(`❌ [Harness] Skill 审核未通过:${result.riskLevel}`);
|
|
97
|
+
result.warnings.forEach(w => console.error(` - ${w.message}`));
|
|
98
|
+
return { passed: false, warnings: result.warnings };
|
|
99
|
+
}
|
|
100
|
+
console.log(`✅ [Harness] Skill 审核通过:${result.riskLevel}`);
|
|
101
|
+
return { passed: true };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Hook: 文件编辑时循环检测
|
|
105
|
+
*/
|
|
106
|
+
onFileEdit(filePath, sessionId) {
|
|
107
|
+
if (!this.config.loopDetectionEnabled) {
|
|
108
|
+
return { allowed: true };
|
|
109
|
+
}
|
|
110
|
+
const relativePath = filePath.split('/').pop() || filePath;
|
|
111
|
+
// 检查是否是保护文件
|
|
112
|
+
if (this.config.protectedFiles.some(f => filePath.endsWith(f))) {
|
|
113
|
+
console.warn(`⚠️ [Harness] 保护文件被修改:${filePath}`);
|
|
114
|
+
// 记录保护文件修改
|
|
115
|
+
this.operationLogger.log({
|
|
116
|
+
sessionId: sessionId || 'unknown',
|
|
114
117
|
modifier: 'AI Agent',
|
|
115
|
-
type: '
|
|
116
|
-
description:
|
|
117
|
-
|
|
118
|
+
type: 'file_edit',
|
|
119
|
+
description: `保护文件修改:${filePath}`,
|
|
120
|
+
file: filePath,
|
|
118
121
|
result: 'success',
|
|
119
122
|
});
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
}
|
|
124
|
+
// 循环检测
|
|
125
|
+
const warning = this.loopDetector.onFileEdit(filePath);
|
|
126
|
+
if (warning) {
|
|
127
|
+
console.warn(`⚠️ [Harness] 循环编辑警告:${warning}`);
|
|
128
|
+
return { allowed: true, warning }; // 允许但警告
|
|
129
|
+
}
|
|
130
|
+
return { allowed: true };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Hook: 文件删除前检查
|
|
134
|
+
*/
|
|
135
|
+
onFileDelete(filePath, sessionId) {
|
|
136
|
+
const relativePath = filePath.split('/').pop() || filePath;
|
|
137
|
+
// 检查是否是保护文件
|
|
138
|
+
if (this.config.protectedFiles.some(f => filePath.endsWith(f))) {
|
|
139
|
+
console.error(`🚨 [Harness] 禁止删除保护文件:${filePath}`);
|
|
140
|
+
this.operationLogger.log({
|
|
141
|
+
sessionId: sessionId || 'unknown',
|
|
142
|
+
modifier: 'AI Agent',
|
|
143
|
+
type: 'file_delete',
|
|
144
|
+
description: `尝试删除保护文件:${filePath}`,
|
|
145
|
+
file: filePath,
|
|
146
|
+
result: 'error',
|
|
124
147
|
});
|
|
148
|
+
return { allowed: false, reason: '保护文件禁止删除' };
|
|
149
|
+
}
|
|
150
|
+
this.operationLogger.log({
|
|
151
|
+
sessionId: sessionId || 'unknown',
|
|
152
|
+
modifier: 'AI Agent',
|
|
153
|
+
type: 'file_delete',
|
|
154
|
+
description: `删除文件:${filePath}`,
|
|
155
|
+
file: filePath,
|
|
156
|
+
result: 'success',
|
|
125
157
|
});
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLG9DQUFvQzs7QUFFcEMsMkNBQXdIO0FBVXhILE1BQU0sY0FBYyxHQUF3QjtJQUMxQyxrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGNBQWMsRUFBRSxJQUFJO0lBQ3BCLG9CQUFvQixFQUFFLElBQUk7SUFDMUIsY0FBYyxFQUFFO1FBQ2QsU0FBUztRQUNULFNBQVM7UUFDVCxXQUFXO1FBQ1gsVUFBVTtRQUNWLFdBQVc7UUFDWCxlQUFlO0tBQ2hCO0lBQ0QsT0FBTyxFQUFFLHdCQUF3QjtDQUNsQyxDQUFDO0FBRUYsTUFBTSxhQUFhLEdBQUc7SUFDcEIsRUFBRSxFQUFFLFNBQVM7SUFDYixJQUFJLEVBQUUscUJBQXFCO0lBQzNCLFdBQVcsRUFBRSxnRUFBZ0U7SUFDN0UsSUFBSSxFQUFFLGFBQWE7SUFDbkIsWUFBWSxFQUFFO1FBQ1osSUFBSSxFQUFFLFFBQWlCO1FBQ3ZCLG9CQUFvQixFQUFFLEtBQUs7UUFDM0IsVUFBVSxFQUFFO1lBQ1Ysa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBa0IsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFO1lBQy9ELGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFrQixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUU7WUFDM0Qsb0JBQW9CLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBa0IsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFO1lBQ2pFLGNBQWMsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFnQixFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFpQixFQUFFLEVBQUU7WUFDOUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQWlCLEVBQUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFO1NBQ3hFO0tBQ0Y7SUFDRCxRQUFRLENBQUMsR0FBUTtRQUNmLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3pELE1BQU0sTUFBTSxHQUF3QixFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRXpFLFFBQVE7UUFDUixNQUFNLGVBQWUsR0FBRyxJQUFJLHlCQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxzQkFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sWUFBWSxHQUFHLElBQUksc0JBQVksQ0FBQyxhQUFhLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sWUFBWSxHQUFHLElBQUksc0JBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNyRCxNQUFNLGVBQWUsR0FBRyxJQUFJLHlCQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDM0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxxQkFBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRW5ELEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBRXhELGdCQUFnQjtRQUNoQixJQUFJLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzlCLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxLQUFLLEVBQUUsU0FBYyxFQUFFLFNBQWtCLEVBQUUsRUFBRTtnQkFDaEUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQztnQkFFMUMsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFMUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDbEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztvQkFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUVwRSxZQUFZLENBQUMsR0FBRyxDQUFDO3dCQUNmLFNBQVMsRUFBRSxTQUFTLElBQUksU0FBUzt3QkFDakMsUUFBUSxFQUFFLFVBQVU7d0JBQ3BCLElBQUksRUFBRSxlQUFlO3dCQUNyQixPQUFPLEVBQUUsRUFBRTt3QkFDWCxNQUFNLEVBQUUsWUFBWTt3QkFDcEIsUUFBUSxFQUFFLEtBQUs7d0JBQ2YsZ0JBQWdCLEVBQUUsS0FBSztxQkFDeEIsQ0FBQyxDQUFDO29CQUVILE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3hELENBQUM7Z0JBRUQsWUFBWSxDQUFDLEdBQUcsQ0FBQztvQkFDZixTQUFTLEVBQUUsU0FBUyxJQUFJLFNBQVM7b0JBQ2pDLFFBQVEsRUFBRSxVQUFVO29CQUNwQixJQUFJLEVBQUUsZUFBZTtvQkFDckIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsTUFBTSxFQUFFLE1BQU07b0JBQ2QsUUFBUSxFQUFFLElBQUk7b0JBQ2QsZ0JBQWdCLEVBQUUsSUFBSTtpQkFDdkIsQ0FBQyxDQUFDO2dCQUVILEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsb0JBQW9CO1FBQ3BCLElBQUksTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzFCLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxLQUFLLEVBQUUsU0FBaUIsRUFBRSxFQUFFO2dCQUMvQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFFckQsTUFBTSxXQUFXLEdBQUcsTUFBTSxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFakUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDeEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztvQkFDNUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDaEYsTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLFdBQVcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDOUYsQ0FBQztnQkFFRCxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELGtCQUFrQjtRQUNsQixJQUFJLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQ2hDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBZ0IsRUFBRSxPQUFlLEVBQUUsRUFBRTtnQkFDM0QsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFbEQsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO29CQUN6QyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLFFBQVEsRUFBRSxDQUFDLENBQUM7b0JBQ3JDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ3hDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxvQkFBb0I7UUFDcEIsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFnQixFQUFFLEVBQUU7WUFDNUMsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxRQUFRLENBQUM7WUFFdkQsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUM3QyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxhQUFhLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsZUFBZTtRQUNmLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBZSxFQUFFLE9BQWEsRUFBRSxFQUFFO1lBQzNELGVBQWUsQ0FBQyxHQUFHLENBQUM7Z0JBQ2xCLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBUyxJQUFJLFNBQVM7Z0JBQzFDLFFBQVEsRUFBRSxVQUFVO2dCQUNwQixJQUFJLEVBQUUsZ0JBQWdCO2dCQUN0QixXQUFXLEVBQUUsUUFBUSxPQUFPLEVBQUU7Z0JBQzlCLE9BQU87Z0JBQ1AsTUFBTSxFQUFFLFNBQVM7YUFDbEIsQ0FBQyxDQUFDO1lBRUgsV0FBVyxDQUFDLEdBQUcsQ0FBQztnQkFDZCxTQUFTLEVBQUUsT0FBTyxFQUFFLFNBQVMsSUFBSSxTQUFTO2dCQUMxQyxJQUFJLEVBQUUsV0FBVztnQkFDakIsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUU7YUFDaEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7Q0FDRixDQUFDO0FBRUYsOEJBQThCO0FBQzlCLGFBQWE7QUFDYixNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNyYy9pbmRleC50cyAtIEhhcm5lc3MgUGx1Z2luIOS4u+WFpeWPo1xuXG5pbXBvcnQgeyBDb25maWdWYWxpZGF0b3IsIFNraWxsQXVkaXRvciwgTG9vcERldGVjdG9yLCBDb25maWdMb2dnZXIsIE9wZXJhdGlvbkxvZ2dlciwgVHJhY2VMb2dnZXIgfSBmcm9tICdAaGRkei9oYXJuZXNzJztcblxuZXhwb3J0IGludGVyZmFjZSBIYXJuZXNzUGx1Z2luQ29uZmlnIHtcbiAgYXV0b1ZhbGlkYXRlQ29uZmlnOiBib29sZWFuO1xuICBhdXRvQXVkaXRTa2lsbDogYm9vbGVhbjtcbiAgbG9vcERldGVjdGlvbkVuYWJsZWQ6IGJvb2xlYW47XG4gIHByb3RlY3RlZEZpbGVzOiBzdHJpbmdbXTtcbiAgbG9nc0Rpcjogc3RyaW5nO1xufVxuXG5jb25zdCBERUZBVUxUX0NPTkZJRzogSGFybmVzc1BsdWdpbkNvbmZpZyA9IHtcbiAgYXV0b1ZhbGlkYXRlQ29uZmlnOiB0cnVlLFxuICBhdXRvQXVkaXRTa2lsbDogdHJ1ZSxcbiAgbG9vcERldGVjdGlvbkVuYWJsZWQ6IHRydWUsXG4gIHByb3RlY3RlZEZpbGVzOiBbXG4gICAgJ1NPVUwubWQnLFxuICAgICdVU0VSLm1kJyxcbiAgICAnQUdFTlRTLm1kJyxcbiAgICAnVE9PTFMubWQnLFxuICAgICdNRU1PUlkubWQnLFxuICAgICdvcGVuY2xhdy5qc29uJyxcbiAgXSxcbiAgbG9nc0RpcjogJ3dvcmtzcGFjZS9sb2dzL2hhcm5lc3MnLFxufTtcblxuY29uc3QgaGFybmVzc1BsdWdpbiA9IHtcbiAgaWQ6ICdoYXJuZXNzJyxcbiAgbmFtZTogJ0hhcm5lc3MgRW5naW5lZXJpbmcnLFxuICBkZXNjcmlwdGlvbjogJ0NvbnN0cmFpbnRzLCBmZWVkYmFjayBsb29wcywgYW5kIGNvbnRyb2wgc3lzdGVtcyBmb3IgQUkgYWdlbnRzJyxcbiAga2luZDogJ2VuZ2luZWVyaW5nJyxcbiAgY29uZmlnU2NoZW1hOiB7XG4gICAgdHlwZTogJ29iamVjdCcgYXMgY29uc3QsXG4gICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIHByb3BlcnRpZXM6IHtcbiAgICAgIGF1dG9WYWxpZGF0ZUNvbmZpZzogeyB0eXBlOiAnYm9vbGVhbicgYXMgY29uc3QsIGRlZmF1bHQ6IHRydWUgfSxcbiAgICAgIGF1dG9BdWRpdFNraWxsOiB7IHR5cGU6ICdib29sZWFuJyBhcyBjb25zdCwgZGVmYXVsdDogdHJ1ZSB9LFxuICAgICAgbG9vcERldGVjdGlvbkVuYWJsZWQ6IHsgdHlwZTogJ2Jvb2xlYW4nIGFzIGNvbnN0LCBkZWZhdWx0OiB0cnVlIH0sXG4gICAgICBwcm90ZWN0ZWRGaWxlczogeyB0eXBlOiAnYXJyYXknIGFzIGNvbnN0LCBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyBhcyBjb25zdCB9IH0sXG4gICAgICBsb2dzRGlyOiB7IHR5cGU6ICdzdHJpbmcnIGFzIGNvbnN0LCBkZWZhdWx0OiAnd29ya3NwYWNlL2xvZ3MvaGFybmVzcycgfSxcbiAgICB9LFxuICB9LFxuICByZWdpc3RlcihhcGk6IGFueSkge1xuICAgIGNvbnN0IHdvcmtzcGFjZVBhdGggPSBhcGkud29ya3NwYWNlUGF0aCB8fCBwcm9jZXNzLmN3ZCgpO1xuICAgIGNvbnN0IGNvbmZpZzogSGFybmVzc1BsdWdpbkNvbmZpZyA9IHsgLi4uREVGQVVMVF9DT05GSUcsIC4uLmFwaS5jb25maWcgfTtcbiAgICBcbiAgICAvLyDliJ3lp4vljJblt6XlhbdcbiAgICBjb25zdCBjb25maWdWYWxpZGF0b3IgPSBuZXcgQ29uZmlnVmFsaWRhdG9yKHdvcmtzcGFjZVBhdGgpO1xuICAgIGNvbnN0IHNraWxsQXVkaXRvciA9IG5ldyBTa2lsbEF1ZGl0b3Iod29ya3NwYWNlUGF0aCk7XG4gICAgY29uc3QgbG9vcERldGVjdG9yID0gbmV3IExvb3BEZXRlY3Rvcih3b3Jrc3BhY2VQYXRoLCB7IGxpbWl0OiA1LCB3aW5kb3dNczogMzAwMDAwIH0pO1xuICAgIGNvbnN0IGNvbmZpZ0xvZ2dlciA9IG5ldyBDb25maWdMb2dnZXIod29ya3NwYWNlUGF0aCk7XG4gICAgY29uc3Qgb3BlcmF0aW9uTG9nZ2VyID0gbmV3IE9wZXJhdGlvbkxvZ2dlcih3b3Jrc3BhY2VQYXRoKTtcbiAgICBjb25zdCB0cmFjZUxvZ2dlciA9IG5ldyBUcmFjZUxvZ2dlcih3b3Jrc3BhY2VQYXRoKTtcblxuICAgIGFwaS5sb2dnZXIuaW5mbygnW0hhcm5lc3NdIOaPkuS7tuW3suWKoOi9ve+8jOW3peS9nOepuumXtDonLCB3b3Jrc3BhY2VQYXRoKTtcblxuICAgIC8vIEhvb2s6IOmFjee9ruS/ruaUueWJjemqjOivgVxuICAgIGlmIChjb25maWcuYXV0b1ZhbGlkYXRlQ29uZmlnKSB7XG4gICAgICBhcGkub25Db25maWdDaGFuZ2U/Lihhc3luYyAobmV3Q29uZmlnOiBhbnksIHNlc3Npb25JZD86IHN0cmluZykgPT4ge1xuICAgICAgICBhcGkubG9nZ2VyLmluZm8oJ/CflI0gW0hhcm5lc3NdIOmqjOivgemFjee9ruWPmOabtC4uLicpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY29uZmlnVmFsaWRhdG9yLnZhbGlkYXRlQ29udGVudChuZXdDb25maWcpO1xuICAgICAgICBcbiAgICAgICAgaWYgKCFyZXN1bHQudmFsaWQpIHtcbiAgICAgICAgICBhcGkubG9nZ2VyLmVycm9yKCfinYwgW0hhcm5lc3NdIOmFjee9rumqjOivgeWksei0pTonKTtcbiAgICAgICAgICByZXN1bHQuZXJyb3JzLmZvckVhY2goKGU6IHN0cmluZykgPT4gYXBpLmxvZ2dlci5lcnJvcihgICAgLSAke2V9YCkpO1xuICAgICAgICAgIFxuICAgICAgICAgIGNvbmZpZ0xvZ2dlci5sb2coe1xuICAgICAgICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWQgfHwgJ3Vua25vd24nLFxuICAgICAgICAgICAgbW9kaWZpZXI6ICdBSSBBZ2VudCcsXG4gICAgICAgICAgICBmaWxlOiAnb3BlbmNsYXcuanNvbicsXG4gICAgICAgICAgICBjaGFuZ2VzOiBbXSxcbiAgICAgICAgICAgIHJlYXNvbjogJ+mFjee9ruS/ruaUue+8iOmqjOivgeWksei0pe+8iScsXG4gICAgICAgICAgICB2ZXJpZmllZDogZmFsc2UsXG4gICAgICAgICAgICBnYXRld2F5UmVzdGFydGVkOiBmYWxzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOmFjee9rumqjOivgeWksei0pe+8miR7cmVzdWx0LmVycm9ycy5qb2luKCcsICcpfWApO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjb25maWdMb2dnZXIubG9nKHtcbiAgICAgICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCB8fCAndW5rbm93bicsXG4gICAgICAgICAgbW9kaWZpZXI6ICdBSSBBZ2VudCcsXG4gICAgICAgICAgZmlsZTogJ29wZW5jbGF3Lmpzb24nLFxuICAgICAgICAgIGNoYW5nZXM6IFtdLFxuICAgICAgICAgIHJlYXNvbjogJ+mFjee9ruS/ruaUuScsXG4gICAgICAgICAgdmVyaWZpZWQ6IHRydWUsXG4gICAgICAgICAgZ2F0ZXdheVJlc3RhcnRlZDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIFxuICAgICAgICBhcGkubG9nZ2VyLmluZm8oJ+KchSBbSGFybmVzc10g6YWN572u6aqM6K+B6YCa6L+HJyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBIb29rOiBTa2lsbCDlronoo4XliY3lrqHmoLhcbiAgICBpZiAoY29uZmlnLmF1dG9BdWRpdFNraWxsKSB7XG4gICAgICBhcGkub25Ta2lsbEluc3RhbGw/Lihhc3luYyAoc2tpbGxQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgICAgYXBpLmxvZ2dlci5pbmZvKCfwn5SNIFtIYXJuZXNzXSDlrqHmoLggU2tpbGw6Jywgc2tpbGxQYXRoKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGF1ZGl0UmVzdWx0ID0gYXdhaXQgc2tpbGxBdWRpdG9yLmF1ZGl0KHNraWxsUGF0aCwgJ2xvY2FsJyk7XG4gICAgICAgIFxuICAgICAgICBpZiAoIWF1ZGl0UmVzdWx0LnBhc3NlZCkge1xuICAgICAgICAgIGFwaS5sb2dnZXIuZXJyb3IoJ+KdjCBbSGFybmVzc10gU2tpbGwg5a6h5qC45aSx6LSlOicpO1xuICAgICAgICAgIGF1ZGl0UmVzdWx0Lndhcm5pbmdzLmZvckVhY2goKHc6IGFueSkgPT4gYXBpLmxvZ2dlci5lcnJvcihgICAgLSAke3cubWVzc2FnZX1gKSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTa2lsbCDlrqHmoLjlpLHotKXvvJoke2F1ZGl0UmVzdWx0Lndhcm5pbmdzLm1hcCgodzogYW55KSA9PiB3Lm1lc3NhZ2UpLmpvaW4oJywgJyl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGFwaS5sb2dnZXIuaW5mbygn4pyFIFtIYXJuZXNzXSBTa2lsbCDlrqHmoLjpgJrov4cnKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEhvb2s6IOaWh+S7tue8lui+keaXtuW+queOr+ajgOa1i1xuICAgIGlmIChjb25maWcubG9vcERldGVjdGlvbkVuYWJsZWQpIHtcbiAgICAgIGFwaS5vbkZpbGVFZGl0Py4oYXN5bmMgKGZpbGVQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCB3YXJuaW5nID0gbG9vcERldGVjdG9yLm9uRmlsZUVkaXQoZmlsZVBhdGgpO1xuICAgICAgICBcbiAgICAgICAgaWYgKHdhcm5pbmcpIHtcbiAgICAgICAgICBhcGkubG9nZ2VyLndhcm4oJ+KaoO+4jyBbSGFybmVzc10g5qOA5rWL5Yiw6aKR57mB57yW6L6ROicpO1xuICAgICAgICAgIGFwaS5sb2dnZXIud2FybihgICAg5paH5Lu277yaJHtmaWxlUGF0aH1gKTtcbiAgICAgICAgICBhcGkubG9nZ2VyLndhcm4oYCAgIOitpuWRiu+8miR7d2FybmluZ31gKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOajgOa1i+WIsOW+queOr+e8lui+ke+8miR7d2FybmluZ31gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSG9vazog5paH5Lu25Yig6Zmk5YmN5qOA5p+l5L+d5oqk5paH5Lu2XG4gICAgYXBpLm9uRmlsZURlbGV0ZT8uKGFzeW5jIChmaWxlUGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGZpbGVQYXRoLnNwbGl0KCcvJykucG9wKCkgfHwgZmlsZVBhdGg7XG4gICAgICBcbiAgICAgIGlmIChjb25maWcucHJvdGVjdGVkRmlsZXMuaW5jbHVkZXMoZmlsZU5hbWUpKSB7XG4gICAgICAgIGFwaS5sb2dnZXIuZXJyb3IoYOKdjCBbSGFybmVzc10g6Zi75q2i5Yig6Zmk5L+d5oqk5paH5Lu277yaJHtmaWxlUGF0aH1gKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDkuI3lhYHorrjliKDpmaTkv53miqTmlofku7bvvJoke2ZpbGVOYW1lfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gSG9vazog5ZG95Luk5omn6KGM5a6h6K6hXG4gICAgYXBpLm9uRXhlY0NvbW1hbmQ/Lihhc3luYyAoY29tbWFuZDogc3RyaW5nLCBvcHRpb25zPzogYW55KSA9PiB7XG4gICAgICBvcGVyYXRpb25Mb2dnZXIubG9nKHtcbiAgICAgICAgc2Vzc2lvbklkOiBvcHRpb25zPy5zZXNzaW9uSWQgfHwgJ3Vua25vd24nLFxuICAgICAgICBtb2RpZmllcjogJ0FJIEFnZW50JyxcbiAgICAgICAgdHlwZTogJ3N5c3RlbV9jb21tYW5kJyxcbiAgICAgICAgZGVzY3JpcHRpb246IGDmiafooYzlkb3ku6TvvJoke2NvbW1hbmR9YCxcbiAgICAgICAgY29tbWFuZCxcbiAgICAgICAgcmVzdWx0OiAnc3VjY2VzcycsXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgdHJhY2VMb2dnZXIubG9nKHtcbiAgICAgICAgc2Vzc2lvbklkOiBvcHRpb25zPy5zZXNzaW9uSWQgfHwgJ3Vua25vd24nLFxuICAgICAgICB0eXBlOiAndG9vbF9jYWxsJyxcbiAgICAgICAgZGF0YTogeyB0b29sOiAnZXhlYycsIGNvbW1hbmQgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYXBpLmxvZ2dlci5pbmZvKCfinIUgW0hhcm5lc3NdIOaJgOaciSBIb29rIOW3suazqOWGjCcpO1xuICB9LFxufTtcblxuLy8gQ29tbW9uSlMg5a+85Ye677yIT3BlbkNsYXcg5pyf5pyb55qE5qC85byP77yJXG4vLyBAdHMtaWdub3JlXG5tb2R1bGUuZXhwb3J0cyA9IGhhcm5lc3NQbHVnaW47XG4iXX0=
|
|
158
|
+
return { allowed: true };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Hook: 系统命令执行前
|
|
162
|
+
*/
|
|
163
|
+
onExecCommand(command, sessionId) {
|
|
164
|
+
this.operationLogger.log({
|
|
165
|
+
sessionId: sessionId || 'unknown',
|
|
166
|
+
modifier: 'AI Agent',
|
|
167
|
+
type: 'system_command',
|
|
168
|
+
description: `执行命令:${command}`,
|
|
169
|
+
command,
|
|
170
|
+
result: 'pending',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 获取插件状态
|
|
175
|
+
*/
|
|
176
|
+
getStatus() {
|
|
177
|
+
return {
|
|
178
|
+
name: this.name,
|
|
179
|
+
version: this.version,
|
|
180
|
+
enabled: true,
|
|
181
|
+
config: this.config,
|
|
182
|
+
loopStats: this.loopDetector.getStats(),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.HarnessPlugin = HarnessPlugin;
|
|
187
|
+
// OpenClaw 插件工厂函数
|
|
188
|
+
function createPlugin(workspacePath, config) {
|
|
189
|
+
return new HarnessPlugin(workspacePath, config);
|
|
190
|
+
}
|
|
191
|
+
exports.default = HarnessPlugin;
|
|
192
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLG9DQUFvQzs7O0FBMk9wQyxvQ0FFQztBQTNPRCxpQ0FBaUg7QUFVakgsTUFBTSxjQUFjLEdBQXdCO0lBQzFDLGtCQUFrQixFQUFFLElBQUk7SUFDeEIsY0FBYyxFQUFFLElBQUk7SUFDcEIsb0JBQW9CLEVBQUUsSUFBSTtJQUMxQixjQUFjLEVBQUU7UUFDZCxTQUFTO1FBQ1QsU0FBUztRQUNULFdBQVc7UUFDWCxVQUFVO1FBQ1YsV0FBVztRQUNYLGVBQWU7S0FDaEI7SUFDRCxPQUFPLEVBQUUsY0FBYyxFQUFHLG1CQUFtQjtDQUM5QyxDQUFDO0FBRUYsTUFBYSxhQUFhO0lBQ3hCLElBQUksR0FBRyxTQUFTLENBQUM7SUFDakIsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUVWLE1BQU0sQ0FBc0I7SUFDNUIsYUFBYSxDQUFTO0lBQ3RCLGVBQWUsQ0FBa0I7SUFDakMsWUFBWSxDQUFlO0lBQzNCLFlBQVksQ0FBZTtJQUMzQixZQUFZLENBQWU7SUFDM0IsZUFBZSxDQUFrQjtJQUNqQyxXQUFXLENBQWM7SUFFakMsWUFBWSxhQUFxQixFQUFFLFNBQXVDLEVBQUU7UUFDMUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsY0FBYyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFL0MsUUFBUTtRQUNSLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxzQkFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxtQkFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxtQkFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxt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RUFBRSxVQUFVO1lBQ3BCLElBQUksRUFBRSxhQUFhO1lBQ25CLFdBQVcsRUFBRSxRQUFRLFFBQVEsRUFBRTtZQUMvQixJQUFJLEVBQUUsUUFBUTtZQUNkLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUMsQ0FBQztRQUVILE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUFDLE9BQWUsRUFBRSxTQUFrQjtRQUMvQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQztZQUN2QixTQUFTLEVBQUUsU0FBUyxJQUFJLFNBQVM7WUFDakMsUUFBUSxFQUFFLFVBQVU7WUFDcEIsSUFBSSxFQUFFLGdCQUFnQjtZQUN0QixXQUFXLEVBQUUsUUFBUSxPQUFPLEVBQUU7WUFDOUIsT0FBTztZQUNQLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVM7UUFDUCxPQUFPO1lBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE9BQU8sRUFBRSxJQUFJO1lBQ2IsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFNBQVMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRTtTQUN4QyxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBN01ELHNDQTZNQztBQUVELGtCQUFrQjtBQUNsQixTQUFnQixZQUFZLENBQUMsYUFBcUIsRUFBRSxNQUFXO0lBQzdELE9BQU8sSUFBSSxhQUFhLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2xELENBQUM7QUFFRCxrQkFBZSxhQUFhLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBzcmMvaW5kZXgudHMgLSBIYXJuZXNzIFBsdWdpbiDkuLvlhaXlj6NcblxuaW1wb3J0IHsgQ29uZmlnVmFsaWRhdG9yLCBTa2lsbEF1ZGl0b3IsIExvb3BEZXRlY3RvciwgQ29uZmlnTG9nZ2VyLCBPcGVyYXRpb25Mb2dnZXIsIFRyYWNlTG9nZ2VyIH0gZnJvbSAnLi9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBIYXJuZXNzUGx1Z2luQ29uZmlnIHtcbiAgYXV0b1ZhbGlkYXRlQ29uZmlnOiBib29sZWFuO1xuICBhdXRvQXVkaXRTa2lsbDogYm9vbGVhbjtcbiAgbG9vcERldGVjdGlvbkVuYWJsZWQ6IGJvb2xlYW47XG4gIHByb3RlY3RlZEZpbGVzOiBzdHJpbmdbXTtcbiAgbG9nc0Rpcjogc3RyaW5nO1xufVxuXG5jb25zdCBERUZBVUxUX0NPTkZJRzogSGFybmVzc1BsdWdpbkNvbmZpZyA9IHtcbiAgYXV0b1ZhbGlkYXRlQ29uZmlnOiB0cnVlLFxuICBhdXRvQXVkaXRTa2lsbDogdHJ1ZSxcbiAgbG9vcERldGVjdGlvbkVuYWJsZWQ6IHRydWUsXG4gIHByb3RlY3RlZEZpbGVzOiBbXG4gICAgJ1NPVUwubWQnLFxuICAgICdVU0VSLm1kJyxcbiAgICAnQUdFTlRTLm1kJyxcbiAgICAnVE9PTFMubWQnLFxuICAgICdNRU1PUlkubWQnLFxuICAgICdvcGVuY2xhdy5qc29uJyxcbiAgXSxcbiAgbG9nc0RpcjogJ2xvZ3MvaGFybmVzcycsICAvLyDnm7jlr7kgd29ya3NwYWNlIOeahOi3r+W+hFxufTtcblxuZXhwb3J0IGNsYXNzIEhhcm5lc3NQbHVnaW4ge1xuICBuYW1lID0gJ2hhcm5lc3MnO1xuICB2ZXJzaW9uID0gJzAuMS4wJztcbiAgXG4gIHByaXZhdGUgY29uZmlnOiBIYXJuZXNzUGx1Z2luQ29uZmlnO1xuICBwcml2YXRlIHdvcmtzcGFjZVBhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSBjb25maWdWYWxpZGF0b3I6IENvbmZpZ1ZhbGlkYXRvcjtcbiAgcHJpdmF0ZSBza2lsbEF1ZGl0b3I6IFNraWxsQXVkaXRvcjtcbiAgcHJpdmF0ZSBsb29wRGV0ZWN0b3I6IExvb3BEZXRlY3RvcjtcbiAgcHJpdmF0ZSBjb25maWdMb2dnZXI6IENvbmZpZ0xvZ2dlcjtcbiAgcHJpdmF0ZSBvcGVyYXRpb25Mb2dnZXI6IE9wZXJhdGlvbkxvZ2dlcjtcbiAgcHJpdmF0ZSB0cmFjZUxvZ2dlcjogVHJhY2VMb2dnZXI7XG5cbiAgY29uc3RydWN0b3Iod29ya3NwYWNlUGF0aDogc3RyaW5nLCBjb25maWc6IFBhcnRpYWw8SGFybmVzc1BsdWdpbkNvbmZpZz4gPSB7fSkge1xuICAgIHRoaXMud29ya3NwYWNlUGF0aCA9IHdvcmtzcGFjZVBhdGg7XG4gICAgdGhpcy5jb25maWcgPSB7IC4uLkRFRkFVTFRfQ09ORklHLCAuLi5jb25maWcgfTtcbiAgICBcbiAgICAvLyDliJ3lp4vljJblt6XlhbdcbiAgICB0aGlzLmNvbmZpZ1ZhbGlkYXRvciA9IG5ldyBDb25maWdWYWxpZGF0b3Iod29ya3NwYWNlUGF0aCk7XG4gICAgdGhpcy5za2lsbEF1ZGl0b3IgPSBuZXcgU2tpbGxBdWRpdG9yKHdvcmtzcGFjZVBhdGgpO1xuICAgIHRoaXMubG9vcERldGVjdG9yID0gbmV3IExvb3BEZXRlY3Rvcih3b3Jrc3BhY2VQYXRoKTtcbiAgICB0aGlzLmNvbmZpZ0xvZ2dlciA9IG5ldyBDb25maWdMb2dnZXIod29ya3NwYWNlUGF0aCk7XG4gICAgdGhpcy5vcGVyYXRpb25Mb2dnZXIgPSBuZXcgT3BlcmF0aW9uTG9nZ2VyKHdvcmtzcGFjZVBhdGgpO1xuICAgIHRoaXMudHJhY2VMb2dnZXIgPSBuZXcgVHJhY2VMb2dnZXIod29ya3NwYWNlUGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogSG9vazog6YWN572u5L+u5pS55YmN6aqM6K+BXG4gICAqL1xuICBhc3luYyBvbkNvbmZpZ0NoYW5nZShuZXdDb25maWc6IGFueSwgc2Vzc2lvbklkPzogc3RyaW5nKTogUHJvbWlzZTx7IHZhbGlkOiBib29sZWFuOyBlcnJvcnM/OiBzdHJpbmdbXSB9PiB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5hdXRvVmFsaWRhdGVDb25maWcpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coJ/CflI0gW0hhcm5lc3NdIOmqjOivgemFjee9ruWPmOabtC4uLicpO1xuICAgIFxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29uZmlnVmFsaWRhdG9yLnZhbGlkYXRlQ29udGVudChuZXdDb25maWcpO1xuICAgIFxuICAgIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCfinYwgW0hhcm5lc3NdIOmFjee9rumqjOivgeWksei0pTonKTtcbiAgICAgIHJlc3VsdC5lcnJvcnMuZm9yRWFjaChlID0+IGNvbnNvbGUuZXJyb3IoYCAgIC0gJHtlfWApKTtcbiAgICAgIFxuICAgICAgLy8g6K6w5b2V6YWN572u5Y+Y5pu05aSx6LSlXG4gICAgICB0aGlzLmNvbmZpZ0xvZ2dlci5sb2coe1xuICAgICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCB8fCAndW5rbm93bicsXG4gICAgICAgIG1vZGlmaWVyOiAnQUkgQWdlbnQnLFxuICAgICAgICBmaWxlOiAnb3BlbmNsYXcuanNvbicsXG4gICAgICAgIHJlYXNvbjogJ+mFjee9ruS/ruaUue+8iOmqjOivgeWksei0pe+8iScsXG4gICAgICAgIHZlcmlmaWVkOiBmYWxzZSxcbiAgICAgICAgZ2F0ZXdheVJlc3RhcnRlZDogZmFsc2UsXG4gICAgICAgIGNoYW5nZXM6IFtdLFxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3JzOiByZXN1bHQuZXJyb3JzIH07XG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKCfinIUgW0hhcm5lc3NdIOmFjee9rumqjOivgemAmui/hycpO1xuICAgIFxuICAgIC8vIOiusOW9lemFjee9ruWPmOabtOaIkOWKn1xuICAgIHRoaXMuY29uZmlnTG9nZ2VyLmxvZyh7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCB8fCAndW5rbm93bicsXG4gICAgICBtb2RpZmllcjogJ0FJIEFnZW50JyxcbiAgICAgIGZpbGU6ICdvcGVuY2xhdy5qc29uJyxcbiAgICAgIHJlYXNvbjogJ+mFjee9ruS/ruaUuScsXG4gICAgICB2ZXJpZmllZDogdHJ1ZSxcbiAgICAgIGdhdGV3YXlSZXN0YXJ0ZWQ6IHRydWUsXG4gICAgICBjaGFuZ2VzOiBbXSxcbiAgICB9KTtcbiAgICBcbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOWFrOW8gOaWueazle+8muiusOW9lemFjee9ruWPmOabtFxuICAgKi9cbiAgbG9nQ29uZmlnQ2hhbmdlKGVudHJ5OiB7XG4gICAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gICAgbW9kaWZpZXI6IHN0cmluZztcbiAgICBmaWxlOiBzdHJpbmc7XG4gICAgcmVhc29uOiBzdHJpbmc7XG4gICAgdmVyaWZpZWQ6IGJvb2xlYW47XG4gICAgZ2F0ZXdheVJlc3RhcnRlZDogYm9vbGVhbjtcbiAgICBjaGFuZ2VzOiBhbnlbXTtcbiAgfSkge1xuICAgIHRoaXMuY29uZmlnTG9nZ2VyLmxvZyhlbnRyeSk7XG4gIH1cblxuICAvKipcbiAgICogSG9vazogU2tpbGwg5a6J6KOF5YmN5a6h5qC4XG4gICAqL1xuICBhc3luYyBvblNraWxsSW5zdGFsbChza2lsbFBhdGg6IHN0cmluZywgc291cmNlPzogc3RyaW5nLCBzZXNzaW9uSWQ/OiBzdHJpbmcpOiBQcm9taXNlPHsgcGFzc2VkOiBib29sZWFuOyB3YXJuaW5ncz86IGFueVtdIH0+IHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLmF1dG9BdWRpdFNraWxsKSB7XG4gICAgICByZXR1cm4geyBwYXNzZWQ6IHRydWUgfTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhg8J+UjSBbSGFybmVzc10g5a6h5qC4IFNraWxsOiAke3NraWxsUGF0aH1gKTtcbiAgICBcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnNraWxsQXVkaXRvci5hdWRpdChza2lsbFBhdGgsIHNvdXJjZSB8fCAndW5rbm93bicpO1xuICAgIFxuICAgIGlmICghcmVzdWx0LnBhc3NlZCkge1xuICAgICAgY29uc29sZS5lcnJvcihg4p2MIFtIYXJuZXNzXSBTa2lsbCDlrqHmoLjmnKrpgJrov4fvvJoke3Jlc3VsdC5yaXNrTGV2ZWx9YCk7XG4gICAgICByZXN1bHQud2FybmluZ3MuZm9yRWFjaCh3ID0+IGNvbnNvbGUuZXJyb3IoYCAgIC0gJHt3Lm1lc3NhZ2V9YCkpO1xuICAgICAgXG4gICAgICByZXR1cm4geyBwYXNzZWQ6IGZhbHNlLCB3YXJuaW5nczogcmVzdWx0Lndhcm5pbmdzIH07XG4gICAgfVxuICAgIFxuICAgIGNvbnNvbGUubG9nKGDinIUgW0hhcm5lc3NdIFNraWxsIOWuoeaguOmAmui/h++8miR7cmVzdWx0LnJpc2tMZXZlbH1gKTtcbiAgICByZXR1cm4geyBwYXNzZWQ6IHRydWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rOiDmlofku7bnvJbovpHml7blvqrnjq/mo4DmtYtcbiAgICovXG4gIG9uRmlsZUVkaXQoZmlsZVBhdGg6IHN0cmluZywgc2Vzc2lvbklkPzogc3RyaW5nKTogeyBhbGxvd2VkOiBib29sZWFuOyB3YXJuaW5nPzogc3RyaW5nIH0ge1xuICAgIGlmICghdGhpcy5jb25maWcubG9vcERldGVjdGlvbkVuYWJsZWQpIHtcbiAgICAgIHJldHVybiB7IGFsbG93ZWQ6IHRydWUgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBmaWxlUGF0aC5zcGxpdCgnLycpLnBvcCgpIHx8IGZpbGVQYXRoO1xuICAgIFxuICAgIC8vIOajgOafpeaYr+WQpuaYr+S/neaKpOaWh+S7tlxuICAgIGlmICh0aGlzLmNvbmZpZy5wcm90ZWN0ZWRGaWxlcy5zb21lKGYgPT4gZmlsZVBhdGguZW5kc1dpdGgoZikpKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoO+4jyBbSGFybmVzc10g5L+d5oqk5paH5Lu26KKr5L+u5pS577yaJHtmaWxlUGF0aH1gKTtcbiAgICAgIC8vIOiusOW9leS/neaKpOaWh+S7tuS/ruaUuVxuICAgICAgdGhpcy5vcGVyYXRpb25Mb2dnZXIubG9nKHtcbiAgICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWQgfHwgJ3Vua25vd24nLFxuICAgICAgICBtb2RpZmllcjogJ0FJIEFnZW50JyxcbiAgICAgICAgdHlwZTogJ2ZpbGVfZWRpdCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBg5L+d5oqk5paH5Lu25L+u5pS577yaJHtmaWxlUGF0aH1gLFxuICAgICAgICBmaWxlOiBmaWxlUGF0aCxcbiAgICAgICAgcmVzdWx0OiAnc3VjY2VzcycsXG4gICAgICB9KTtcbiAgICB9XG4gICAgXG4gICAgLy8g5b6q546v5qOA5rWLXG4gICAgY29uc3Qgd2FybmluZyA9IHRoaXMubG9vcERldGVjdG9yLm9uRmlsZUVkaXQoZmlsZVBhdGgpO1xuICAgIFxuICAgIGlmICh3YXJuaW5nKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoO+4jyBbSGFybmVzc10g5b6q546v57yW6L6R6K2m5ZGK77yaJHt3YXJuaW5nfWApO1xuICAgICAgcmV0dXJuIHsgYWxsb3dlZDogdHJ1ZSwgd2FybmluZyB9OyAvLyDlhYHorrjkvYborablkYpcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHsgYWxsb3dlZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEhvb2s6IOaWh+S7tuWIoOmZpOWJjeajgOafpVxuICAgKi9cbiAgb25GaWxlRGVsZXRlKGZpbGVQYXRoOiBzdHJpbmcsIHNlc3Npb25JZD86IHN0cmluZyk6IHsgYWxsb3dlZDogYm9vbGVhbjsgcmVhc29uPzogc3RyaW5nIH0ge1xuICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGZpbGVQYXRoLnNwbGl0KCcvJykucG9wKCkgfHwgZmlsZVBhdGg7XG4gICAgXG4gICAgLy8g5qOA5p+l5piv5ZCm5piv5L+d5oqk5paH5Lu2XG4gICAgaWYgKHRoaXMuY29uZmlnLnByb3RlY3RlZEZpbGVzLnNvbWUoZiA9PiBmaWxlUGF0aC5lbmRzV2l0aChmKSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYPCfmqggW0hhcm5lc3NdIOemgeatouWIoOmZpOS/neaKpOaWh+S7tu+8miR7ZmlsZVBhdGh9YCk7XG4gICAgICBcbiAgICAgIHRoaXMub3BlcmF0aW9uTG9nZ2VyLmxvZyh7XG4gICAgICAgIHNlc3Npb25JZDogc2Vzc2lvbklkIHx8ICd1bmtub3duJyxcbiAgICAgICAgbW9kaWZpZXI6ICdBSSBBZ2VudCcsXG4gICAgICAgIHR5cGU6ICdmaWxlX2RlbGV0ZScsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBg5bCd6K+V5Yig6Zmk5L+d5oqk5paH5Lu277yaJHtmaWxlUGF0aH1gLFxuICAgICAgICBmaWxlOiBmaWxlUGF0aCxcbiAgICAgICAgcmVzdWx0OiAnZXJyb3InLFxuICAgICAgfSk7XG4gICAgICBcbiAgICAgIHJldHVybiB7IGFsbG93ZWQ6IGZhbHNlLCByZWFzb246ICfkv53miqTmlofku7bnpoHmraLliKDpmaQnIH07XG4gICAgfVxuICAgIFxuICAgIHRoaXMub3BlcmF0aW9uTG9nZ2VyLmxvZyh7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCB8fCAndW5rbm93bicsXG4gICAgICBtb2RpZmllcjogJ0FJIEFnZW50JyxcbiAgICAgIHR5cGU6ICdmaWxlX2RlbGV0ZScsXG4gICAgICBkZXNjcmlwdGlvbjogYOWIoOmZpOaWh+S7tu+8miR7ZmlsZVBhdGh9YCxcbiAgICAgIGZpbGU6IGZpbGVQYXRoLFxuICAgICAgcmVzdWx0OiAnc3VjY2VzcycsXG4gICAgfSk7XG4gICAgXG4gICAgcmV0dXJuIHsgYWxsb3dlZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEhvb2s6IOezu+e7n+WRveS7pOaJp+ihjOWJjVxuICAgKi9cbiAgb25FeGVjQ29tbWFuZChjb21tYW5kOiBzdHJpbmcsIHNlc3Npb25JZD86IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMub3BlcmF0aW9uTG9nZ2VyLmxvZyh7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZCB8fCAndW5rbm93bicsXG4gICAgICBtb2RpZmllcjogJ0FJIEFnZW50JyxcbiAgICAgIHR5cGU6ICdzeXN0ZW1fY29tbWFuZCcsXG4gICAgICBkZXNjcmlwdGlvbjogYOaJp+ihjOWRveS7pO+8miR7Y29tbWFuZH1gLFxuICAgICAgY29tbWFuZCxcbiAgICAgIHJlc3VsdDogJ3BlbmRpbmcnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOiOt+WPluaPkuS7tueKtuaAgVxuICAgKi9cbiAgZ2V0U3RhdHVzKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgIHZlcnNpb246IHRoaXMudmVyc2lvbixcbiAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICBjb25maWc6IHRoaXMuY29uZmlnLFxuICAgICAgbG9vcFN0YXRzOiB0aGlzLmxvb3BEZXRlY3Rvci5nZXRTdGF0cygpLFxuICAgIH07XG4gIH1cbn1cblxuLy8gT3BlbkNsYXcg5o+S5Lu25bel5Y6C5Ye95pWwXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGx1Z2luKHdvcmtzcGFjZVBhdGg6IHN0cmluZywgY29uZmlnOiBhbnkpOiBIYXJuZXNzUGx1Z2luIHtcbiAgcmV0dXJuIG5ldyBIYXJuZXNzUGx1Z2luKHdvcmtzcGFjZVBhdGgsIGNvbmZpZyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEhhcm5lc3NQbHVnaW47XG4iXX0=
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HarnessPlugin } from './index.js';
|
|
2
|
+
export interface FileWatcherConfig {
|
|
3
|
+
watchFiles: string[];
|
|
4
|
+
debounceMs: number;
|
|
5
|
+
onFileChange: (filePath: string, newContent: any) => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare class FileWatcher {
|
|
8
|
+
private watchPaths;
|
|
9
|
+
private debounceTimers;
|
|
10
|
+
private config;
|
|
11
|
+
private plugin;
|
|
12
|
+
constructor(plugin: HarnessPlugin, config: FileWatcherConfig);
|
|
13
|
+
/**
|
|
14
|
+
* 开始监听文件
|
|
15
|
+
*/
|
|
16
|
+
start(): void;
|
|
17
|
+
/**
|
|
18
|
+
* 监听单个文件
|
|
19
|
+
*/
|
|
20
|
+
private watchFile;
|
|
21
|
+
/**
|
|
22
|
+
* 停止监听单个文件
|
|
23
|
+
*/
|
|
24
|
+
private unwatchFile;
|
|
25
|
+
/**
|
|
26
|
+
* 文件变化处理(带防抖)
|
|
27
|
+
*/
|
|
28
|
+
private onFileChange;
|
|
29
|
+
/**
|
|
30
|
+
* 处理文件变化
|
|
31
|
+
*/
|
|
32
|
+
private handleFileChange;
|
|
33
|
+
/**
|
|
34
|
+
* 停止所有监听
|
|
35
|
+
*/
|
|
36
|
+
stop(): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/file-watcher.ts - 配置文件监听器
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.FileWatcher = void 0;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
class FileWatcher {
|
|
40
|
+
watchPaths = new Map();
|
|
41
|
+
debounceTimers = new Map();
|
|
42
|
+
config;
|
|
43
|
+
plugin;
|
|
44
|
+
constructor(plugin, config) {
|
|
45
|
+
this.plugin = plugin;
|
|
46
|
+
this.config = config;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 开始监听文件
|
|
50
|
+
*/
|
|
51
|
+
start() {
|
|
52
|
+
console.log('👁️ [FileWatcher] 开始监听配置文件...');
|
|
53
|
+
for (const file of this.config.watchFiles) {
|
|
54
|
+
this.watchFile(file);
|
|
55
|
+
}
|
|
56
|
+
console.log(`👁️ [FileWatcher] 正在监听 ${this.config.watchFiles.length} 个文件`);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 监听单个文件
|
|
60
|
+
*/
|
|
61
|
+
watchFile(filePath) {
|
|
62
|
+
// 如果已经在监听,先停止
|
|
63
|
+
if (this.watchPaths.has(filePath)) {
|
|
64
|
+
this.unwatchFile(filePath);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const watcher = fs.watch(filePath, { persistent: false }, (eventType, filename) => {
|
|
68
|
+
if (eventType === 'change' || eventType === 'rename') {
|
|
69
|
+
console.log(`📝 [FileWatcher] 检测到文件变化:${filePath} (${eventType})`);
|
|
70
|
+
this.onFileChange(filePath);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
watcher.on('error', (error) => {
|
|
74
|
+
console.error(`❌ [FileWatcher] 监听错误 ${filePath}:`, error.message);
|
|
75
|
+
});
|
|
76
|
+
this.watchPaths.set(filePath, watcher);
|
|
77
|
+
console.log(`✅ [FileWatcher] 开始监听:${filePath}`);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.warn(`⚠️ [FileWatcher] 无法监听文件 ${filePath}: ${error.message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 停止监听单个文件
|
|
85
|
+
*/
|
|
86
|
+
unwatchFile(filePath) {
|
|
87
|
+
const watcher = this.watchPaths.get(filePath);
|
|
88
|
+
if (watcher) {
|
|
89
|
+
watcher.close();
|
|
90
|
+
this.watchPaths.delete(filePath);
|
|
91
|
+
console.log(`🛑 [FileWatcher] 停止监听:${filePath}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 文件变化处理(带防抖)
|
|
96
|
+
*/
|
|
97
|
+
async onFileChange(filePath) {
|
|
98
|
+
// 清除之前的定时器
|
|
99
|
+
const existingTimer = this.debounceTimers.get(filePath);
|
|
100
|
+
if (existingTimer) {
|
|
101
|
+
clearTimeout(existingTimer);
|
|
102
|
+
}
|
|
103
|
+
// 设置新的防抖定时器
|
|
104
|
+
const timer = setTimeout(async () => {
|
|
105
|
+
try {
|
|
106
|
+
await this.handleFileChange(filePath);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error(`❌ [FileWatcher] 处理文件变化失败 ${filePath}:`, error.message);
|
|
110
|
+
}
|
|
111
|
+
this.debounceTimers.delete(filePath);
|
|
112
|
+
}, this.config.debounceMs);
|
|
113
|
+
this.debounceTimers.set(filePath, timer);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 处理文件变化
|
|
117
|
+
*/
|
|
118
|
+
async handleFileChange(filePath) {
|
|
119
|
+
console.log(`🔍 [FileWatcher] 处理文件变化:${filePath}`);
|
|
120
|
+
// 读取新配置
|
|
121
|
+
let newConfig;
|
|
122
|
+
try {
|
|
123
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
124
|
+
newConfig = JSON.parse(content);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error(`❌ [FileWatcher] 读取配置失败:${error.message}`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// 调用插件的配置变更处理
|
|
131
|
+
await this.config.onFileChange(filePath, newConfig);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 停止所有监听
|
|
135
|
+
*/
|
|
136
|
+
stop() {
|
|
137
|
+
console.log('🛑 [FileWatcher] 停止所有文件监听...');
|
|
138
|
+
for (const [filePath, watcher] of this.watchPaths.entries()) {
|
|
139
|
+
watcher.close();
|
|
140
|
+
}
|
|
141
|
+
this.watchPaths.clear();
|
|
142
|
+
// 清除所有定时器
|
|
143
|
+
for (const [filePath, timer] of this.debounceTimers.entries()) {
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
}
|
|
146
|
+
this.debounceTimers.clear();
|
|
147
|
+
console.log('🛑 [FileWatcher] 已停止所有监听');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.FileWatcher = FileWatcher;
|
|
151
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS13YXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZpbGUtd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsZ0NBQWdDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFaEMsdUNBQXlCO0FBVXpCLE1BQWEsV0FBVztJQUNkLFVBQVUsR0FBOEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNsRCxjQUFjLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDeEQsTUFBTSxDQUFvQjtJQUMxQixNQUFNLENBQWdCO0lBRTlCLFlBQVksTUFBcUIsRUFBRSxNQUF5QjtRQUMxRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLO1FBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBRTdDLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7T0FFRztJQUNLLFNBQVMsQ0FBQyxRQUFnQjtRQUNoQyxjQUFjO1FBQ2QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFF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QUMsT0FBTyxLQUFVLEVBQUUsQ0FBQztZQUNwQixPQUFPLENBQUMsS0FBSyxDQUFDLDBCQUEwQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN6RCxPQUFPO1FBQ1QsQ0FBQztRQUVELGNBQWM7UUFDZCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJO1FBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBRTVDLEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDNUQsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRXhCLFVBQVU7UUFDVixLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQzlELFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixDQUFDO1FBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDMUMsQ0FBQztDQUNGO0FBL0hELGtDQStIQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNyYy9maWxlLXdhdGNoZXIudHMgLSDphY3nva7mlofku7bnm5HlkKzlmahcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB0eXBlIHsgSGFybmVzc1BsdWdpbiB9IGZyb20gJy4vaW5kZXguanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVXYXRjaGVyQ29uZmlnIHtcbiAgd2F0Y2hGaWxlczogc3RyaW5nW107XG4gIGRlYm91bmNlTXM6IG51bWJlcjtcbiAgb25GaWxlQ2hhbmdlOiAoZmlsZVBhdGg6IHN0cmluZywgbmV3Q29udGVudDogYW55KSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZVdhdGNoZXIge1xuICBwcml2YXRlIHdhdGNoUGF0aHM6IE1hcDxzdHJpbmcsIGZzLkZTV2F0Y2hlcj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZGVib3VuY2VUaW1lcnM6IE1hcDxzdHJpbmcsIE5vZGVKUy5UaW1lb3V0PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBjb25maWc6IEZpbGVXYXRjaGVyQ29uZmlnO1xuICBwcml2YXRlIHBsdWdpbjogSGFybmVzc1BsdWdpbjtcblxuICBjb25zdHJ1Y3RvcihwbHVnaW46IEhhcm5lc3NQbHVnaW4sIGNvbmZpZzogRmlsZVdhdGNoZXJDb25maWcpIHtcbiAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiDlvIDlp4vnm5HlkKzmlofku7ZcbiAgICovXG4gIHN0YXJ0KCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCfwn5GB77iPIFtGaWxlV2F0Y2hlcl0g5byA5aeL55uR5ZCs6YWN572u5paH5Lu2Li4uJyk7XG4gICAgXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIHRoaXMuY29uZmlnLndhdGNoRmlsZXMpIHtcbiAgICAgIHRoaXMud2F0Y2hGaWxlKGZpbGUpO1xuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZyhg8J+Rge+4jyBbRmlsZVdhdGNoZXJdIOato+WcqOebkeWQrCAke3RoaXMuY29uZmlnLndhdGNoRmlsZXMubGVuZ3RofSDkuKrmlofku7ZgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnm5HlkKzljZXkuKrmlofku7ZcbiAgICovXG4gIHByaXZhdGUgd2F0Y2hGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyDlpoLmnpzlt7Lnu4/lnKjnm5HlkKzvvIzlhYjlgZzmraJcbiAgICBpZiAodGhpcy53YXRjaFBhdGhzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgIHRoaXMudW53YXRjaEZpbGUoZmlsZVBhdGgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB3YXRjaGVyID0gZnMud2F0Y2goZmlsZVBhdGgsIHsgcGVyc2lzdGVudDogZmFsc2UgfSwgKGV2ZW50VHlwZSwgZmlsZW5hbWUpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gJ2NoYW5nZScgfHwgZXZlbnRUeXBlID09PSAncmVuYW1lJykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGDwn5OdIFtGaWxlV2F0Y2hlcl0g5qOA5rWL5Yiw5paH5Lu25Y+Y5YyW77yaJHtmaWxlUGF0aH0gKCR7ZXZlbnRUeXBlfSlgKTtcbiAgICAgICAgICB0aGlzLm9uRmlsZUNoYW5nZShmaWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB3YXRjaGVyLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKGDinYwgW0ZpbGVXYXRjaGVyXSDnm5HlkKzplJnor68gJHtmaWxlUGF0aH06YCwgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXRjaFBhdGhzLnNldChmaWxlUGF0aCwgd2F0Y2hlcik7XG4gICAgICBjb25zb2xlLmxvZyhg4pyFIFtGaWxlV2F0Y2hlcl0g5byA5aeL55uR5ZCs77yaJHtmaWxlUGF0aH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoO+4jyBbRmlsZVdhdGNoZXJdIOaXoOazleebkeWQrOaWh+S7tiAke2ZpbGVQYXRofTogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDlgZzmraLnm5HlkKzljZXkuKrmlofku7ZcbiAgICovXG4gIHByaXZhdGUgdW53YXRjaEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHdhdGNoZXIgPSB0aGlzLndhdGNoUGF0aHMuZ2V0KGZpbGVQYXRoKTtcbiAgICBpZiAod2F0Y2hlcikge1xuICAgICAgd2F0Y2hlci5jbG9zZSgpO1xuICAgICAgdGhpcy53YXRjaFBhdGhzLmRlbGV0ZShmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhg8J+bkSBbRmlsZVdhdGNoZXJdIOWBnOatouebkeWQrO+8miR7ZmlsZVBhdGh9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaWh+S7tuWPmOWMluWkhOeQhu+8iOW4pumYsuaKlu+8iVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvbkZpbGVDaGFuZ2UoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOa4hemZpOS5i+WJjeeahOWumuaXtuWZqFxuICAgIGNvbnN0IGV4aXN0aW5nVGltZXIgPSB0aGlzLmRlYm91bmNlVGltZXJzLmdldChmaWxlUGF0aCk7XG4gICAgaWYgKGV4aXN0aW5nVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dChleGlzdGluZ1RpbWVyKTtcbiAgICB9XG5cbiAgICAvLyDorr7nva7mlrDnmoTpmLLmipblrprml7blmahcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGaWxlQ2hhbmdlKGZpbGVQYXRoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihg4p2MIFtGaWxlV2F0Y2hlcl0g5aSE55CG5paH5Lu25Y+Y5YyW5aSx6LSlICR7ZmlsZVBhdGh9OmAsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWJvdW5jZVRpbWVycy5kZWxldGUoZmlsZVBhdGgpO1xuICAgIH0sIHRoaXMuY29uZmlnLmRlYm91bmNlTXMpO1xuXG4gICAgdGhpcy5kZWJvdW5jZVRpbWVycy5zZXQoZmlsZVBhdGgsIHRpbWVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlpITnkIbmlofku7blj5jljJZcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRmlsZUNoYW5nZShmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYPCflI0gW0ZpbGVXYXRjaGVyXSDlpITnkIbmlofku7blj5jljJbvvJoke2ZpbGVQYXRofWApO1xuXG4gICAgLy8g6K+75Y+W5paw6YWN572uXG4gICAgbGV0IG5ld0NvbmZpZzogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgbmV3Q29uZmlnID0gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGDinYwgW0ZpbGVXYXRjaGVyXSDor7vlj5bphY3nva7lpLHotKXvvJoke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g6LCD55So5o+S5Lu255qE6YWN572u5Y+Y5pu05aSE55CGXG4gICAgYXdhaXQgdGhpcy5jb25maWcub25GaWxlQ2hhbmdlKGZpbGVQYXRoLCBuZXdDb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWBnOatouaJgOacieebkeWQrFxuICAgKi9cbiAgc3RvcCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygn8J+bkSBbRmlsZVdhdGNoZXJdIOWBnOatouaJgOacieaWh+S7tuebkeWQrC4uLicpO1xuICAgIFxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCB3YXRjaGVyXSBvZiB0aGlzLndhdGNoUGF0aHMuZW50cmllcygpKSB7XG4gICAgICB3YXRjaGVyLmNsb3NlKCk7XG4gICAgfVxuICAgIFxuICAgIHRoaXMud2F0Y2hQYXRocy5jbGVhcigpO1xuICAgIFxuICAgIC8vIOa4hemZpOaJgOacieWumuaXtuWZqFxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCB0aW1lcl0gb2YgdGhpcy5kZWJvdW5jZVRpbWVycy5lbnRyaWVzKCkpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgfVxuICAgIFxuICAgIHRoaXMuZGVib3VuY2VUaW1lcnMuY2xlYXIoKTtcbiAgICBjb25zb2xlLmxvZygn8J+bkSBbRmlsZVdhdGNoZXJdIOW3suWBnOatouaJgOacieebkeWQrCcpO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export interface HarnessPluginConfig {
|
|
2
|
+
autoValidateConfig: boolean;
|
|
3
|
+
autoAuditSkill: boolean;
|
|
4
|
+
loopDetectionEnabled: boolean;
|
|
5
|
+
protectedFiles: string[];
|
|
6
|
+
logsDir: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class HarnessPlugin {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
private config;
|
|
12
|
+
private workspacePath;
|
|
13
|
+
private configValidator;
|
|
14
|
+
private skillAuditor;
|
|
15
|
+
private loopDetector;
|
|
16
|
+
private configLogger;
|
|
17
|
+
private operationLogger;
|
|
18
|
+
private traceLogger;
|
|
19
|
+
constructor(workspacePath: string, config?: Partial<HarnessPluginConfig>);
|
|
20
|
+
/**
|
|
21
|
+
* Hook: 配置修改前验证
|
|
22
|
+
*/
|
|
23
|
+
onConfigChange(newConfig: any, sessionId?: string): Promise<{
|
|
24
|
+
valid: boolean;
|
|
25
|
+
errors?: string[];
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* 公开方法:记录配置变更
|
|
29
|
+
*/
|
|
30
|
+
logConfigChange(entry: {
|
|
31
|
+
sessionId: string;
|
|
32
|
+
modifier: string;
|
|
33
|
+
file: string;
|
|
34
|
+
reason: string;
|
|
35
|
+
verified: boolean;
|
|
36
|
+
gatewayRestarted: boolean;
|
|
37
|
+
changes: any[];
|
|
38
|
+
}): void;
|
|
39
|
+
/**
|
|
40
|
+
* Hook: Skill 安装前审核
|
|
41
|
+
*/
|
|
42
|
+
onSkillInstall(skillPath: string, source?: string, sessionId?: string): Promise<{
|
|
43
|
+
passed: boolean;
|
|
44
|
+
warnings?: any[];
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Hook: 文件编辑时循环检测
|
|
48
|
+
*/
|
|
49
|
+
onFileEdit(filePath: string, sessionId?: string): {
|
|
50
|
+
allowed: boolean;
|
|
51
|
+
warning?: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Hook: 文件删除前检查
|
|
55
|
+
*/
|
|
56
|
+
onFileDelete(filePath: string, sessionId?: string): {
|
|
57
|
+
allowed: boolean;
|
|
58
|
+
reason?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Hook: 系统命令执行前
|
|
62
|
+
*/
|
|
63
|
+
onExecCommand(command: string, sessionId?: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* 获取插件状态
|
|
66
|
+
*/
|
|
67
|
+
getStatus(): any;
|
|
68
|
+
}
|
|
69
|
+
export declare function createPlugin(workspacePath: string, config: any): HarnessPlugin;
|
|
70
|
+
export default HarnessPlugin;
|