add-skill-kit 3.2.3 → 3.2.5

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.
Files changed (126) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/commands/help.js +0 -4
  3. package/bin/lib/commands/install.js +90 -9
  4. package/bin/lib/ui.js +1 -1
  5. package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
  6. package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
  7. package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
  8. package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
  9. package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
  10. package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
  11. package/lib/agent-cli/bin/agent.js +191 -0
  12. package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
  13. package/lib/agent-cli/dashboard/index.html +538 -0
  14. package/lib/agent-cli/lib/audit.js +154 -0
  15. package/lib/agent-cli/lib/audit.test.js +100 -0
  16. package/lib/agent-cli/lib/auto-learn.js +319 -0
  17. package/lib/agent-cli/lib/auto_preview.py +148 -0
  18. package/lib/agent-cli/lib/backup.js +138 -0
  19. package/lib/agent-cli/lib/backup.test.js +78 -0
  20. package/lib/agent-cli/lib/checklist.py +222 -0
  21. package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
  22. package/lib/agent-cli/lib/completion.js +149 -0
  23. package/lib/agent-cli/lib/config.js +35 -0
  24. package/lib/agent-cli/lib/eslint-fix.js +238 -0
  25. package/lib/agent-cli/lib/evolution-signal.js +215 -0
  26. package/lib/agent-cli/lib/export.js +86 -0
  27. package/lib/agent-cli/lib/export.test.js +65 -0
  28. package/lib/agent-cli/lib/fix.js +337 -0
  29. package/lib/agent-cli/lib/fix.test.js +80 -0
  30. package/lib/agent-cli/lib/gemini-export.js +83 -0
  31. package/lib/agent-cli/lib/generate-registry.js +42 -0
  32. package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
  33. package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
  34. package/lib/agent-cli/lib/ignore.js +116 -0
  35. package/lib/agent-cli/lib/ignore.test.js +58 -0
  36. package/lib/agent-cli/lib/init.js +124 -0
  37. package/lib/agent-cli/lib/learn.js +255 -0
  38. package/lib/agent-cli/lib/learn.test.js +70 -0
  39. package/lib/agent-cli/lib/migrate-to-v4.js +322 -0
  40. package/lib/agent-cli/lib/proposals.js +199 -0
  41. package/lib/agent-cli/lib/proposals.test.js +56 -0
  42. package/lib/agent-cli/lib/recall.js +820 -0
  43. package/lib/agent-cli/lib/recall.test.js +107 -0
  44. package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
  45. package/lib/agent-cli/lib/session_manager.py +120 -0
  46. package/lib/agent-cli/lib/settings.js +227 -0
  47. package/lib/agent-cli/lib/skill-learn.js +296 -0
  48. package/lib/agent-cli/lib/stats.js +132 -0
  49. package/lib/agent-cli/lib/stats.test.js +94 -0
  50. package/lib/agent-cli/lib/types.js +33 -0
  51. package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
  52. package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
  53. package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
  54. package/lib/agent-cli/lib/ui/common.js +83 -0
  55. package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
  56. package/lib/agent-cli/lib/ui/custom-select.js +69 -0
  57. package/lib/agent-cli/lib/ui/dashboard-ui.js +222 -0
  58. package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
  59. package/lib/agent-cli/lib/ui/export-ui.js +94 -0
  60. package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
  61. package/lib/agent-cli/lib/ui/help-ui.js +49 -0
  62. package/lib/agent-cli/lib/ui/index.js +199 -0
  63. package/lib/agent-cli/lib/ui/init-ui.js +56 -0
  64. package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
  65. package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
  66. package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
  67. package/lib/agent-cli/lib/ui/pretty.js +145 -0
  68. package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
  69. package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
  70. package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
  71. package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
  72. package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
  73. package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
  74. package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
  75. package/lib/agent-cli/lib/verify_all.py +327 -0
  76. package/lib/agent-cli/lib/watcher.js +181 -0
  77. package/lib/agent-cli/lib/watcher.test.js +85 -0
  78. package/lib/agent-cli/package.json +51 -0
  79. package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
  80. package/lib/agent-cli/scripts/dashboard_server.js +224 -0
  81. package/lib/agent-cli/scripts/error_sensor.js +565 -0
  82. package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
  83. package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
  84. package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
  85. package/lib/agent-cli/scripts/rule_sharing.js +374 -0
  86. package/lib/agent-cli/scripts/skill_injector.js +387 -0
  87. package/lib/agent-cli/scripts/success_sensor.js +500 -0
  88. package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
  89. package/lib/agent-cli/services/auto-learn-service.js +247 -0
  90. package/lib/agent-cli/src/MIGRATION.md +418 -0
  91. package/lib/agent-cli/src/README.md +367 -0
  92. package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
  93. package/lib/agent-cli/src/core/evolution/index.js +17 -0
  94. package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
  95. package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
  96. package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
  97. package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
  98. package/lib/agent-cli/src/core/index.js +15 -0
  99. package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
  100. package/lib/agent-cli/src/core/learning/index.js +12 -0
  101. package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
  102. package/lib/agent-cli/src/core/scanning/index.js +14 -0
  103. package/lib/agent-cli/src/data/index.js +13 -0
  104. package/lib/agent-cli/src/data/repositories/index.js +8 -0
  105. package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
  106. package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
  107. package/lib/agent-cli/src/data/storage/index.js +8 -0
  108. package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
  109. package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
  110. package/lib/agent-cli/src/infrastructure/index.js +13 -0
  111. package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
  112. package/lib/agent-cli/src/services/export-service.js +162 -0
  113. package/lib/agent-cli/src/services/index.js +13 -0
  114. package/lib/agent-cli/src/services/learning-service.js +99 -0
  115. package/lib/agent-cli/types/index.d.ts +343 -0
  116. package/lib/agent-cli/utils/benchmark.js +269 -0
  117. package/lib/agent-cli/utils/logger.js +303 -0
  118. package/lib/agent-cli/utils/ml_patterns.js +300 -0
  119. package/lib/agent-cli/utils/recovery.js +312 -0
  120. package/lib/agent-cli/utils/telemetry.js +290 -0
  121. package/lib/agentskillskit-cli/README.md +21 -0
  122. package/{node_modules/agentskillskit-cli/bin → lib/agentskillskit-cli}/ag-smart.js +15 -15
  123. package/lib/agentskillskit-cli/package.json +51 -0
  124. package/package.json +19 -9
  125. /package/bin/{cli.js → kit.js} +0 -0
  126. /package/{node_modules/agentskillskit-cli → lib/agent-cli}/README.md +0 -0
@@ -0,0 +1,374 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Rule Sharing - Export/Import rules for collaborative learning
4
+ *
5
+ * Part of FAANG-Grade Auto-Learn System Phase 4
6
+ *
7
+ * Features:
8
+ * - Export rules to YAML format
9
+ * - Import rules from file
10
+ * - Global storage (~/.agent-skills/)
11
+ * - Cross-project learning
12
+ *
13
+ * Usage:
14
+ * node rule_sharing.js --export
15
+ * node rule_sharing.js --import <file>
16
+ * node rule_sharing.js --sync
17
+ */
18
+
19
+ import fs from 'fs';
20
+ import path from 'path';
21
+ import os from 'os';
22
+ import { fileURLToPath } from 'url';
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = path.dirname(__filename);
26
+
27
+ // Colors
28
+ const c = {
29
+ reset: '\x1b[0m',
30
+ red: '\x1b[31m',
31
+ green: '\x1b[32m',
32
+ yellow: '\x1b[33m',
33
+ blue: '\x1b[34m',
34
+ cyan: '\x1b[36m',
35
+ gray: '\x1b[90m',
36
+ bold: '\x1b[1m'
37
+ };
38
+
39
+ // Paths
40
+ function findProjectRoot() {
41
+ let current = process.cwd();
42
+ while (current !== path.dirname(current)) {
43
+ if (fs.existsSync(path.join(current, '.agent'))) {
44
+ return current;
45
+ }
46
+ current = path.dirname(current);
47
+ }
48
+ return process.cwd();
49
+ }
50
+
51
+ const projectRoot = findProjectRoot();
52
+ const knowledgePath = path.join(projectRoot, '.agent', 'knowledge');
53
+ const globalPath = path.join(os.homedir(), '.agent-skills');
54
+ const globalRulesPath = path.join(globalPath, 'shared-rules.yaml');
55
+
56
+ // Ensure directories exist
57
+ function ensureDirectories() {
58
+ if (!fs.existsSync(knowledgePath)) {
59
+ fs.mkdirSync(knowledgePath, { recursive: true });
60
+ }
61
+ if (!fs.existsSync(globalPath)) {
62
+ fs.mkdirSync(globalPath, { recursive: true });
63
+ }
64
+ }
65
+
66
+ // Load JSON file
67
+ function loadJson(filename) {
68
+ const filePath = path.join(knowledgePath, filename);
69
+ try {
70
+ if (fs.existsSync(filePath)) {
71
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
72
+ }
73
+ } catch { }
74
+ return null;
75
+ }
76
+
77
+ // ==================== EXPORT FUNCTIONS ====================
78
+
79
+ /**
80
+ * Export lessons and rules to YAML format
81
+ */
82
+ function exportRules(outputPath) {
83
+ ensureDirectories();
84
+
85
+ const lessons = loadJson('lessons-learned.json');
86
+ const patterns = loadJson('patterns.json');
87
+ const autoRules = [];
88
+
89
+ // Load auto-rules if exists
90
+ const autoRulesPath = path.join(knowledgePath, 'auto-rules.yaml');
91
+ if (fs.existsSync(autoRulesPath)) {
92
+ const content = fs.readFileSync(autoRulesPath, 'utf8');
93
+ // Parse existing auto-rules (simplified)
94
+ const matches = content.matchAll(/id:\s*(\S+)[\s\S]*?pattern:\s*"([^"]+)"[\s\S]*?severity:\s*(\S+)/g);
95
+ for (const match of matches) {
96
+ autoRules.push({
97
+ id: match[1],
98
+ pattern: match[2],
99
+ severity: match[3]
100
+ });
101
+ }
102
+ }
103
+
104
+ // Build YAML content
105
+ let yaml = `# Auto-Learn Shared Rules
106
+ # Exported from: ${projectRoot}
107
+ # Date: ${new Date().toISOString()}
108
+ # Version: 1.0.0
109
+
110
+ metadata:
111
+ project: ${path.basename(projectRoot)}
112
+ exportedAt: "${new Date().toISOString()}"
113
+ totalRules: ${(lessons?.lessons?.length || 0) + autoRules.length}
114
+
115
+ `;
116
+
117
+ // Export lessons
118
+ if (lessons?.lessons?.length > 0) {
119
+ yaml += `# Lessons Learned\nlessons:\n`;
120
+ for (const lesson of lessons.lessons) {
121
+ yaml += ` - id: ${lesson.id}
122
+ pattern: "${lesson.pattern || ''}"
123
+ severity: ${lesson.severity || 'MEDIUM'}
124
+ message: "${(lesson.message || '').replace(/"/g, '\\"')}"
125
+ category: ${lesson.id?.split('-')[0] || 'GENERAL'}
126
+ hitCount: ${lesson.hitCount || 1}
127
+ confidence: ${lesson.confidence || 0.8}
128
+ `;
129
+ }
130
+ yaml += '\n';
131
+ }
132
+
133
+ // Export auto-rules
134
+ if (autoRules.length > 0) {
135
+ yaml += `# Auto-Generated Rules\nautoRules:\n`;
136
+ for (const rule of autoRules) {
137
+ yaml += ` - id: ${rule.id}
138
+ pattern: "${rule.pattern}"
139
+ severity: ${rule.severity}
140
+ status: approved
141
+ `;
142
+ }
143
+ yaml += '\n';
144
+ }
145
+
146
+ // Export high-frequency patterns
147
+ if (patterns?.highFrequency?.length > 0) {
148
+ yaml += `# High-Frequency Patterns\nhighFrequency:\n`;
149
+ for (const hf of patterns.highFrequency.slice(0, 10)) {
150
+ yaml += ` - pattern: "${hf.pattern}"
151
+ count: ${hf.count}
152
+ type: ${hf.type}
153
+ `;
154
+ }
155
+ }
156
+
157
+ // Write to file
158
+ const targetPath = outputPath || path.join(knowledgePath, 'exported-rules.yaml');
159
+ fs.writeFileSync(targetPath, yaml);
160
+
161
+ console.log(`${c.green}✓ Exported rules to: ${targetPath}${c.reset}`);
162
+ console.log(` Lessons: ${lessons?.lessons?.length || 0}`);
163
+ console.log(` Auto-rules: ${autoRules.length}`);
164
+ console.log(` High-frequency: ${patterns?.highFrequency?.length || 0}`);
165
+
166
+ return targetPath;
167
+ }
168
+
169
+ /**
170
+ * Export rules to global storage
171
+ */
172
+ function exportToGlobal() {
173
+ ensureDirectories();
174
+ return exportRules(globalRulesPath);
175
+ }
176
+
177
+ // ==================== IMPORT FUNCTIONS ====================
178
+
179
+ /**
180
+ * Parse YAML content (simplified parser)
181
+ */
182
+ function parseYaml(content) {
183
+ const result = { lessons: [], autoRules: [], highFrequency: [] };
184
+
185
+ // Parse lessons
186
+ const lessonsMatch = content.match(/lessons:\s*([\s\S]*?)(?=\n[a-zA-Z]|\n#|$)/);
187
+ if (lessonsMatch) {
188
+ const lessonsBlock = lessonsMatch[1];
189
+ const lessonMatches = lessonsBlock.matchAll(/- id:\s*(\S+)[\s\S]*?pattern:\s*"([^"]*)"[\s\S]*?severity:\s*(\S+)[\s\S]*?message:\s*"([^"]*)"/g);
190
+ for (const match of lessonMatches) {
191
+ result.lessons.push({
192
+ id: match[1],
193
+ pattern: match[2],
194
+ severity: match[3],
195
+ message: match[4]
196
+ });
197
+ }
198
+ }
199
+
200
+ // Parse auto-rules
201
+ const rulesMatch = content.match(/autoRules:\s*([\s\S]*?)(?=\n[a-zA-Z]|\n#|$)/);
202
+ if (rulesMatch) {
203
+ const rulesBlock = rulesMatch[1];
204
+ const ruleMatches = rulesBlock.matchAll(/- id:\s*(\S+)[\s\S]*?pattern:\s*"([^"]*)"[\s\S]*?severity:\s*(\S+)/g);
205
+ for (const match of ruleMatches) {
206
+ result.autoRules.push({
207
+ id: match[1],
208
+ pattern: match[2],
209
+ severity: match[3]
210
+ });
211
+ }
212
+ }
213
+
214
+ return result;
215
+ }
216
+
217
+ /**
218
+ * Import rules from file
219
+ */
220
+ function importRules(inputPath, options = { merge: true }) {
221
+ ensureDirectories();
222
+
223
+ if (!fs.existsSync(inputPath)) {
224
+ console.log(`${c.red}Error: File not found: ${inputPath}${c.reset}`);
225
+ return false;
226
+ }
227
+
228
+ const content = fs.readFileSync(inputPath, 'utf8');
229
+ const imported = parseYaml(content);
230
+
231
+ console.log(`${c.cyan}📥 Importing rules from: ${inputPath}${c.reset}`);
232
+ console.log(` Found: ${imported.lessons.length} lessons, ${imported.autoRules.length} auto-rules`);
233
+
234
+ // Merge with existing lessons
235
+ const lessonsPath = path.join(knowledgePath, 'lessons-learned.json');
236
+ let existingLessons = { lessons: [] };
237
+ if (fs.existsSync(lessonsPath)) {
238
+ existingLessons = JSON.parse(fs.readFileSync(lessonsPath, 'utf8'));
239
+ }
240
+
241
+ let addedCount = 0;
242
+ for (const lesson of imported.lessons) {
243
+ const exists = existingLessons.lessons.some(l => l.pattern === lesson.pattern);
244
+ if (!exists) {
245
+ lesson.importedAt = new Date().toISOString();
246
+ lesson.source = 'imported';
247
+ existingLessons.lessons.push(lesson);
248
+ addedCount++;
249
+ }
250
+ }
251
+
252
+ if (addedCount > 0) {
253
+ fs.writeFileSync(lessonsPath, JSON.stringify(existingLessons, null, 2));
254
+ console.log(`${c.green} Added ${addedCount} new lessons${c.reset}`);
255
+ } else {
256
+ console.log(`${c.gray} No new lessons to add (all duplicates)${c.reset}`);
257
+ }
258
+
259
+ return true;
260
+ }
261
+
262
+ /**
263
+ * Import from global storage
264
+ */
265
+ function importFromGlobal() {
266
+ ensureDirectories();
267
+
268
+ if (!fs.existsSync(globalRulesPath)) {
269
+ console.log(`${c.yellow}No global rules found at: ${globalRulesPath}${c.reset}`);
270
+ console.log(`${c.gray}Run --export-global first to create shared rules${c.reset}`);
271
+ return false;
272
+ }
273
+
274
+ return importRules(globalRulesPath);
275
+ }
276
+
277
+ // ==================== SYNC FUNCTIONS ====================
278
+
279
+ /**
280
+ * Sync rules between local and global storage
281
+ */
282
+ function syncRules() {
283
+ console.log(`${c.cyan}🔄 Syncing rules...${c.reset}\n`);
284
+
285
+ // Export to global
286
+ console.log(`${c.bold}Step 1: Export to global storage${c.reset}`);
287
+ exportToGlobal();
288
+
289
+ console.log('');
290
+
291
+ // Import from global (will merge with any rules from other projects)
292
+ console.log(`${c.bold}Step 2: Import from global storage${c.reset}`);
293
+ importFromGlobal();
294
+
295
+ console.log(`\n${c.green}✓ Sync complete!${c.reset}`);
296
+ }
297
+
298
+ /**
299
+ * List global rules
300
+ */
301
+ function listGlobalRules() {
302
+ ensureDirectories();
303
+
304
+ console.log(`${c.cyan}📂 Global Rules Storage: ${globalPath}${c.reset}\n`);
305
+
306
+ if (!fs.existsSync(globalRulesPath)) {
307
+ console.log(`${c.gray}No shared rules yet.${c.reset}`);
308
+ console.log(`${c.gray}Run: node rule_sharing.js --export-global${c.reset}`);
309
+ return;
310
+ }
311
+
312
+ const content = fs.readFileSync(globalRulesPath, 'utf8');
313
+ const parsed = parseYaml(content);
314
+
315
+ console.log(`${c.bold}Shared Lessons: ${parsed.lessons.length}${c.reset}`);
316
+ for (const lesson of parsed.lessons.slice(0, 5)) {
317
+ console.log(` ${c.blue}${lesson.id}${c.reset}: ${lesson.pattern}`);
318
+ }
319
+ if (parsed.lessons.length > 5) {
320
+ console.log(` ${c.gray}... and ${parsed.lessons.length - 5} more${c.reset}`);
321
+ }
322
+
323
+ console.log(`\n${c.bold}Shared Auto-Rules: ${parsed.autoRules.length}${c.reset}`);
324
+ for (const rule of parsed.autoRules.slice(0, 5)) {
325
+ console.log(` ${c.green}${rule.id}${c.reset}: ${rule.pattern}`);
326
+ }
327
+ }
328
+
329
+ // ==================== MAIN ====================
330
+
331
+ const args = process.argv.slice(2);
332
+
333
+ if (args.includes('--export') || args.includes('-e')) {
334
+ const idx = args.indexOf('--export') !== -1 ? args.indexOf('--export') : args.indexOf('-e');
335
+ const outputPath = args[idx + 1];
336
+ exportRules(outputPath && !outputPath.startsWith('-') ? outputPath : undefined);
337
+ } else if (args.includes('--export-global')) {
338
+ exportToGlobal();
339
+ } else if (args.includes('--import') || args.includes('-i')) {
340
+ const idx = args.indexOf('--import') !== -1 ? args.indexOf('--import') : args.indexOf('-i');
341
+ const inputPath = args[idx + 1];
342
+ if (!inputPath || inputPath.startsWith('-')) {
343
+ console.log(`${c.red}Error: --import requires a file path${c.reset}`);
344
+ } else {
345
+ importRules(inputPath);
346
+ }
347
+ } else if (args.includes('--import-global')) {
348
+ importFromGlobal();
349
+ } else if (args.includes('--sync')) {
350
+ syncRules();
351
+ } else if (args.includes('--list-global')) {
352
+ listGlobalRules();
353
+ } else {
354
+ console.log(`${c.cyan}rule_sharing - Export/Import rules for collaborative learning${c.reset}
355
+
356
+ ${c.bold}Usage:${c.reset}
357
+ node rule_sharing.js --export [file] Export rules to YAML
358
+ node rule_sharing.js --export-global Export to global storage
359
+ node rule_sharing.js --import <file> Import rules from file
360
+ node rule_sharing.js --import-global Import from global storage
361
+ node rule_sharing.js --sync Sync local <-> global
362
+ node rule_sharing.js --list-global List global rules
363
+
364
+ ${c.bold}Global Storage:${c.reset}
365
+ ${globalPath}
366
+
367
+ ${c.bold}Examples:${c.reset}
368
+ node rule_sharing.js --export Export to local file
369
+ node rule_sharing.js --sync Sync with global storage
370
+ node rule_sharing.js --list-global View shared rules
371
+ `);
372
+ }
373
+
374
+ export { exportRules, exportToGlobal, importRules, importFromGlobal, syncRules };