@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
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ // src/validators/config-validator.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.ConfigValidator = void 0;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ class ConfigValidator {
41
+ workspacePath;
42
+ configPath;
43
+ constructor(workspacePath) {
44
+ this.workspacePath = workspacePath;
45
+ // OpenClaw 配置文件在 workspace 的父目录
46
+ this.configPath = path.join(workspacePath, '..', 'openclaw.json');
47
+ }
48
+ /**
49
+ * 验证配置内容(用于包装层拦截)
50
+ */
51
+ validateContent(config) {
52
+ const result = { valid: true, errors: [], warnings: [], info: [] };
53
+ // 检查是否是有效的对象
54
+ if (!config || typeof config !== 'object') {
55
+ result.valid = false;
56
+ result.errors.push('配置必须是有效的 JSON 对象');
57
+ return result;
58
+ }
59
+ // 检查必填字段
60
+ const requiredFields = ['models', 'plugins', 'gateway'];
61
+ requiredFields.forEach(field => {
62
+ if (!config[field]) {
63
+ result.valid = false;
64
+ result.errors.push(`缺少必填字段:${field}`);
65
+ }
66
+ });
67
+ // 检查 models 配置
68
+ if (config.models) {
69
+ if (!config.models.providers || Object.keys(config.models.providers).length === 0) {
70
+ result.warnings.push('未配置任何模型提供商');
71
+ }
72
+ else {
73
+ const providers = Object.keys(config.models.providers);
74
+ result.info.push(`已配置模型提供商:${providers.join(', ')}`);
75
+ }
76
+ if (config.models.defaultModel && !config.models.defaultModel.includes('/')) {
77
+ result.warnings.push('defaultModel 格式可能不正确(应为 provider/model-name)');
78
+ }
79
+ }
80
+ // 检查 gateway 配置
81
+ if (config.gateway) {
82
+ if (config.gateway.port) {
83
+ if (config.gateway.port < 1024 || config.gateway.port > 65535) {
84
+ result.valid = false;
85
+ result.errors.push(`无效的端口号:${config.gateway.port}`);
86
+ }
87
+ else {
88
+ result.info.push(`Gateway 端口:${config.gateway.port}`);
89
+ }
90
+ }
91
+ if (config.gateway.host) {
92
+ result.info.push(`Gateway 主机:${config.gateway.host}`);
93
+ }
94
+ }
95
+ // 检查 plugins 配置
96
+ if (config.plugins && config.plugins.entries) {
97
+ const pluginEntries = Object.entries(config.plugins.entries);
98
+ const enabledPlugins = pluginEntries
99
+ .filter(([_, plugin]) => plugin.enabled)
100
+ .map(([name, _]) => name);
101
+ if (enabledPlugins.length > 0) {
102
+ result.info.push(`已启用插件:${enabledPlugins.join(', ')}`);
103
+ }
104
+ pluginEntries.forEach(([name, plugin]) => {
105
+ if (plugin.enabled && !plugin.config) {
106
+ result.warnings.push(`插件 ${name} 已启用但缺少配置`);
107
+ }
108
+ });
109
+ }
110
+ return result;
111
+ }
112
+ validate(configPath) {
113
+ const pathToValidate = configPath || this.configPath;
114
+ const result = { valid: true, errors: [], warnings: [], info: [] };
115
+ // 检查文件存在
116
+ if (!fs.existsSync(pathToValidate)) {
117
+ result.valid = false;
118
+ result.errors.push(`配置文件不存在:${pathToValidate}`);
119
+ return result;
120
+ }
121
+ // 检查 JSON 格式
122
+ let config;
123
+ try {
124
+ const content = fs.readFileSync(pathToValidate, 'utf8');
125
+ config = JSON.parse(content);
126
+ result.info.push(`配置文件大小:${(content.length / 1024).toFixed(2)} KB`);
127
+ }
128
+ catch (e) {
129
+ result.valid = false;
130
+ result.errors.push(`JSON 格式错误:${e.message}`);
131
+ return result;
132
+ }
133
+ // 检查必填字段
134
+ const requiredFields = ['models', 'plugins', 'gateway'];
135
+ requiredFields.forEach(field => {
136
+ if (!config[field]) {
137
+ result.valid = false;
138
+ result.errors.push(`缺少必填字段:${field}`);
139
+ }
140
+ });
141
+ // 检查 models 配置
142
+ if (config.models) {
143
+ if (!config.models.providers || Object.keys(config.models.providers).length === 0) {
144
+ result.warnings.push('未配置任何模型提供商');
145
+ }
146
+ else {
147
+ const providers = Object.keys(config.models.providers);
148
+ result.info.push(`已配置模型提供商:${providers.join(', ')}`);
149
+ }
150
+ if (config.models.defaultModel && !config.models.defaultModel.includes('/')) {
151
+ result.warnings.push('defaultModel 格式可能不正确(应为 provider/model-name)');
152
+ }
153
+ }
154
+ // 检查 gateway 配置
155
+ if (config.gateway) {
156
+ if (config.gateway.port) {
157
+ if (config.gateway.port < 1024 || config.gateway.port > 65535) {
158
+ result.valid = false;
159
+ result.errors.push(`无效的端口号:${config.gateway.port}`);
160
+ }
161
+ else {
162
+ result.info.push(`Gateway 端口:${config.gateway.port}`);
163
+ }
164
+ }
165
+ if (config.gateway.host) {
166
+ result.info.push(`Gateway 主机:${config.gateway.host}`);
167
+ }
168
+ }
169
+ // 检查 plugins 配置
170
+ if (config.plugins && config.plugins.entries) {
171
+ const pluginEntries = Object.entries(config.plugins.entries);
172
+ const enabledPlugins = pluginEntries
173
+ .filter(([_, plugin]) => plugin.enabled)
174
+ .map(([name, _]) => name);
175
+ if (enabledPlugins.length > 0) {
176
+ result.info.push(`已启用插件:${enabledPlugins.join(', ')}`);
177
+ }
178
+ pluginEntries.forEach(([name, plugin]) => {
179
+ if (plugin.enabled && !plugin.config) {
180
+ result.warnings.push(`插件 ${name} 已启用但缺少配置`);
181
+ }
182
+ });
183
+ }
184
+ // 检查记忆配置
185
+ if (config.memory) {
186
+ if (config.memory.maxSummaryDays) {
187
+ result.info.push(`记忆摘要天数:${config.memory.maxSummaryDays}`);
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ validateAndThrow(configPath) {
193
+ const result = this.validate(configPath);
194
+ if (!result.valid) {
195
+ throw new Error(`配置验证失败:\n${result.errors.join('\n')}`);
196
+ }
197
+ }
198
+ /**
199
+ * 比较两个配置的差异
200
+ */
201
+ diffConfigs(oldConfigPath, newConfigPath) {
202
+ const changes = [];
203
+ try {
204
+ const oldConfig = JSON.parse(fs.readFileSync(oldConfigPath, 'utf8'));
205
+ const newConfig = JSON.parse(fs.readFileSync(newConfigPath, 'utf8'));
206
+ const compare = (oldObj, newObj, path = '') => {
207
+ const allKeys = new Set([...Object.keys(oldObj || {}), ...Object.keys(newObj || {})]);
208
+ for (const key of allKeys) {
209
+ const fullPath = path ? `${path}.${key}` : key;
210
+ const oldVal = oldObj?.[key];
211
+ const newVal = newObj?.[key];
212
+ if (typeof oldVal === 'object' && typeof newVal === 'object' &&
213
+ oldVal !== null && newVal !== null &&
214
+ !Array.isArray(oldVal) && !Array.isArray(newVal)) {
215
+ compare(oldVal, newVal, fullPath);
216
+ }
217
+ else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
218
+ changes.push({
219
+ field: fullPath,
220
+ oldValue: oldVal,
221
+ newValue: newVal,
222
+ });
223
+ }
224
+ }
225
+ };
226
+ compare(oldConfig, newConfig);
227
+ }
228
+ catch (error) {
229
+ // 忽略错误
230
+ }
231
+ return changes;
232
+ }
233
+ }
234
+ exports.ConfigValidator = ConfigValidator;
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLXZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb3JlL3ZhbGlkYXRvcnMvY29uZmlnLXZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNkNBQTZDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFN0MsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQVM3QixNQUFhLGVBQWU7SUFHTjtJQUZaLFVBQVUsQ0FBUztJQUUzQixZQUFvQixhQUFxQjtRQUFyQixrQkFBYSxHQUFiLGFBQWEsQ0FBUTtRQUN2QyxnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZUFBZSxDQUFDLE1BQVc7UUFDekIsTUFBTSxNQUFNLEdBQXFCLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBRXJGLGFBQWE7UUFDYixJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDdkMsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUVELFNBQVM7UUFDVCxNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDeEQsY0FBYyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ25CLE1B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LFFBQVE7d0JBQ3hELE1BQU0sS0FBSyxJQUFJLElBQUksTUFBTSxLQUFLLElBQUk7d0JBQ2xDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQzt3QkFDckQsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7b0JBQ3BDLENBQUM7eUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQzt3QkFDN0QsT0FBTyxDQUFDLElBQUksQ0FBQzs0QkFDWCxLQUFLLEVBQUUsUUFBUTs0QkFDZixRQUFRLEVBQUUsTUFBTTs0QkFDaEIsUUFBUSxFQUFFLE1BQU07eUJBQ2pCLENBQUMsQ0FBQztvQkFDTCxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDLENBQUM7WUFFRixPQUFPLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTztRQUNULENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQ0Y7QUE3TkQsMENBNk5DIiwic291cmNlc0NvbnRlbnQiOlsiLy8gc3JjL3ZhbGlkYXRvcnMvY29uZmlnLXZhbGlkYXRvci50cyAtIOmFjee9rumqjOivgeWZqFxuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZhbGlkYXRpb25SZXN1bHQge1xuICB2YWxpZDogYm9vbGVhbjtcbiAgZXJyb3JzOiBzdHJpbmdbXTtcbiAgd2FybmluZ3M6IHN0cmluZ1tdO1xuICBpbmZvOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGNsYXNzIENvbmZpZ1ZhbGlkYXRvciB7XG4gIHByaXZhdGUgY29uZmlnUGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgd29ya3NwYWNlUGF0aDogc3RyaW5nKSB7XG4gICAgLy8gT3BlbkNsYXcg6YWN572u5paH5Lu25ZyoIHdvcmtzcGFjZSDnmoTniLbnm67lvZVcbiAgICB0aGlzLmNvbmZpZ1BhdGggPSBwYXRoLmpvaW4od29ya3NwYWNlUGF0aCwgJy4uJywgJ29wZW5jbGF3Lmpzb24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDpqozor4HphY3nva7lhoXlrrnvvIjnlKjkuo7ljIXoo4XlsYLmi6bmiKrvvIlcbiAgICovXG4gIHZhbGlkYXRlQ29udGVudChjb25maWc6IGFueSk6IFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdDogVmFsaWRhdGlvblJlc3VsdCA9IHsgdmFsaWQ6IHRydWUsIGVycm9yczogW10sIHdhcm5pbmdzOiBbXSwgaW5mbzogW10gfTtcblxuICAgIC8vIOajgOafpeaYr+WQpuaYr+acieaViOeahOWvueixoVxuICAgIGlmICghY29uZmlnIHx8IHR5cGVvZiBjb25maWcgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXN1bHQudmFsaWQgPSBmYWxzZTtcbiAgICAgIHJlc3VsdC5lcnJvcnMucHVzaCgn6YWN572u5b+F6aG75piv5pyJ5pWI55qEIEpTT04g5a+56LGhJyk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIOajgOafpeW/heWhq+Wtl+autVxuICAgIGNvbnN0IHJlcXVpcmVkRmllbGRzID0gWydtb2RlbHMnLCAncGx1Z2lucycsICdnYXRld2F5J107XG4gICAgcmVxdWlyZWRGaWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICBpZiAoIWNvbmZpZ1tmaWVsZF0pIHtcbiAgICAgICAgcmVzdWx0LnZhbGlkID0gZmFsc2U7XG4gICAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChg57y65bCR5b+F5aGr5a2X5q6177yaJHtmaWVsZH1gKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIOajgOafpSBtb2RlbHMg6YWN572uXG4gICAgaWYgKGNvbmZpZy5tb2RlbHMpIHtcbiAgICAgIGlmICghY29uZmlnLm1vZGVscy5wcm92aWRlcnMgfHwgT2JqZWN0LmtleXMoY29uZmlnLm1vZGVscy5wcm92aWRlcnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXN1bHQud2FybmluZ3MucHVzaCgn5pyq6YWN572u5Lu75L2V5qih5Z6L5o+Q5L6b5ZWGJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhjb25maWcubW9kZWxzLnByb3ZpZGVycyk7XG4gICAgICAgIHJlc3VsdC5pbmZvLnB1c2goYOW3sumFjee9ruaooeWei+aPkOS+m+WVhu+8miR7cHJvdmlkZXJzLmpvaW4oJywgJyl9YCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcubW9kZWxzLmRlZmF1bHRNb2RlbCAmJiAhY29uZmlnLm1vZGVscy5kZWZhdWx0TW9kZWwuaW5jbHVkZXMoJy8nKSkge1xuICAgICAgICByZXN1bHQud2FybmluZ3MucHVzaCgnZGVmYXVsdE1vZGVsIOagvOW8j+WPr+iDveS4jeato+ehru+8iOW6lOS4uiBwcm92aWRlci9tb2RlbC1uYW1l77yJJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g5qOA5p+lIGdhdGV3YXkg6YWN572uXG4gICAgaWYgKGNvbmZpZy5nYXRld2F5KSB7XG4gICAgICBpZiAoY29uZmlnLmdhdGV3YXkucG9ydCkge1xuICAgICAgICBpZiAoY29uZmlnLmdhdGV3YXkucG9ydCA8IDEwMjQgfHwgY29uZmlnLmdhdGV3YXkucG9ydCA+IDY1NTM1KSB7XG4gICAgICAgICAgcmVzdWx0LnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgcmVzdWx0LmVycm9ycy5wdXNoKGDml6DmlYjnmoTnq6/lj6Plj7fvvJoke2NvbmZpZy5nYXRld2F5LnBvcnR9YCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0LmluZm8ucHVzaChgR2F0ZXdheSDnq6/lj6PvvJoke2NvbmZpZy5nYXRld2F5LnBvcnR9YCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5nYXRld2F5Lmhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmluZm8ucHVzaChgR2F0ZXdheSDkuLvmnLrvvJoke2NvbmZpZy5nYXRld2F5Lmhvc3R9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g5qOA5p+lIHBsdWdpbnMg6YWN572uXG4gICAgaWYgKGNvbmZpZy5wbHVnaW5zICYmIGNvbmZpZy5wbHVnaW5zLmVudHJpZXMpIHtcbiAgICAgIGNvbnN0IHBsdWdpbkVudHJpZXMgPSBPYmplY3QuZW50cmllcyhjb25maWcucGx1Z2lucy5lbnRyaWVzKTtcbiAgICAgIGNvbnN0IGVuYWJsZWRQbHVnaW5zID0gcGx1Z2luRW50cmllc1xuICAgICAgICAuZmlsdGVyKChbXywgcGx1Z2luXTogW3N0cmluZywgYW55XSkgPT4gcGx1Z2luLmVuYWJsZWQpXG4gICAgICAgIC5tYXAoKFtuYW1lLCBfXSkgPT4gbmFtZSk7XG4gICAgICBcbiAgICAgIGlmIChlbmFibGVkUGx1Z2lucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlc3VsdC5pbmZvLnB1c2goYOW3suWQr+eUqOaPkuS7tu+8miR7ZW5hYmxlZFBsdWdpbnMuam9pbignLCAnKX1gKTtcbiAgICAgIH1cblxuICAgICAgcGx1Z2luRW50cmllcy5mb3JFYWNoKChbbmFtZSwgcGx1Z2luXTogW3N0cmluZywgYW55XSkgPT4ge1xuICAgICAgICBpZiAocGx1Z2luLmVuYWJsZWQgJiYgIXBsdWdpbi5jb25maWcpIHtcbiAgICAgICAgICByZXN1bHQud2FybmluZ3MucHVzaChg5o+S5Lu2ICR7bmFtZX0g5bey5ZCv55So5L2G57y65bCR6YWN572uYCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB2YWxpZGF0ZShjb25maWdQYXRoPzogc3RyaW5nKTogVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgY29uc3QgcGF0aFRvVmFsaWRhdGUgPSBjb25maWdQYXRoIHx8IHRoaXMuY29uZmlnUGF0aDtcbiAgICBjb25zdCByZXN1bHQ6IFZhbGlkYXRpb25SZXN1bHQgPSB7IHZhbGlkOiB0cnVlLCBlcnJvcnM6IFtdLCB3YXJuaW5nczogW10sIGluZm86IFtdIH07XG5cbiAgICAvLyDmo4Dmn6Xmlofku7blrZjlnKhcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMocGF0aFRvVmFsaWRhdGUpKSB7XG4gICAgICByZXN1bHQudmFsaWQgPSBmYWxzZTtcbiAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChg6YWN572u5paH5Lu25LiN5a2Y5Zyo77yaJHtwYXRoVG9WYWxpZGF0ZX1gKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8g5qOA5p+lIEpTT04g5qC85byPXG4gICAgbGV0IGNvbmZpZzogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHBhdGhUb1ZhbGlkYXRlLCAndXRmOCcpO1xuICAgICAgY29uZmlnID0gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICAgIHJlc3VsdC5pbmZvLnB1c2goYOmFjee9ruaWh+S7tuWkp+Wwj++8miR7KGNvbnRlbnQubGVuZ3RoIC8gMTAyNCkudG9GaXhlZCgyKX0gS0JgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHJlc3VsdC52YWxpZCA9IGZhbHNlO1xuICAgICAgcmVzdWx0LmVycm9ycy5wdXNoKGBKU09OIOagvOW8j+mUmeivr++8miR7ZS5tZXNzYWdlfWApO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyDmo4Dmn6Xlv4XloavlrZfmrrVcbiAgICBjb25zdCByZXF1aXJlZEZpZWxkcyA9IFsnbW9kZWxzJywgJ3BsdWdpbnMnLCAnZ2F0ZXdheSddO1xuICAgIHJlcXVpcmVkRmllbGRzLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgaWYgKCFjb25maWdbZmllbGRdKSB7XG4gICAgICAgIHJlc3VsdC52YWxpZCA9IGZhbHNlO1xuICAgICAgICByZXN1bHQuZXJyb3JzLnB1c2goYOe8uuWwkeW/heWhq+Wtl+aute+8miR7ZmllbGR9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyDmo4Dmn6UgbW9kZWxzIOmFjee9rlxuICAgIGlmIChjb25maWcubW9kZWxzKSB7XG4gICAgICBpZiAoIWNvbmZpZy5tb2RlbHMucHJvdmlkZXJzIHx8IE9iamVjdC5rZXlzKGNvbmZpZy5tb2RlbHMucHJvdmlkZXJzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goJ+acqumFjee9ruS7u+S9leaooeWei+aPkOS+m+WVhicpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXJzID0gT2JqZWN0LmtleXMoY29uZmlnLm1vZGVscy5wcm92aWRlcnMpO1xuICAgICAgICByZXN1bHQuaW5mby5wdXNoKGDlt7LphY3nva7mqKHlnovmj5DkvpvllYbvvJoke3Byb3ZpZGVycy5qb2luKCcsICcpfWApO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29uZmlnLm1vZGVscy5kZWZhdWx0TW9kZWwgJiYgIWNvbmZpZy5tb2RlbHMuZGVmYXVsdE1vZGVsLmluY2x1ZGVzKCcvJykpIHtcbiAgICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goJ2RlZmF1bHRNb2RlbCDmoLzlvI/lj6/og73kuI3mraPnoa7vvIjlupTkuLogcHJvdmlkZXIvbW9kZWwtbmFtZe+8iScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOajgOafpSBnYXRld2F5IOmFjee9rlxuICAgIGlmIChjb25maWcuZ2F0ZXdheSkge1xuICAgICAgaWYgKGNvbmZpZy5nYXRld2F5LnBvcnQpIHtcbiAgICAgICAgaWYgKGNvbmZpZy5nYXRld2F5LnBvcnQgPCAxMDI0IHx8IGNvbmZpZy5nYXRld2F5LnBvcnQgPiA2NTUzNSkge1xuICAgICAgICAgIHJlc3VsdC52YWxpZCA9IGZhbHNlO1xuICAgICAgICAgIHJlc3VsdC5lcnJvcnMucHVzaChg5peg5pWI55qE56uv5Y+j5Y+377yaJHtjb25maWcuZ2F0ZXdheS5wb3J0fWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdC5pbmZvLnB1c2goYEdhdGV3YXkg56uv5Y+j77yaJHtjb25maWcuZ2F0ZXdheS5wb3J0fWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcuZ2F0ZXdheS5ob3N0KSB7XG4gICAgICAgIHJlc3VsdC5pbmZvLnB1c2goYEdhdGV3YXkg5Li75py677yaJHtjb25maWcuZ2F0ZXdheS5ob3N0fWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOajgOafpSBwbHVnaW5zIOmFjee9rlxuICAgIGlmIChjb25maWcucGx1Z2lucyAmJiBjb25maWcucGx1Z2lucy5lbnRyaWVzKSB7XG4gICAgICBjb25zdCBwbHVnaW5FbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoY29uZmlnLnBsdWdpbnMuZW50cmllcyk7XG4gICAgICBjb25zdCBlbmFibGVkUGx1Z2lucyA9IHBsdWdpbkVudHJpZXNcbiAgICAgICAgLmZpbHRlcigoW18sIHBsdWdpbl06IFtzdHJpbmcsIGFueV0pID0+IHBsdWdpbi5lbmFibGVkKVxuICAgICAgICAubWFwKChbbmFtZSwgX10pID0+IG5hbWUpO1xuICAgICAgXG4gICAgICBpZiAoZW5hYmxlZFBsdWdpbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXN1bHQuaW5mby5wdXNoKGDlt7LlkK/nlKjmj5Lku7bvvJoke2VuYWJsZWRQbHVnaW5zLmpvaW4oJywgJyl9YCk7XG4gICAgICB9XG5cbiAgICAgIHBsdWdpbkVudHJpZXMuZm9yRWFjaCgoW25hbWUsIHBsdWdpbl06IFtzdHJpbmcsIGFueV0pID0+IHtcbiAgICAgICAgaWYgKHBsdWdpbi5lbmFibGVkICYmICFwbHVnaW4uY29uZmlnKSB7XG4gICAgICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goYOaPkuS7tiAke25hbWV9IOW3suWQr+eUqOS9hue8uuWwkemFjee9rmApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyDmo4Dmn6XorrDlv4bphY3nva5cbiAgICBpZiAoY29uZmlnLm1lbW9yeSkge1xuICAgICAgaWYgKGNvbmZpZy5tZW1vcnkubWF4U3VtbWFyeURheXMpIHtcbiAgICAgICAgcmVzdWx0LmluZm8ucHVzaChg6K6w5b+G5pGY6KaB5aSp5pWw77yaJHtjb25maWcubWVtb3J5Lm1heFN1bW1hcnlEYXlzfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB2YWxpZGF0ZUFuZFRocm93KGNvbmZpZ1BhdGg/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnZhbGlkYXRlKGNvbmZpZ1BhdGgpO1xuICAgIGlmICghcmVzdWx0LnZhbGlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYOmFjee9rumqjOivgeWksei0pTpcXG4ke3Jlc3VsdC5lcnJvcnMuam9pbignXFxuJyl9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOavlOi+g+S4pOS4qumFjee9rueahOW3ruW8glxuICAgKi9cbiAgZGlmZkNvbmZpZ3Mob2xkQ29uZmlnUGF0aDogc3RyaW5nLCBuZXdDb25maWdQYXRoOiBzdHJpbmcpOiBBcnJheTx7XG4gICAgZmllbGQ6IHN0cmluZztcbiAgICBvbGRWYWx1ZTogYW55O1xuICAgIG5ld1ZhbHVlOiBhbnk7XG4gIH0+IHtcbiAgICBjb25zdCBjaGFuZ2VzOiBBcnJheTx7IGZpZWxkOiBzdHJpbmc7IG9sZFZhbHVlOiBhbnk7IG5ld1ZhbHVlOiBhbnkgfT4gPSBbXTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBvbGRDb25maWcgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhvbGRDb25maWdQYXRoLCAndXRmOCcpKTtcbiAgICAgIGNvbnN0IG5ld0NvbmZpZyA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKG5ld0NvbmZpZ1BhdGgsICd1dGY4JykpO1xuXG4gICAgICBjb25zdCBjb21wYXJlID0gKG9sZE9iajogYW55LCBuZXdPYmo6IGFueSwgcGF0aDogc3RyaW5nID0gJycpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgYWxsS2V5cyA9IG5ldyBTZXQoWy4uLk9iamVjdC5rZXlzKG9sZE9iaiB8fCB7fSksIC4uLk9iamVjdC5rZXlzKG5ld09iaiB8fCB7fSldKTtcbiAgICAgICAgXG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFsbEtleXMpIHtcbiAgICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGggPyBgJHtwYXRofS4ke2tleX1gIDoga2V5O1xuICAgICAgICAgIGNvbnN0IG9sZFZhbCA9IG9sZE9iaj8uW2tleV07XG4gICAgICAgICAgY29uc3QgbmV3VmFsID0gbmV3T2JqPy5ba2V5XTtcblxuICAgICAgICAgIGlmICh0eXBlb2Ygb2xkVmFsID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbmV3VmFsID09PSAnb2JqZWN0JyAmJiBcbiAgICAgICAgICAgICAgb2xkVmFsICE9PSBudWxsICYmIG5ld1ZhbCAhPT0gbnVsbCAmJiBcbiAgICAgICAgICAgICAgIUFycmF5LmlzQXJyYXkob2xkVmFsKSAmJiAhQXJyYXkuaXNBcnJheShuZXdWYWwpKSB7XG4gICAgICAgICAgICBjb21wYXJlKG9sZFZhbCwgbmV3VmFsLCBmdWxsUGF0aCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChKU09OLnN0cmluZ2lmeShvbGRWYWwpICE9PSBKU09OLnN0cmluZ2lmeShuZXdWYWwpKSB7XG4gICAgICAgICAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICBmaWVsZDogZnVsbFBhdGgsXG4gICAgICAgICAgICAgIG9sZFZhbHVlOiBvbGRWYWwsXG4gICAgICAgICAgICAgIG5ld1ZhbHVlOiBuZXdWYWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbXBhcmUob2xkQ29uZmlnLCBuZXdDb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyDlv73nlaXplJnor69cbiAgICB9XG5cbiAgICByZXR1cm4gY2hhbmdlcztcbiAgfVxufVxuIl19
@@ -0,0 +1,2 @@
1
+ export { ConfigValidator } from './config-validator';
2
+ export type { ValidationResult } from './config-validator';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigValidator = void 0;
4
+ // src/validators/index.ts
5
+ var config_validator_1 = require("./config-validator");
6
+ Object.defineProperty(exports, "ConfigValidator", { enumerable: true, get: function () { return config_validator_1.ConfigValidator; } });
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29yZS92YWxpZGF0b3JzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDBCQUEwQjtBQUMxQix1REFBcUQ7QUFBNUMsbUhBQUEsZUFBZSxPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gc3JjL3ZhbGlkYXRvcnMvaW5kZXgudHNcbmV4cG9ydCB7IENvbmZpZ1ZhbGlkYXRvciB9IGZyb20gJy4vY29uZmlnLXZhbGlkYXRvcic7XG5leHBvcnQgdHlwZSB7IFZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuL2NvbmZpZy12YWxpZGF0b3InO1xuIl19
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS13YXRjaGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZpbGUtd2F0Y2hlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsZ0NBQWdDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFaEMsdUNBQXlCO0FBVXpCLE1BQWEsV0FBVztJQUNkLFVBQVUsR0FBOEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNsRCxjQUFjLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDeEQsTUFBTSxDQUFvQjtJQUMxQixNQUFNLENBQWdCO0lBRTlCLFlBQVksTUFBcUIsRUFBRSxNQUF5QjtRQUMxRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLO1FBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBRTdDLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRDs7T0FFRztJQUNLLFNBQVMsQ0FBQyxRQUFnQjtRQUNoQyxjQUFjO1FBQ2QsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEVB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T0FBTyxLQUFVLEVBQUUsQ0FBQztZQUNwQixPQUFPLENBQUMsS0FBSyxDQUFDLDBCQUEwQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN6RCxPQUFPO1FBQ1QsQ0FBQztRQUVELGNBQWM7UUFDZCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJO1FBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBRTVDLEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDNUQsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRXhCLFVBQVU7UUFDVixLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQzlELFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixDQUFDO1FBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDMUMsQ0FBQztDQUNGO0FBL0hELGtDQStIQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNyYy9maWxlLXdhdGNoZXIudHMgLSDphY3nva7mlofku7bnm5HlkKzlmahcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB0eXBlIHsgSGFybmVzc1BsdWdpbiB9IGZyb20gJy4vaW5kZXguanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVXYXRjaGVyQ29uZmlnIHtcbiAgd2F0Y2hGaWxlczogc3RyaW5nW107XG4gIGRlYm91bmNlTXM6IG51bWJlcjtcbiAgb25GaWxlQ2hhbmdlOiAoZmlsZVBhdGg6IHN0cmluZywgbmV3Q29udGVudDogYW55KSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZVdhdGNoZXIge1xuICBwcml2YXRlIHdhdGNoUGF0aHM6IE1hcDxzdHJpbmcsIGZzLkZTV2F0Y2hlcj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZGVib3VuY2VUaW1lcnM6IE1hcDxzdHJpbmcsIE5vZGVKUy5UaW1lb3V0PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBjb25maWc6IEZpbGVXYXRjaGVyQ29uZmlnO1xuICBwcml2YXRlIHBsdWdpbjogSGFybmVzc1BsdWdpbjtcblxuICBjb25zdHJ1Y3RvcihwbHVnaW46IEhhcm5lc3NQbHVnaW4sIGNvbmZpZzogRmlsZVdhdGNoZXJDb25maWcpIHtcbiAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiDlvIDlp4vnm5HlkKzmlofku7ZcbiAgICovXG4gIHN0YXJ0KCk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCfwn5GB77iPIFtGaWxlV2F0Y2hlcl0g5byA5aeL55uR5ZCs6YWN572u5paH5Lu2Li4uJyk7XG4gICAgXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIHRoaXMuY29uZmlnLndhdGNoRmlsZXMpIHtcbiAgICAgIHRoaXMud2F0Y2hGaWxlKGZpbGUpO1xuICAgIH1cbiAgICBcbiAgICBjb25zb2xlLmxvZyhg8J+Rge+4jyBbRmlsZVdhdGNoZXJdIOato+WcqOebkeWQrCAke3RoaXMuY29uZmlnLndhdGNoRmlsZXMubGVuZ3RofSDkuKrmlofku7ZgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDnm5HlkKzljZXkuKrmlofku7ZcbiAgICovXG4gIHByaXZhdGUgd2F0Y2hGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyDlpoLmnpzlt7Lnu4/lnKjnm5HlkKzvvIzlhYjlgZzmraJcbiAgICBpZiAodGhpcy53YXRjaFBhdGhzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgIHRoaXMudW53YXRjaEZpbGUoZmlsZVBhdGgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB3YXRjaGVyID0gZnMud2F0Y2goZmlsZVBhdGgsIHsgcGVyc2lzdGVudDogZmFsc2UgfSwgKGV2ZW50VHlwZSwgZmlsZW5hbWUpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50VHlwZSA9PT0gJ2NoYW5nZScgfHwgZXZlbnRUeXBlID09PSAncmVuYW1lJykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGDwn5OdIFtGaWxlV2F0Y2hlcl0g5qOA5rWL5Yiw5paH5Lu25Y+Y5YyW77yaJHtmaWxlUGF0aH0gKCR7ZXZlbnRUeXBlfSlgKTtcbiAgICAgICAgICB0aGlzLm9uRmlsZUNoYW5nZShmaWxlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB3YXRjaGVyLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKGDinYwgW0ZpbGVXYXRjaGVyXSDnm5HlkKzplJnor68gJHtmaWxlUGF0aH06YCwgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy53YXRjaFBhdGhzLnNldChmaWxlUGF0aCwgd2F0Y2hlcik7XG4gICAgICBjb25zb2xlLmxvZyhg4pyFIFtGaWxlV2F0Y2hlcl0g5byA5aeL55uR5ZCs77yaJHtmaWxlUGF0aH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoO+4jyBbRmlsZVdhdGNoZXJdIOaXoOazleebkeWQrOaWh+S7tiAke2ZpbGVQYXRofTogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDlgZzmraLnm5HlkKzljZXkuKrmlofku7ZcbiAgICovXG4gIHByaXZhdGUgdW53YXRjaEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHdhdGNoZXIgPSB0aGlzLndhdGNoUGF0aHMuZ2V0KGZpbGVQYXRoKTtcbiAgICBpZiAod2F0Y2hlcikge1xuICAgICAgd2F0Y2hlci5jbG9zZSgpO1xuICAgICAgdGhpcy53YXRjaFBhdGhzLmRlbGV0ZShmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhg8J+bkSBbRmlsZVdhdGNoZXJdIOWBnOatouebkeWQrO+8miR7ZmlsZVBhdGh9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOaWh+S7tuWPmOWMluWkhOeQhu+8iOW4pumYsuaKlu+8iVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvbkZpbGVDaGFuZ2UoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOa4hemZpOS5i+WJjeeahOWumuaXtuWZqFxuICAgIGNvbnN0IGV4aXN0aW5nVGltZXIgPSB0aGlzLmRlYm91bmNlVGltZXJzLmdldChmaWxlUGF0aCk7XG4gICAgaWYgKGV4aXN0aW5nVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dChleGlzdGluZ1RpbWVyKTtcbiAgICB9XG5cbiAgICAvLyDorr7nva7mlrDnmoTpmLLmipblrprml7blmahcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGaWxlQ2hhbmdlKGZpbGVQYXRoKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihg4p2MIFtGaWxlV2F0Y2hlcl0g5aSE55CG5paH5Lu25Y+Y5YyW5aSx6LSlICR7ZmlsZVBhdGh9OmAsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWJvdW5jZVRpbWVycy5kZWxldGUoZmlsZVBhdGgpO1xuICAgIH0sIHRoaXMuY29uZmlnLmRlYm91bmNlTXMpO1xuXG4gICAgdGhpcy5kZWJvdW5jZVRpbWVycy5zZXQoZmlsZVBhdGgsIHRpbWVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDlpITnkIbmlofku7blj5jljJZcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRmlsZUNoYW5nZShmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYPCflI0gW0ZpbGVXYXRjaGVyXSDlpITnkIbmlofku7blj5jljJbvvJoke2ZpbGVQYXRofWApO1xuXG4gICAgLy8g6K+75Y+W5paw6YWN572uXG4gICAgbGV0IG5ld0NvbmZpZzogYW55O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgbmV3Q29uZmlnID0gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKGDinYwgW0ZpbGVXYXRjaGVyXSDor7vlj5bphY3nva7lpLHotKXvvJoke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g6LCD55So5o+S5Lu255qE6YWN572u5Y+Y5pu05aSE55CGXG4gICAgYXdhaXQgdGhpcy5jb25maWcub25GaWxlQ2hhbmdlKGZpbGVQYXRoLCBuZXdDb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIOWBnOatouaJgOacieebkeWQrFxuICAgKi9cbiAgc3RvcCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZygn8J+bkSBbRmlsZVdhdGNoZXJdIOWBnOatouaJgOacieaWh+S7tuebkeWQrC4uLicpO1xuICAgIFxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCB3YXRjaGVyXSBvZiB0aGlzLndhdGNoUGF0aHMuZW50cmllcygpKSB7XG4gICAgICB3YXRjaGVyLmNsb3NlKCk7XG4gICAgfVxuICAgIFxuICAgIHRoaXMud2F0Y2hQYXRocy5jbGVhcigpO1xuICAgIFxuICAgIC8vIOa4hemZpOaJgOacieWumuaXtuWZqFxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCB0aW1lcl0gb2YgdGhpcy5kZWJvdW5jZVRpbWVycy5lbnRyaWVzKCkpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgfVxuICAgIFxuICAgIHRoaXMuZGVib3VuY2VUaW1lcnMuY2xlYXIoKTtcbiAgICBjb25zb2xlLmxvZygn8J+bkSBbRmlsZVdhdGNoZXJdIOW3suWBnOatouaJgOacieebkeWQrCcpO1xuICB9XG59XG4iXX0=
package/dist/index.d.ts CHANGED
@@ -5,3 +5,66 @@ export interface HarnessPluginConfig {
5
5
  protectedFiles: string[];
6
6
  logsDir: string;
7
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;