clawdoctor 0.1.0

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 (78) hide show
  1. package/README.md +112 -0
  2. package/dist/alerters/telegram.d.ts +21 -0
  3. package/dist/alerters/telegram.d.ts.map +1 -0
  4. package/dist/alerters/telegram.js +87 -0
  5. package/dist/alerters/telegram.js.map +1 -0
  6. package/dist/config.d.ts +42 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +77 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/daemon.d.ts +21 -0
  11. package/dist/daemon.d.ts.map +1 -0
  12. package/dist/daemon.js +172 -0
  13. package/dist/daemon.js.map +1 -0
  14. package/dist/healers/base.d.ts +15 -0
  15. package/dist/healers/base.d.ts.map +1 -0
  16. package/dist/healers/base.js +25 -0
  17. package/dist/healers/base.js.map +1 -0
  18. package/dist/healers/cron.d.ts +6 -0
  19. package/dist/healers/cron.d.ts.map +1 -0
  20. package/dist/healers/cron.js +26 -0
  21. package/dist/healers/cron.js.map +1 -0
  22. package/dist/healers/process.d.ts +6 -0
  23. package/dist/healers/process.d.ts.map +1 -0
  24. package/dist/healers/process.js +67 -0
  25. package/dist/healers/process.js.map +1 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +283 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/store.d.ts +22 -0
  31. package/dist/store.d.ts.map +1 -0
  32. package/dist/store.js +97 -0
  33. package/dist/store.js.map +1 -0
  34. package/dist/test/config.test.d.ts +2 -0
  35. package/dist/test/config.test.d.ts.map +1 -0
  36. package/dist/test/config.test.js +90 -0
  37. package/dist/test/config.test.js.map +1 -0
  38. package/dist/test/store.test.d.ts +2 -0
  39. package/dist/test/store.test.d.ts.map +1 -0
  40. package/dist/test/store.test.js +89 -0
  41. package/dist/test/store.test.js.map +1 -0
  42. package/dist/test/telegram.test.d.ts +2 -0
  43. package/dist/test/telegram.test.d.ts.map +1 -0
  44. package/dist/test/telegram.test.js +107 -0
  45. package/dist/test/telegram.test.js.map +1 -0
  46. package/dist/test/watchers.test.d.ts +2 -0
  47. package/dist/test/watchers.test.d.ts.map +1 -0
  48. package/dist/test/watchers.test.js +194 -0
  49. package/dist/test/watchers.test.js.map +1 -0
  50. package/dist/utils.d.ts +18 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +62 -0
  53. package/dist/utils.js.map +1 -0
  54. package/dist/watchers/auth.d.ts +10 -0
  55. package/dist/watchers/auth.d.ts.map +1 -0
  56. package/dist/watchers/auth.js +79 -0
  57. package/dist/watchers/auth.js.map +1 -0
  58. package/dist/watchers/base.d.ts +22 -0
  59. package/dist/watchers/base.d.ts.map +1 -0
  60. package/dist/watchers/base.js +39 -0
  61. package/dist/watchers/base.js.map +1 -0
  62. package/dist/watchers/cost.d.ts +9 -0
  63. package/dist/watchers/cost.d.ts.map +1 -0
  64. package/dist/watchers/cost.js +151 -0
  65. package/dist/watchers/cost.js.map +1 -0
  66. package/dist/watchers/cron.d.ts +7 -0
  67. package/dist/watchers/cron.d.ts.map +1 -0
  68. package/dist/watchers/cron.js +79 -0
  69. package/dist/watchers/cron.js.map +1 -0
  70. package/dist/watchers/gateway.d.ts +7 -0
  71. package/dist/watchers/gateway.d.ts.map +1 -0
  72. package/dist/watchers/gateway.js +33 -0
  73. package/dist/watchers/gateway.js.map +1 -0
  74. package/dist/watchers/session.d.ts +7 -0
  75. package/dist/watchers/session.d.ts.map +1 -0
  76. package/dist/watchers/session.js +112 -0
  77. package/dist/watchers/session.js.map +1 -0
  78. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/healers/cron.ts"],"names":[],"mappings":";;;AAAA,uCAAmD;AAEnD,MAAa,UAAW,SAAQ,oBAAU;IAC/B,IAAI,GAAG,YAAY,CAAC;IAE7B,KAAK,CAAC,IAAI,CAAC,OAAgC;QACzC,MAAM,QAAQ,GAAI,OAAO,CAAC,QAA+B,IAAI,SAAS,CAAC;QACvE,MAAM,OAAO,GAAI,OAAO,CAAC,OAA8B,IAAI,SAAS,CAAC;QACrE,MAAM,SAAS,GAAI,OAAO,CAAC,SAAgC,IAAI,SAAS,CAAC;QAEzE,yDAAyD;QACzD,MAAM,aAAa,GAAG,QAAQ,KAAK,SAAS;YAC1C,CAAC,CAAC,qBAAqB,QAAQ,EAAE;YACjC,CAAC,CAAC,+BAA+B,CAAC;QAEpC,MAAM,MAAM,GAAe;YACzB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,4BAA4B,QAAQ,GAAG;YAC/C,OAAO,EAAE,SAAS,QAAQ,WAAW,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,OAAO,qBAAqB,aAAa,IAAI;YAClI,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE;SACzD,CAAC;QAEF,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAvBD,gCAuBC"}
@@ -0,0 +1,6 @@
1
+ import { BaseHealer, HealResult } from './base.js';
2
+ export declare class ProcessHealer extends BaseHealer {
3
+ readonly name = "ProcessHealer";
4
+ heal(_context: Record<string, unknown>): Promise<HealResult>;
5
+ }
6
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/healers/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGnD,qBAAa,aAAc,SAAQ,UAAU;IAC3C,QAAQ,CAAC,IAAI,mBAAmB;IAE1B,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CA4DnE"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProcessHealer = void 0;
4
+ const base_js_1 = require("./base.js");
5
+ const utils_js_1 = require("../utils.js");
6
+ class ProcessHealer extends base_js_1.BaseHealer {
7
+ name = 'ProcessHealer';
8
+ async heal(_context) {
9
+ if (this.config.dryRun) {
10
+ return {
11
+ success: true,
12
+ action: 'dry-run: would restart gateway',
13
+ message: '[DRY RUN] Would restart openclaw gateway',
14
+ };
15
+ }
16
+ // Try systemctl first
17
+ const systemctlStatus = (0, utils_js_1.runShell)('systemctl is-enabled openclaw-gateway 2>/dev/null');
18
+ if (systemctlStatus.ok && systemctlStatus.stdout.trim() === 'enabled') {
19
+ const restartResult = (0, utils_js_1.runShell)('systemctl restart openclaw-gateway');
20
+ if (restartResult.ok) {
21
+ await (0, utils_js_1.sleep)(10000);
22
+ const verifyResult = (0, utils_js_1.runShell)('systemctl is-active openclaw-gateway 2>/dev/null');
23
+ if (verifyResult.ok && verifyResult.stdout.trim() === 'active') {
24
+ const result = {
25
+ success: true,
26
+ action: 'systemctl restart openclaw-gateway',
27
+ message: 'Gateway restarted via systemd and verified running',
28
+ };
29
+ await this.recordHeal('GatewayWatcher', result, 'gateway_restarted');
30
+ return result;
31
+ }
32
+ const result = {
33
+ success: false,
34
+ action: 'systemctl restart openclaw-gateway',
35
+ message: 'Gateway restarted via systemd but failed to verify running after 10s',
36
+ };
37
+ await this.recordHeal('GatewayWatcher', result, 'gateway_restart_failed');
38
+ return result;
39
+ }
40
+ }
41
+ // Try openclaw gateway restart
42
+ const openclaw = (0, utils_js_1.runShell)('openclaw gateway restart');
43
+ if (openclaw.ok) {
44
+ await (0, utils_js_1.sleep)(10000);
45
+ const verify = (0, utils_js_1.runShell)('pgrep -f "openclaw"');
46
+ if (verify.ok && verify.stdout.trim().length > 0) {
47
+ const result = {
48
+ success: true,
49
+ action: 'openclaw gateway restart',
50
+ message: 'Gateway restarted via openclaw CLI and verified running',
51
+ };
52
+ await this.recordHeal('GatewayWatcher', result, 'gateway_restarted');
53
+ return result;
54
+ }
55
+ }
56
+ const result = {
57
+ success: false,
58
+ action: 'attempted restart',
59
+ message: `Failed to restart gateway. stdout: ${openclaw.stdout.slice(0, 200)} stderr: ${openclaw.stderr.slice(0, 200)}`,
60
+ details: { stdout: openclaw.stdout, stderr: openclaw.stderr },
61
+ };
62
+ await this.recordHeal('GatewayWatcher', result, 'gateway_restart_failed');
63
+ return result;
64
+ }
65
+ }
66
+ exports.ProcessHealer = ProcessHealer;
67
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/healers/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const readline_1 = __importDefault(require("readline"));
11
+ const os_1 = __importDefault(require("os"));
12
+ const config_js_1 = require("./config.js");
13
+ const daemon_js_1 = require("./daemon.js");
14
+ const store_js_1 = require("./store.js");
15
+ const utils_js_1 = require("./utils.js");
16
+ const pkg = { version: '0.1.0' };
17
+ const program = new commander_1.Command();
18
+ program
19
+ .name('clawdoctor')
20
+ .description('Self-healing doctor for OpenClaw')
21
+ .version(pkg.version);
22
+ // ── init ──────────────────────────────────────────────────────────────────────
23
+ program
24
+ .command('init')
25
+ .description('Interactive setup: detect OpenClaw, configure alerts')
26
+ .action(async () => {
27
+ console.log('\n🔍 ClawDoctor Setup\n');
28
+ const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
29
+ const ask = (question, defaultVal = '') => new Promise(resolve => {
30
+ const hint = defaultVal ? ` [${defaultVal}]` : '';
31
+ rl.question(`${question}${hint}: `, answer => {
32
+ resolve(answer.trim() || defaultVal);
33
+ });
34
+ });
35
+ // Detect OpenClaw
36
+ const defaultOpenclawPath = path_1.default.join(os_1.default.homedir(), '.openclaw');
37
+ const openclawExists = fs_1.default.existsSync(defaultOpenclawPath);
38
+ const openclawhWhich = (0, utils_js_1.runShell)('which openclaw');
39
+ if (openclawExists) {
40
+ console.log(`✅ Found OpenClaw at ${defaultOpenclawPath}`);
41
+ }
42
+ else {
43
+ console.log(`⚠️ OpenClaw not found at ${defaultOpenclawPath}`);
44
+ }
45
+ if (openclawhWhich.ok) {
46
+ console.log(`✅ openclaw binary found at ${openclawhWhich.stdout.trim()}`);
47
+ }
48
+ else {
49
+ console.log(`⚠️ openclaw binary not found in PATH`);
50
+ }
51
+ console.log('');
52
+ const openclawPath = await ask('OpenClaw data path', defaultOpenclawPath);
53
+ // Telegram setup
54
+ console.log('\n📱 Telegram Alerts (optional — press Enter to skip)\n');
55
+ const botToken = await ask('Telegram bot token (leave blank to skip)');
56
+ let chatId = '';
57
+ if (botToken) {
58
+ chatId = await ask('Telegram chat ID');
59
+ }
60
+ // Watcher preferences
61
+ console.log('\n⚙️ Watcher Configuration\n');
62
+ const enableGateway = (await ask('Monitor gateway process?', 'yes')).toLowerCase() !== 'no';
63
+ const enableCron = (await ask('Monitor crons?', 'yes')).toLowerCase() !== 'no';
64
+ const enableSession = (await ask('Monitor sessions?', 'yes')).toLowerCase() !== 'no';
65
+ const enableAuth = (await ask('Monitor auth failures?', 'yes')).toLowerCase() !== 'no';
66
+ const enableCost = (await ask('Monitor cost anomalies?', 'yes')).toLowerCase() !== 'no';
67
+ // Healer preferences
68
+ console.log('\n🔧 Auto-Fix Configuration\n');
69
+ const enableProcessRestart = (await ask('Auto-restart gateway on failure?', 'yes')).toLowerCase() !== 'no';
70
+ // Dry run?
71
+ const dryRun = (await ask('Enable dry-run mode (no actual healing)?', 'no')).toLowerCase() === 'yes';
72
+ rl.close();
73
+ const config = {
74
+ ...config_js_1.DEFAULT_CONFIG,
75
+ openclawPath,
76
+ watchers: {
77
+ gateway: { enabled: enableGateway, interval: 30 },
78
+ cron: { enabled: enableCron, interval: 60 },
79
+ session: { enabled: enableSession, interval: 60 },
80
+ auth: { enabled: enableAuth, interval: 60 },
81
+ cost: { enabled: enableCost, interval: 300 },
82
+ },
83
+ healers: {
84
+ processRestart: { enabled: enableProcessRestart },
85
+ cronRetry: { enabled: false },
86
+ },
87
+ alerts: {
88
+ telegram: {
89
+ enabled: !!(botToken && chatId),
90
+ botToken: botToken || '',
91
+ chatId: chatId || '',
92
+ },
93
+ },
94
+ dryRun,
95
+ retentionDays: 7,
96
+ };
97
+ (0, config_js_1.saveConfig)(config);
98
+ console.log(`\n✅ Config saved to ${config_js_1.AGENTWATCH_DIR}/config.json`);
99
+ // Offer systemd install
100
+ console.log('\n💡 To start monitoring now, run: clawdoctor start');
101
+ console.log('💡 To install as a systemd service, run: clawdoctor install-service');
102
+ console.log('');
103
+ });
104
+ // ── start ─────────────────────────────────────────────────────────────────────
105
+ program
106
+ .command('start')
107
+ .description('Start monitoring daemon (foreground)')
108
+ .option('--dry-run', 'Run in dry-run mode (no healing actions)')
109
+ .action((opts) => {
110
+ let config;
111
+ try {
112
+ config = (0, config_js_1.loadConfig)();
113
+ }
114
+ catch (err) {
115
+ console.error(`Error: ${String(err)}`);
116
+ process.exit(1);
117
+ }
118
+ if (opts.dryRun)
119
+ config.dryRun = true;
120
+ // Write PID file
121
+ fs_1.default.mkdirSync(config_js_1.AGENTWATCH_DIR, { recursive: true });
122
+ fs_1.default.writeFileSync(config_js_1.PID_PATH, String(process.pid), 'utf-8');
123
+ const daemon = new daemon_js_1.Daemon(config);
124
+ const shutdown = () => {
125
+ daemon.stop();
126
+ try {
127
+ fs_1.default.unlinkSync(config_js_1.PID_PATH);
128
+ }
129
+ catch { /* ignore */ }
130
+ process.exit(0);
131
+ };
132
+ process.on('SIGTERM', shutdown);
133
+ process.on('SIGINT', shutdown);
134
+ daemon.start();
135
+ });
136
+ // ── stop ──────────────────────────────────────────────────────────────────────
137
+ program
138
+ .command('stop')
139
+ .description('Stop the running daemon')
140
+ .action(() => {
141
+ if (!fs_1.default.existsSync(config_js_1.PID_PATH)) {
142
+ console.log('No daemon PID file found. Is clawdoctor running?');
143
+ process.exit(1);
144
+ }
145
+ const pid = parseInt(fs_1.default.readFileSync(config_js_1.PID_PATH, 'utf-8').trim(), 10);
146
+ if (isNaN(pid)) {
147
+ console.error('Invalid PID file');
148
+ process.exit(1);
149
+ }
150
+ try {
151
+ process.kill(pid, 'SIGTERM');
152
+ console.log(`Sent SIGTERM to PID ${pid}`);
153
+ }
154
+ catch (err) {
155
+ console.error(`Failed to stop daemon (PID ${pid}):`, err);
156
+ process.exit(1);
157
+ }
158
+ });
159
+ // ── status ────────────────────────────────────────────────────────────────────
160
+ program
161
+ .command('status')
162
+ .description('Show current health of all monitors')
163
+ .action(async () => {
164
+ let config;
165
+ try {
166
+ config = (0, config_js_1.loadConfig)();
167
+ }
168
+ catch (err) {
169
+ console.error(`Error: ${String(err)}`);
170
+ process.exit(1);
171
+ }
172
+ const daemonRunning = isDaemonRunning();
173
+ console.log(`\nClawDoctor Status`);
174
+ console.log(`─────────────────`);
175
+ console.log(`Daemon: ${daemonRunning ? '✅ running' : '⚪ stopped'}`);
176
+ console.log(`Config: ${config_js_1.AGENTWATCH_DIR}/config.json`);
177
+ console.log(`Dry Run: ${config.dryRun ? 'yes' : 'no'}`);
178
+ console.log(`Telegram: ${config.alerts.telegram.enabled ? '✅ enabled' : '⚪ disabled'}`);
179
+ console.log('');
180
+ console.log('Watchers:');
181
+ for (const [name, watcher] of Object.entries(config.watchers)) {
182
+ console.log(` ${watcher.enabled ? '✅' : '⚪'} ${name.padEnd(10)} (every ${watcher.interval}s)`);
183
+ }
184
+ console.log('');
185
+ console.log('Healers:');
186
+ for (const [name, healer] of Object.entries(config.healers)) {
187
+ console.log(` ${healer.enabled ? '✅' : '⚪'} ${name}`);
188
+ }
189
+ // Run a quick check
190
+ console.log('\nRunning quick check...\n');
191
+ const daemon = new daemon_js_1.Daemon(config);
192
+ const results = await daemon.runOnce();
193
+ for (const [watcherName, watchResults] of results) {
194
+ for (const result of watchResults) {
195
+ const icon = result.ok ? '✅' : (result.severity === 'critical' ? '🔴' : result.severity === 'error' ? '🟠' : '🟡');
196
+ console.log(`${icon} [${watcherName}] ${result.message}`);
197
+ }
198
+ }
199
+ console.log('');
200
+ });
201
+ // ── log ───────────────────────────────────────────────────────────────────────
202
+ program
203
+ .command('log')
204
+ .description('Show recent events from local SQLite')
205
+ .option('-n, --lines <number>', 'Number of events to show', '50')
206
+ .option('-w, --watcher <name>', 'Filter by watcher name')
207
+ .option('-s, --severity <level>', 'Filter by severity (info|warning|error|critical)')
208
+ .action((opts) => {
209
+ const limit = parseInt(opts.lines, 10);
210
+ let config;
211
+ try {
212
+ config = (0, config_js_1.loadConfig)();
213
+ }
214
+ catch (err) {
215
+ console.error(`Error: ${String(err)}`);
216
+ process.exit(1);
217
+ }
218
+ // Prune first
219
+ (0, store_js_1.pruneOldEvents)(config.retentionDays);
220
+ const events = (0, store_js_1.getRecentEvents)(limit, opts.watcher, opts.severity);
221
+ if (events.length === 0) {
222
+ console.log('No events found.');
223
+ return;
224
+ }
225
+ console.log(`\nRecent Events (${events.length})\n`);
226
+ for (const event of events.reverse()) {
227
+ const severityIcon = { info: '⚪', warning: '🟡', error: '🟠', critical: '🔴' }[event.severity] ?? '⚪';
228
+ const ts = event.timestamp.slice(0, 19).replace('T', ' ');
229
+ console.log(`${severityIcon} ${ts} [${event.watcher}] ${event.message}`);
230
+ if (event.action_taken) {
231
+ console.log(` → ${event.action_taken}: ${event.action_result ?? ''}`);
232
+ }
233
+ }
234
+ console.log('');
235
+ });
236
+ // ── install-service ───────────────────────────────────────────────────────────
237
+ program
238
+ .command('install-service')
239
+ .description('Install clawdoctor as a systemd user service')
240
+ .action(() => {
241
+ const agentWatchBin = (0, utils_js_1.runShell)('which clawdoctor').stdout.trim() || process.argv[1];
242
+ const serviceContent = `[Unit]
243
+ Description=ClawDoctor — OpenClaw monitor
244
+ After=network.target
245
+
246
+ [Service]
247
+ Type=simple
248
+ ExecStart=${agentWatchBin} start
249
+ Restart=on-failure
250
+ RestartSec=10
251
+ StandardOutput=journal
252
+ StandardError=journal
253
+
254
+ [Install]
255
+ WantedBy=default.target
256
+ `;
257
+ const systemdUserDir = path_1.default.join(os_1.default.homedir(), '.config', 'systemd', 'user');
258
+ fs_1.default.mkdirSync(systemdUserDir, { recursive: true });
259
+ const serviceFile = path_1.default.join(systemdUserDir, 'clawdoctor.service');
260
+ fs_1.default.writeFileSync(serviceFile, serviceContent, 'utf-8');
261
+ console.log(`✅ Service file written to ${serviceFile}`);
262
+ console.log('\nTo enable and start:');
263
+ console.log(' systemctl --user daemon-reload');
264
+ console.log(' systemctl --user enable clawdoctor');
265
+ console.log(' systemctl --user start clawdoctor');
266
+ console.log('');
267
+ });
268
+ function isDaemonRunning() {
269
+ if (!fs_1.default.existsSync(config_js_1.PID_PATH))
270
+ return false;
271
+ try {
272
+ const pid = parseInt(fs_1.default.readFileSync(config_js_1.PID_PATH, 'utf-8').trim(), 10);
273
+ if (isNaN(pid))
274
+ return false;
275
+ process.kill(pid, 0); // Check if process exists
276
+ return true;
277
+ }
278
+ catch {
279
+ return false;
280
+ }
281
+ }
282
+ program.parse(process.argv);
283
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export type Severity = 'info' | 'warning' | 'error' | 'critical';
2
+ export interface Event {
3
+ id?: number;
4
+ timestamp: string;
5
+ watcher: string;
6
+ severity: Severity;
7
+ event_type: string;
8
+ message: string;
9
+ details?: string;
10
+ action_taken?: string;
11
+ action_result?: string;
12
+ created_at?: string;
13
+ }
14
+ export interface EventRow extends Required<Event> {
15
+ id: number;
16
+ }
17
+ export declare function insertEvent(event: Omit<Event, 'id' | 'created_at'>): number;
18
+ export declare function getRecentEvents(limit?: number, watcher?: string, severity?: Severity): EventRow[];
19
+ export declare function pruneOldEvents(retentionDays: number): number;
20
+ export declare function closeDb(): void;
21
+ export declare function getEventCount(): number;
22
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,KAAK;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAS,SAAQ,QAAQ,CAAC,KAAK,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;CACZ;AAkCD,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,MAAM,CAiB3E;AAED,wBAAgB,eAAe,CAAC,KAAK,SAAK,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAqB7F;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wBAAgB,OAAO,IAAI,IAAI,CAK9B;AAED,wBAAgB,aAAa,IAAI,MAAM,CAItC"}
package/dist/store.js ADDED
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.insertEvent = insertEvent;
7
+ exports.getRecentEvents = getRecentEvents;
8
+ exports.pruneOldEvents = pruneOldEvents;
9
+ exports.closeDb = closeDb;
10
+ exports.getEventCount = getEventCount;
11
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
12
+ const config_js_1 = require("./config.js");
13
+ let _db = null;
14
+ function getDb() {
15
+ if (!_db) {
16
+ (0, config_js_1.ensureAgentwatchDir)();
17
+ _db = new better_sqlite3_1.default(config_js_1.DB_PATH);
18
+ _db.pragma('journal_mode = WAL');
19
+ initSchema(_db);
20
+ }
21
+ return _db;
22
+ }
23
+ function initSchema(db) {
24
+ db.exec(`
25
+ CREATE TABLE IF NOT EXISTS events (
26
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
27
+ timestamp TEXT NOT NULL,
28
+ watcher TEXT NOT NULL,
29
+ severity TEXT NOT NULL,
30
+ event_type TEXT NOT NULL,
31
+ message TEXT NOT NULL,
32
+ details TEXT,
33
+ action_taken TEXT,
34
+ action_result TEXT,
35
+ created_at TEXT DEFAULT (datetime('now'))
36
+ );
37
+ CREATE INDEX IF NOT EXISTS idx_events_watcher ON events(watcher);
38
+ CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);
39
+ CREATE INDEX IF NOT EXISTS idx_events_severity ON events(severity);
40
+ `);
41
+ }
42
+ function insertEvent(event) {
43
+ const db = getDb();
44
+ const stmt = db.prepare(`
45
+ INSERT INTO events (timestamp, watcher, severity, event_type, message, details, action_taken, action_result)
46
+ VALUES (@timestamp, @watcher, @severity, @event_type, @message, @details, @action_taken, @action_result)
47
+ `);
48
+ const result = stmt.run({
49
+ timestamp: event.timestamp,
50
+ watcher: event.watcher,
51
+ severity: event.severity,
52
+ event_type: event.event_type,
53
+ message: event.message,
54
+ details: event.details ?? null,
55
+ action_taken: event.action_taken ?? null,
56
+ action_result: event.action_result ?? null,
57
+ });
58
+ return result.lastInsertRowid;
59
+ }
60
+ function getRecentEvents(limit = 50, watcher, severity) {
61
+ const db = getDb();
62
+ let query = 'SELECT * FROM events';
63
+ const conditions = [];
64
+ const params = { limit };
65
+ if (watcher) {
66
+ conditions.push('watcher = @watcher');
67
+ params.watcher = watcher;
68
+ }
69
+ if (severity) {
70
+ conditions.push('severity = @severity');
71
+ params.severity = severity;
72
+ }
73
+ if (conditions.length > 0) {
74
+ query += ' WHERE ' + conditions.join(' AND ');
75
+ }
76
+ query += ' ORDER BY id DESC LIMIT @limit';
77
+ return db.prepare(query).all(params);
78
+ }
79
+ function pruneOldEvents(retentionDays) {
80
+ const db = getDb();
81
+ const result = db.prepare(`
82
+ DELETE FROM events WHERE created_at < datetime('now', '-' || ? || ' days')
83
+ `).run(retentionDays);
84
+ return result.changes;
85
+ }
86
+ function closeDb() {
87
+ if (_db) {
88
+ _db.close();
89
+ _db = null;
90
+ }
91
+ }
92
+ function getEventCount() {
93
+ const db = getDb();
94
+ const row = db.prepare('SELECT COUNT(*) as count FROM events').get();
95
+ return row.count;
96
+ }
97
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/test/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const node_test_1 = require("node:test");
40
+ const strict_1 = __importDefault(require("node:assert/strict"));
41
+ const fs_1 = __importDefault(require("fs"));
42
+ const path_1 = __importDefault(require("path"));
43
+ const os_1 = __importDefault(require("os"));
44
+ // We test config validation by importing config functions after patching paths
45
+ const tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'clawdoctor-test-'));
46
+ const configPath = path_1.default.join(tmpDir, 'config.json');
47
+ (0, node_test_1.describe)('Config', () => {
48
+ (0, node_test_1.after)(() => {
49
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
50
+ });
51
+ (0, node_test_1.it)('DEFAULT_CONFIG has all required fields', async () => {
52
+ const { DEFAULT_CONFIG } = await Promise.resolve().then(() => __importStar(require('../config.js')));
53
+ strict_1.default.ok(DEFAULT_CONFIG.watchers.gateway);
54
+ strict_1.default.ok(DEFAULT_CONFIG.watchers.cron);
55
+ strict_1.default.ok(DEFAULT_CONFIG.watchers.session);
56
+ strict_1.default.ok(DEFAULT_CONFIG.watchers.auth);
57
+ strict_1.default.ok(DEFAULT_CONFIG.watchers.cost);
58
+ strict_1.default.ok(DEFAULT_CONFIG.healers.processRestart);
59
+ strict_1.default.ok(DEFAULT_CONFIG.healers.cronRetry);
60
+ strict_1.default.ok(DEFAULT_CONFIG.alerts.telegram);
61
+ strict_1.default.equal(DEFAULT_CONFIG.dryRun, false);
62
+ strict_1.default.equal(DEFAULT_CONFIG.retentionDays, 7);
63
+ });
64
+ (0, node_test_1.it)('DEFAULT_CONFIG watcher intervals are sane', async () => {
65
+ const { DEFAULT_CONFIG } = await Promise.resolve().then(() => __importStar(require('../config.js')));
66
+ strict_1.default.equal(DEFAULT_CONFIG.watchers.gateway.interval, 30);
67
+ strict_1.default.equal(DEFAULT_CONFIG.watchers.cron.interval, 60);
68
+ strict_1.default.equal(DEFAULT_CONFIG.watchers.session.interval, 60);
69
+ strict_1.default.equal(DEFAULT_CONFIG.watchers.auth.interval, 60);
70
+ strict_1.default.equal(DEFAULT_CONFIG.watchers.cost.interval, 300);
71
+ });
72
+ (0, node_test_1.it)('saveConfig and loadConfig roundtrip', async () => {
73
+ // Write config manually to temp path
74
+ const { DEFAULT_CONFIG } = await Promise.resolve().then(() => __importStar(require('../config.js')));
75
+ const testConfig = { ...DEFAULT_CONFIG, dryRun: true, retentionDays: 14 };
76
+ fs_1.default.writeFileSync(configPath, JSON.stringify(testConfig, null, 2));
77
+ const parsed = JSON.parse(fs_1.default.readFileSync(configPath, 'utf-8'));
78
+ strict_1.default.equal(parsed.dryRun, true);
79
+ strict_1.default.equal(parsed.retentionDays, 14);
80
+ strict_1.default.ok(parsed.watchers);
81
+ strict_1.default.ok(parsed.alerts);
82
+ });
83
+ (0, node_test_1.it)('configExists returns false when no config file', async () => {
84
+ const { configExists } = await Promise.resolve().then(() => __importStar(require('../config.js')));
85
+ // configExists checks the real AGENTWATCH_DIR — just verify it's a boolean
86
+ const result = configExists();
87
+ strict_1.default.equal(typeof result, 'boolean');
88
+ });
89
+ });
90
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/test/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=store.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../src/test/store.test.ts"],"names":[],"mappings":""}