@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.

Files changed (41) hide show
  1. package/README.md +97 -114
  2. package/dist/core/auditors/index.d.ts +2 -0
  3. package/dist/core/auditors/index.js +7 -0
  4. package/dist/core/auditors/skill-auditor.d.ts +72 -0
  5. package/dist/core/auditors/skill-auditor.js +488 -0
  6. package/dist/core/index.d.ts +22 -0
  7. package/dist/core/index.js +47 -0
  8. package/dist/core/loggers/config-logger.d.ts +25 -0
  9. package/dist/core/loggers/config-logger.js +139 -0
  10. package/dist/core/loggers/index.d.ts +4 -0
  11. package/dist/core/loggers/index.js +9 -0
  12. package/dist/core/loggers/operation-logger.d.ts +23 -0
  13. package/dist/core/loggers/operation-logger.js +125 -0
  14. package/dist/core/middleware/context-injector.d.ts +25 -0
  15. package/dist/core/middleware/context-injector.js +174 -0
  16. package/dist/core/middleware/index.d.ts +5 -0
  17. package/dist/core/middleware/index.js +11 -0
  18. package/dist/core/middleware/loop-detector.d.ts +18 -0
  19. package/dist/core/middleware/loop-detector.js +125 -0
  20. package/dist/core/middleware/trace-logger.d.ts +34 -0
  21. package/dist/core/middleware/trace-logger.js +141 -0
  22. package/dist/core/utils/file.d.ts +28 -0
  23. package/dist/core/utils/file.js +104 -0
  24. package/dist/core/utils/format.d.ts +16 -0
  25. package/dist/core/utils/format.js +60 -0
  26. package/dist/core/utils/index.d.ts +2 -0
  27. package/dist/core/utils/index.js +14 -0
  28. package/dist/core/validators/config-validator.d.ts +25 -0
  29. package/dist/core/validators/config-validator.js +235 -0
  30. package/dist/core/validators/index.d.ts +2 -0
  31. package/dist/core/validators/index.js +7 -0
  32. package/dist/file-watcher.d.ts +37 -0
  33. package/dist/file-watcher.js +151 -0
  34. package/dist/index.d.ts +63 -0
  35. package/dist/index.js +166 -106
  36. package/dist/src/file-watcher.d.ts +37 -0
  37. package/dist/src/file-watcher.js +151 -0
  38. package/dist/src/index.d.ts +70 -0
  39. package/dist/src/index.js +192 -0
  40. package/package.json +4 -12
  41. 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
- const harness_1 = require("@hddz/harness");
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: 'workspace/logs/harness',
19
+ logsDir: 'logs/harness', // 相对 workspace 的路径
18
20
  };
19
- const harnessPlugin = {
20
- id: 'harness',
21
- name: 'Harness Engineering',
22
- description: 'Constraints, feedback loops, and control systems for AI agents',
23
- kind: 'engineering',
24
- configSchema: {
25
- type: 'object',
26
- additionalProperties: false,
27
- properties: {
28
- autoValidateConfig: { type: 'boolean', default: true },
29
- autoAuditSkill: { type: 'boolean', default: true },
30
- loopDetectionEnabled: { type: 'boolean', default: true },
31
- protectedFiles: { type: 'array', items: { type: 'string' } },
32
- logsDir: { type: 'string', default: 'workspace/logs/harness' },
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
- const configValidator = new harness_1.ConfigValidator(workspacePath);
40
- const skillAuditor = new harness_1.SkillAuditor(workspacePath);
41
- const loopDetector = new harness_1.LoopDetector(workspacePath, { limit: 5, windowMs: 300000 });
42
- const configLogger = new harness_1.ConfigLogger(workspacePath);
43
- const operationLogger = new harness_1.OperationLogger(workspacePath);
44
- const traceLogger = new harness_1.TraceLogger(workspacePath);
45
- api.logger.info('[Harness] 插件已加载,工作空间:', workspacePath);
46
- // Hook: 配置修改前验证
47
- if (config.autoValidateConfig) {
48
- api.onConfigChange?.(async (newConfig, sessionId) => {
49
- api.logger.info('🔍 [Harness] 验证配置变更...');
50
- const result = configValidator.validateContent(newConfig);
51
- if (!result.valid) {
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
- // Hook: 文件编辑时循环检测
91
- if (config.loopDetectionEnabled) {
92
- api.onFileEdit?.(async (filePath, content) => {
93
- const warning = loopDetector.onFileEdit(filePath);
94
- if (warning) {
95
- api.logger.warn('⚠️ [Harness] 检测到频繁编辑:');
96
- api.logger.warn(` 文件:${filePath}`);
97
- api.logger.warn(` 警告:${warning}`);
98
- throw new Error(`检测到循环编辑:${warning}`);
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
- // Hook: 文件删除前检查保护文件
103
- api.onFileDelete?.(async (filePath) => {
104
- const fileName = filePath.split('/').pop() || filePath;
105
- if (config.protectedFiles.includes(fileName)) {
106
- api.logger.error(`❌ [Harness] 阻止删除保护文件:${filePath}`);
107
- throw new Error(`不允许删除保护文件:${fileName}`);
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
- // Hook: 命令执行审计
111
- api.onExecCommand?.(async (command, options) => {
112
- operationLogger.log({
113
- sessionId: options?.sessionId || 'unknown',
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: 'system_command',
116
- description: `执行命令:${command}`,
117
- command,
118
+ type: 'file_edit',
119
+ description: `保护文件修改:${filePath}`,
120
+ file: filePath,
118
121
  result: 'success',
119
122
  });
120
- traceLogger.log({
121
- sessionId: options?.sessionId || 'unknown',
122
- type: 'tool_call',
123
- data: { tool: 'exec', command },
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
- api.logger.info('✅ [Harness] 所有 Hook 已注册');
127
- },
128
- };
129
- // CommonJS 导出(OpenClaw 期望的格式)
130
- // @ts-ignore
131
- module.exports = harnessPlugin;
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;