add-skill-kit 3.2.4 → 3.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -119
- package/bin/lib/commands/help.js +0 -4
- package/bin/lib/commands/install.js +129 -9
- package/bin/lib/ui.js +1 -1
- package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
- package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
- package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
- package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
- package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
- package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
- package/lib/agent-cli/bin/{ag-smart.js → agent.js} +48 -15
- package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
- package/lib/agent-cli/dashboard/index.html +538 -0
- package/lib/agent-cli/lib/audit.js +2 -2
- package/lib/agent-cli/lib/auto-learn.js +8 -8
- package/lib/agent-cli/lib/eslint-fix.js +1 -1
- package/lib/agent-cli/lib/fix.js +5 -5
- package/lib/agent-cli/lib/hooks/install-hooks.js +4 -4
- package/lib/agent-cli/lib/hooks/lint-learn.js +4 -4
- package/lib/agent-cli/lib/learn.js +10 -10
- package/lib/agent-cli/lib/recall.js +1 -1
- package/lib/agent-cli/lib/settings.js +24 -0
- package/lib/agent-cli/lib/skill-learn.js +2 -2
- package/lib/agent-cli/lib/stats.js +3 -3
- package/lib/agent-cli/lib/ui/dashboard-ui.js +103 -4
- package/lib/agent-cli/lib/ui/index.js +36 -6
- package/lib/agent-cli/lib/watcher.js +2 -2
- package/lib/agent-cli/package.json +4 -4
- package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
- package/lib/agent-cli/scripts/dashboard_server.js +224 -0
- package/lib/agent-cli/scripts/error_sensor.js +565 -0
- package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
- package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
- package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
- package/lib/agent-cli/scripts/rule_sharing.js +374 -0
- package/lib/agent-cli/scripts/skill_injector.js +387 -0
- package/lib/agent-cli/scripts/success_sensor.js +500 -0
- package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
- package/lib/agent-cli/services/auto-learn-service.js +247 -0
- package/lib/agent-cli/src/MIGRATION.md +418 -0
- package/lib/agent-cli/src/README.md +367 -0
- package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
- package/lib/agent-cli/src/core/evolution/index.js +17 -0
- package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
- package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
- package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
- package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
- package/lib/agent-cli/src/core/index.js +15 -0
- package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
- package/lib/agent-cli/src/core/learning/index.js +12 -0
- package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
- package/lib/agent-cli/src/core/scanning/index.js +14 -0
- package/lib/agent-cli/src/data/index.js +13 -0
- package/lib/agent-cli/src/data/repositories/index.js +8 -0
- package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
- package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
- package/lib/agent-cli/src/data/storage/index.js +8 -0
- package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
- package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
- package/lib/agent-cli/src/infrastructure/index.js +13 -0
- package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
- package/lib/agent-cli/src/services/export-service.js +162 -0
- package/lib/agent-cli/src/services/index.js +13 -0
- package/lib/agent-cli/src/services/learning-service.js +99 -0
- package/lib/agent-cli/types/index.d.ts +343 -0
- package/lib/agent-cli/utils/benchmark.js +269 -0
- package/lib/agent-cli/utils/logger.js +303 -0
- package/lib/agent-cli/utils/ml_patterns.js +300 -0
- package/lib/agent-cli/utils/recovery.js +312 -0
- package/lib/agent-cli/utils/telemetry.js +290 -0
- package/lib/agentskillskit-cli/ag-smart.js +15 -15
- package/lib/agentskillskit-cli/package.json +3 -3
- package/package.json +12 -6
- package/lib/agent-cli/lib/auto_preview.py +0 -148
- package/lib/agent-cli/lib/checklist.py +0 -222
- package/lib/agent-cli/lib/session_manager.py +0 -120
- package/lib/agent-cli/lib/verify_all.py +0 -327
- /package/bin/{cli.js → kit.js} +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-healing Recovery Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides checkpoint and rollback capabilities:
|
|
5
|
+
* - Save state before risky operations
|
|
6
|
+
* - Rollback on failure
|
|
7
|
+
* - Recovery logging
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import recovery from './recovery.js';
|
|
11
|
+
*
|
|
12
|
+
* const checkpoint = recovery.save('operation-name', currentState);
|
|
13
|
+
* try {
|
|
14
|
+
* // risky operation
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* recovery.rollback(checkpoint);
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import path from 'path';
|
|
22
|
+
import { fileURLToPath } from 'url';
|
|
23
|
+
|
|
24
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
25
|
+
const __dirname = path.dirname(__filename);
|
|
26
|
+
|
|
27
|
+
// ==================== STORAGE ====================
|
|
28
|
+
|
|
29
|
+
const checkpoints = new Map();
|
|
30
|
+
const history = [];
|
|
31
|
+
const MAX_CHECKPOINTS = 10;
|
|
32
|
+
|
|
33
|
+
// ==================== COLORS ====================
|
|
34
|
+
|
|
35
|
+
const c = {
|
|
36
|
+
reset: '\x1b[0m',
|
|
37
|
+
red: '\x1b[31m',
|
|
38
|
+
green: '\x1b[32m',
|
|
39
|
+
yellow: '\x1b[33m',
|
|
40
|
+
cyan: '\x1b[36m',
|
|
41
|
+
gray: '\x1b[90m'
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// ==================== CHECKPOINT ====================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate checkpoint ID
|
|
48
|
+
*/
|
|
49
|
+
function generateId() {
|
|
50
|
+
return `CP-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Save a state checkpoint
|
|
55
|
+
* @param {string} operation - Operation name
|
|
56
|
+
* @param {any} state - State to save (will be deep cloned)
|
|
57
|
+
* @param {object} options - Options
|
|
58
|
+
* @returns {object} Checkpoint reference
|
|
59
|
+
*/
|
|
60
|
+
function save(operation, state, options = {}) {
|
|
61
|
+
const id = generateId();
|
|
62
|
+
const checkpoint = {
|
|
63
|
+
id,
|
|
64
|
+
operation,
|
|
65
|
+
state: JSON.parse(JSON.stringify(state)), // Deep clone
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
options
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
checkpoints.set(id, checkpoint);
|
|
71
|
+
history.push({ type: 'save', id, operation, timestamp: checkpoint.timestamp });
|
|
72
|
+
|
|
73
|
+
// Cleanup old checkpoints
|
|
74
|
+
if (checkpoints.size > MAX_CHECKPOINTS) {
|
|
75
|
+
const oldest = [...checkpoints.keys()][0];
|
|
76
|
+
checkpoints.delete(oldest);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`${c.gray}💾 Checkpoint saved: ${operation} (${id})${c.reset}`);
|
|
80
|
+
|
|
81
|
+
return checkpoint;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Rollback to a checkpoint
|
|
86
|
+
* @param {object|string} checkpoint - Checkpoint reference or ID
|
|
87
|
+
* @returns {any} Restored state
|
|
88
|
+
*/
|
|
89
|
+
function rollback(checkpoint) {
|
|
90
|
+
const id = typeof checkpoint === 'string' ? checkpoint : checkpoint.id;
|
|
91
|
+
const saved = checkpoints.get(id);
|
|
92
|
+
|
|
93
|
+
if (!saved) {
|
|
94
|
+
console.error(`${c.red}❌ Checkpoint not found: ${id}${c.reset}`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
history.push({
|
|
99
|
+
type: 'rollback',
|
|
100
|
+
id,
|
|
101
|
+
operation: saved.operation,
|
|
102
|
+
timestamp: new Date().toISOString()
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
console.log(`${c.yellow}⏪ Rolling back: ${saved.operation}${c.reset}`);
|
|
106
|
+
|
|
107
|
+
return saved.state;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get a checkpoint by ID
|
|
112
|
+
* @param {string} id - Checkpoint ID
|
|
113
|
+
*/
|
|
114
|
+
function get(id) {
|
|
115
|
+
return checkpoints.get(id);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* List all checkpoints
|
|
120
|
+
*/
|
|
121
|
+
function list() {
|
|
122
|
+
return [...checkpoints.values()].map(cp => ({
|
|
123
|
+
id: cp.id,
|
|
124
|
+
operation: cp.operation,
|
|
125
|
+
timestamp: cp.timestamp
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ==================== FILE RECOVERY ====================
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Backup a file before modification
|
|
133
|
+
* @param {string} filePath - File to backup
|
|
134
|
+
* @returns {object} Backup reference
|
|
135
|
+
*/
|
|
136
|
+
function backupFile(filePath) {
|
|
137
|
+
if (!fs.existsSync(filePath)) {
|
|
138
|
+
return { id: null, exists: false, path: filePath };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
142
|
+
const backup = save(`file:${path.basename(filePath)}`, {
|
|
143
|
+
path: filePath,
|
|
144
|
+
content,
|
|
145
|
+
exists: true
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return backup;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Restore a file from backup
|
|
153
|
+
* @param {object|string} backup - Backup reference
|
|
154
|
+
*/
|
|
155
|
+
function restoreFile(backup) {
|
|
156
|
+
const state = rollback(backup);
|
|
157
|
+
|
|
158
|
+
if (!state) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (state.exists) {
|
|
163
|
+
fs.writeFileSync(state.path, state.content, 'utf8');
|
|
164
|
+
console.log(`${c.green}✓ Restored: ${state.path}${c.reset}`);
|
|
165
|
+
} else {
|
|
166
|
+
// File didn't exist, delete if created
|
|
167
|
+
if (fs.existsSync(state.path)) {
|
|
168
|
+
fs.unlinkSync(state.path);
|
|
169
|
+
console.log(`${c.green}✓ Removed: ${state.path}${c.reset}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ==================== TRANSACTION ====================
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Execute operation with automatic rollback on failure
|
|
180
|
+
* @param {string} name - Operation name
|
|
181
|
+
* @param {any} state - State to checkpoint
|
|
182
|
+
* @param {Function} operation - Operation to execute
|
|
183
|
+
* @returns {Promise<{success: boolean, result?: any, error?: Error}>}
|
|
184
|
+
*/
|
|
185
|
+
async function withRecovery(name, state, operation) {
|
|
186
|
+
const checkpoint = save(name, state);
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
const result = await operation();
|
|
190
|
+
|
|
191
|
+
history.push({
|
|
192
|
+
type: 'success',
|
|
193
|
+
id: checkpoint.id,
|
|
194
|
+
operation: name,
|
|
195
|
+
timestamp: new Date().toISOString()
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
console.log(`${c.green}✓ ${name} completed successfully${c.reset}`);
|
|
199
|
+
|
|
200
|
+
return { success: true, result };
|
|
201
|
+
} catch (error) {
|
|
202
|
+
const restored = rollback(checkpoint);
|
|
203
|
+
|
|
204
|
+
history.push({
|
|
205
|
+
type: 'failure',
|
|
206
|
+
id: checkpoint.id,
|
|
207
|
+
operation: name,
|
|
208
|
+
error: error.message,
|
|
209
|
+
timestamp: new Date().toISOString()
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
console.error(`${c.red}❌ ${name} failed, rolled back${c.reset}`);
|
|
213
|
+
console.error(`${c.gray} Error: ${error.message}${c.reset}`);
|
|
214
|
+
|
|
215
|
+
return { success: false, error, restored };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ==================== HISTORY ====================
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get recovery history
|
|
223
|
+
*/
|
|
224
|
+
function getHistory() {
|
|
225
|
+
return [...history];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get statistics
|
|
230
|
+
*/
|
|
231
|
+
function getStats() {
|
|
232
|
+
const stats = {
|
|
233
|
+
totalCheckpoints: checkpoints.size,
|
|
234
|
+
totalOperations: history.length,
|
|
235
|
+
saves: history.filter(h => h.type === 'save').length,
|
|
236
|
+
rollbacks: history.filter(h => h.type === 'rollback').length,
|
|
237
|
+
successes: history.filter(h => h.type === 'success').length,
|
|
238
|
+
failures: history.filter(h => h.type === 'failure').length
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
stats.successRate = stats.successes + stats.failures > 0
|
|
242
|
+
? (stats.successes / (stats.successes + stats.failures) * 100).toFixed(1) + '%'
|
|
243
|
+
: 'N/A';
|
|
244
|
+
|
|
245
|
+
return stats;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Print history summary
|
|
250
|
+
*/
|
|
251
|
+
function printHistory() {
|
|
252
|
+
console.log(`\n${c.cyan}═══ Recovery History ═══${c.reset}\n`);
|
|
253
|
+
|
|
254
|
+
if (history.length === 0) {
|
|
255
|
+
console.log(`${c.gray}No recovery operations yet.${c.reset}`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
for (const entry of history.slice(-10)) {
|
|
260
|
+
const icon = {
|
|
261
|
+
save: '💾',
|
|
262
|
+
rollback: '⏪',
|
|
263
|
+
success: '✅',
|
|
264
|
+
failure: '❌'
|
|
265
|
+
}[entry.type];
|
|
266
|
+
|
|
267
|
+
console.log(`${icon} ${entry.operation} (${entry.type})`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const stats = getStats();
|
|
271
|
+
console.log(`\n${c.gray}Stats: ${stats.successes} success, ${stats.failures} failures (${stats.successRate})${c.reset}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Clear all checkpoints and history
|
|
276
|
+
*/
|
|
277
|
+
function clear() {
|
|
278
|
+
checkpoints.clear();
|
|
279
|
+
history.length = 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// ==================== EXPORTS ====================
|
|
283
|
+
|
|
284
|
+
const recovery = {
|
|
285
|
+
save,
|
|
286
|
+
rollback,
|
|
287
|
+
get,
|
|
288
|
+
list,
|
|
289
|
+
backupFile,
|
|
290
|
+
restoreFile,
|
|
291
|
+
withRecovery,
|
|
292
|
+
getHistory,
|
|
293
|
+
getStats,
|
|
294
|
+
printHistory,
|
|
295
|
+
clear
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
export {
|
|
299
|
+
save,
|
|
300
|
+
rollback,
|
|
301
|
+
get,
|
|
302
|
+
list,
|
|
303
|
+
backupFile,
|
|
304
|
+
restoreFile,
|
|
305
|
+
withRecovery,
|
|
306
|
+
getHistory,
|
|
307
|
+
getStats,
|
|
308
|
+
printHistory,
|
|
309
|
+
clear
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export default recovery;
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry Utility - Local Metrics Collection
|
|
3
|
+
*
|
|
4
|
+
* Provides opt-in anonymous metrics collection:
|
|
5
|
+
* - Local storage only (no external transmission)
|
|
6
|
+
* - Error frequency tracking
|
|
7
|
+
* - Usage patterns
|
|
8
|
+
* - Performance metrics
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* import telemetry from './telemetry.js';
|
|
12
|
+
* telemetry.track('error_detected', { type: 'test' });
|
|
13
|
+
* telemetry.report();
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = path.dirname(__filename);
|
|
22
|
+
|
|
23
|
+
// ==================== CONFIGURATION ====================
|
|
24
|
+
|
|
25
|
+
const config = {
|
|
26
|
+
enabled: true, // Master switch
|
|
27
|
+
storeLocally: true, // Store to file
|
|
28
|
+
maxEvents: 1000, // Max events to keep
|
|
29
|
+
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
30
|
+
storagePath: null // Will be set dynamically
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// ==================== STORAGE ====================
|
|
34
|
+
|
|
35
|
+
const events = [];
|
|
36
|
+
const counters = new Map();
|
|
37
|
+
const gauges = new Map();
|
|
38
|
+
|
|
39
|
+
// ==================== HELPERS ====================
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get storage path
|
|
43
|
+
*/
|
|
44
|
+
function getStoragePath() {
|
|
45
|
+
if (config.storagePath) return config.storagePath;
|
|
46
|
+
|
|
47
|
+
// Try to find project root
|
|
48
|
+
let dir = process.cwd();
|
|
49
|
+
while (dir !== path.dirname(dir)) {
|
|
50
|
+
if (fs.existsSync(path.join(dir, 'package.json'))) {
|
|
51
|
+
return path.join(dir, '.agent', 'knowledge', 'telemetry.json');
|
|
52
|
+
}
|
|
53
|
+
dir = path.dirname(dir);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return path.join(process.cwd(), '.agent', 'knowledge', 'telemetry.json');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Load existing telemetry data
|
|
61
|
+
*/
|
|
62
|
+
function load() {
|
|
63
|
+
const storagePath = getStoragePath();
|
|
64
|
+
if (!fs.existsSync(storagePath)) return;
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const data = JSON.parse(fs.readFileSync(storagePath, 'utf8'));
|
|
68
|
+
if (data.events) events.push(...data.events);
|
|
69
|
+
if (data.counters) {
|
|
70
|
+
for (const [k, v] of Object.entries(data.counters)) {
|
|
71
|
+
counters.set(k, v);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
// Ignore parse errors
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Save telemetry data
|
|
81
|
+
*/
|
|
82
|
+
function save() {
|
|
83
|
+
if (!config.storeLocally) return;
|
|
84
|
+
|
|
85
|
+
const storagePath = getStoragePath();
|
|
86
|
+
const dir = path.dirname(storagePath);
|
|
87
|
+
|
|
88
|
+
if (!fs.existsSync(dir)) {
|
|
89
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const data = {
|
|
93
|
+
events: events.slice(-config.maxEvents),
|
|
94
|
+
counters: Object.fromEntries(counters),
|
|
95
|
+
gauges: Object.fromEntries(gauges),
|
|
96
|
+
savedAt: new Date().toISOString()
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
fs.writeFileSync(storagePath, JSON.stringify(data, null, 2));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ==================== TRACKING ====================
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Track an event
|
|
106
|
+
* @param {string} name - Event name
|
|
107
|
+
* @param {object} properties - Event properties
|
|
108
|
+
*/
|
|
109
|
+
function track(name, properties = {}) {
|
|
110
|
+
if (!config.enabled) return;
|
|
111
|
+
|
|
112
|
+
const event = {
|
|
113
|
+
name,
|
|
114
|
+
properties,
|
|
115
|
+
timestamp: new Date().toISOString()
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
events.push(event);
|
|
119
|
+
|
|
120
|
+
// Increment counter
|
|
121
|
+
increment(name);
|
|
122
|
+
|
|
123
|
+
// Cleanup old events
|
|
124
|
+
if (events.length > config.maxEvents) {
|
|
125
|
+
events.splice(0, events.length - config.maxEvents);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Increment a counter
|
|
131
|
+
* @param {string} name - Counter name
|
|
132
|
+
* @param {number} value - Value to add (default: 1)
|
|
133
|
+
*/
|
|
134
|
+
function increment(name, value = 1) {
|
|
135
|
+
if (!config.enabled) return;
|
|
136
|
+
counters.set(name, (counters.get(name) || 0) + value);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Set a gauge value
|
|
141
|
+
* @param {string} name - Gauge name
|
|
142
|
+
* @param {number} value - Value to set
|
|
143
|
+
*/
|
|
144
|
+
function gauge(name, value) {
|
|
145
|
+
if (!config.enabled) return;
|
|
146
|
+
gauges.set(name, value);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ==================== TIMING ====================
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Time an operation
|
|
153
|
+
* @param {string} name - Operation name
|
|
154
|
+
*/
|
|
155
|
+
function startTimer(name) {
|
|
156
|
+
const start = Date.now();
|
|
157
|
+
return {
|
|
158
|
+
end: () => {
|
|
159
|
+
const duration = Date.now() - start;
|
|
160
|
+
track(`${name}_duration`, { duration });
|
|
161
|
+
return duration;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ==================== REPORTING ====================
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get summary statistics
|
|
170
|
+
*/
|
|
171
|
+
function getSummary() {
|
|
172
|
+
const now = Date.now();
|
|
173
|
+
const cutoff = now - 24 * 60 * 60 * 1000; // Last 24 hours
|
|
174
|
+
|
|
175
|
+
const recentEvents = events.filter(e =>
|
|
176
|
+
new Date(e.timestamp).getTime() > cutoff
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
const byName = {};
|
|
180
|
+
for (const event of recentEvents) {
|
|
181
|
+
byName[event.name] = (byName[event.name] || 0) + 1;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
totalEvents: events.length,
|
|
186
|
+
last24h: recentEvents.length,
|
|
187
|
+
counters: Object.fromEntries(counters),
|
|
188
|
+
gauges: Object.fromEntries(gauges),
|
|
189
|
+
byEvent: byName
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Print telemetry report
|
|
195
|
+
*/
|
|
196
|
+
function report() {
|
|
197
|
+
const summary = getSummary();
|
|
198
|
+
|
|
199
|
+
console.log('\n📊 Telemetry Report');
|
|
200
|
+
console.log('═══════════════════\n');
|
|
201
|
+
|
|
202
|
+
console.log(`Total Events: ${summary.totalEvents}`);
|
|
203
|
+
console.log(`Last 24h: ${summary.last24h}`);
|
|
204
|
+
|
|
205
|
+
if (Object.keys(summary.counters).length > 0) {
|
|
206
|
+
console.log('\nCounters:');
|
|
207
|
+
for (const [name, count] of Object.entries(summary.counters)) {
|
|
208
|
+
console.log(` ${name}: ${count}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (Object.keys(summary.byEvent).length > 0) {
|
|
213
|
+
console.log('\nRecent Events (24h):');
|
|
214
|
+
const sorted = Object.entries(summary.byEvent)
|
|
215
|
+
.sort((a, b) => b[1] - a[1])
|
|
216
|
+
.slice(0, 10);
|
|
217
|
+
|
|
218
|
+
for (const [name, count] of sorted) {
|
|
219
|
+
console.log(` ${name}: ${count}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ==================== CONFIGURATION ====================
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Enable telemetry
|
|
228
|
+
*/
|
|
229
|
+
function enable() {
|
|
230
|
+
config.enabled = true;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Disable telemetry
|
|
235
|
+
*/
|
|
236
|
+
function disable() {
|
|
237
|
+
config.enabled = false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Check if enabled
|
|
242
|
+
*/
|
|
243
|
+
function isEnabled() {
|
|
244
|
+
return config.enabled;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Clear all telemetry data
|
|
249
|
+
*/
|
|
250
|
+
function clear() {
|
|
251
|
+
events.length = 0;
|
|
252
|
+
counters.clear();
|
|
253
|
+
gauges.clear();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ==================== EXPORTS ====================
|
|
257
|
+
|
|
258
|
+
const telemetry = {
|
|
259
|
+
track,
|
|
260
|
+
increment,
|
|
261
|
+
gauge,
|
|
262
|
+
startTimer,
|
|
263
|
+
getSummary,
|
|
264
|
+
report,
|
|
265
|
+
enable,
|
|
266
|
+
disable,
|
|
267
|
+
isEnabled,
|
|
268
|
+
clear,
|
|
269
|
+
save,
|
|
270
|
+
load,
|
|
271
|
+
config
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export {
|
|
275
|
+
track,
|
|
276
|
+
increment,
|
|
277
|
+
gauge,
|
|
278
|
+
startTimer,
|
|
279
|
+
getSummary,
|
|
280
|
+
report,
|
|
281
|
+
enable,
|
|
282
|
+
disable,
|
|
283
|
+
isEnabled,
|
|
284
|
+
clear,
|
|
285
|
+
save,
|
|
286
|
+
load,
|
|
287
|
+
config
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export default telemetry;
|
|
@@ -52,46 +52,46 @@ function printHelp() {
|
|
|
52
52
|
console.log(`
|
|
53
53
|
🤖 Agent Skill Kit CLI v${VERSION}
|
|
54
54
|
|
|
55
|
-
Usage:
|
|
55
|
+
Usage: agent <command> [options]
|
|
56
56
|
|
|
57
57
|
${"─".repeat(50)}
|
|
58
58
|
|
|
59
59
|
📚 CORE COMMANDS:
|
|
60
60
|
|
|
61
61
|
learn Teach a new lesson to the memory
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
agent learn --add --pattern "var " --message "Use let/const"
|
|
63
|
+
agent learn --list
|
|
64
|
+
agent learn --remove LEARN-001
|
|
65
65
|
|
|
66
66
|
recall Check file(s) against learned patterns
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
agent recall src/app.js
|
|
68
|
+
agent recall ./src
|
|
69
69
|
|
|
70
70
|
audit Run full compliance audit
|
|
71
|
-
|
|
71
|
+
agent audit [directory]
|
|
72
72
|
|
|
73
73
|
${"─".repeat(50)}
|
|
74
74
|
|
|
75
75
|
🚀 PRODUCTION FEATURES:
|
|
76
76
|
|
|
77
77
|
watch Real-time file monitoring
|
|
78
|
-
|
|
78
|
+
agent watch [directory]
|
|
79
79
|
|
|
80
80
|
stats Knowledge base statistics
|
|
81
|
-
|
|
81
|
+
agent stats
|
|
82
82
|
|
|
83
83
|
install-hooks Install git pre-commit hook
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
agent install-hooks
|
|
85
|
+
agent install-hooks --remove
|
|
86
86
|
|
|
87
87
|
lint-learn Auto-learn from ESLint JSON output
|
|
88
|
-
npx eslint . --format json |
|
|
88
|
+
npx eslint . --format json | agent lint-learn
|
|
89
89
|
|
|
90
90
|
fix 🆕 Auto-fix violations
|
|
91
|
-
|
|
91
|
+
agent fix <file|dir> [--mode safe|aggressive]
|
|
92
92
|
|
|
93
93
|
sync-skills 🆕 Sync hot patterns to SKILL.md
|
|
94
|
-
|
|
94
|
+
agent sync-skills
|
|
95
95
|
|
|
96
96
|
${"─".repeat(50)}
|
|
97
97
|
|
|
@@ -153,6 +153,6 @@ switch (COMMAND) {
|
|
|
153
153
|
break;
|
|
154
154
|
default:
|
|
155
155
|
console.log(`❌ Unknown command: ${COMMAND}`);
|
|
156
|
-
console.log(" Run '
|
|
156
|
+
console.log(" Run 'agent help' for available commands.\n");
|
|
157
157
|
process.exit(1);
|
|
158
158
|
}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/config.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"agent": "bin/
|
|
9
|
-
"
|
|
10
|
-
"agent-skills-kit": "bin/
|
|
8
|
+
"agent": "bin/agent.js",
|
|
9
|
+
"agent": "bin/agent.js",
|
|
10
|
+
"agent-skills-kit": "bin/agent.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "vitest run",
|