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.
- package/README.md +112 -0
- package/dist/alerters/telegram.d.ts +21 -0
- package/dist/alerters/telegram.d.ts.map +1 -0
- package/dist/alerters/telegram.js +87 -0
- package/dist/alerters/telegram.js.map +1 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +21 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +172 -0
- package/dist/daemon.js.map +1 -0
- package/dist/healers/base.d.ts +15 -0
- package/dist/healers/base.d.ts.map +1 -0
- package/dist/healers/base.js +25 -0
- package/dist/healers/base.js.map +1 -0
- package/dist/healers/cron.d.ts +6 -0
- package/dist/healers/cron.d.ts.map +1 -0
- package/dist/healers/cron.js +26 -0
- package/dist/healers/cron.js.map +1 -0
- package/dist/healers/process.d.ts +6 -0
- package/dist/healers/process.d.ts.map +1 -0
- package/dist/healers/process.js +67 -0
- package/dist/healers/process.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +283 -0
- package/dist/index.js.map +1 -0
- package/dist/store.d.ts +22 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +97 -0
- package/dist/store.js.map +1 -0
- package/dist/test/config.test.d.ts +2 -0
- package/dist/test/config.test.d.ts.map +1 -0
- package/dist/test/config.test.js +90 -0
- package/dist/test/config.test.js.map +1 -0
- package/dist/test/store.test.d.ts +2 -0
- package/dist/test/store.test.d.ts.map +1 -0
- package/dist/test/store.test.js +89 -0
- package/dist/test/store.test.js.map +1 -0
- package/dist/test/telegram.test.d.ts +2 -0
- package/dist/test/telegram.test.d.ts.map +1 -0
- package/dist/test/telegram.test.js +107 -0
- package/dist/test/telegram.test.js.map +1 -0
- package/dist/test/watchers.test.d.ts +2 -0
- package/dist/test/watchers.test.d.ts.map +1 -0
- package/dist/test/watchers.test.js +194 -0
- package/dist/test/watchers.test.js.map +1 -0
- package/dist/utils.d.ts +18 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +62 -0
- package/dist/utils.js.map +1 -0
- package/dist/watchers/auth.d.ts +10 -0
- package/dist/watchers/auth.d.ts.map +1 -0
- package/dist/watchers/auth.js +79 -0
- package/dist/watchers/auth.js.map +1 -0
- package/dist/watchers/base.d.ts +22 -0
- package/dist/watchers/base.d.ts.map +1 -0
- package/dist/watchers/base.js +39 -0
- package/dist/watchers/base.js.map +1 -0
- package/dist/watchers/cost.d.ts +9 -0
- package/dist/watchers/cost.d.ts.map +1 -0
- package/dist/watchers/cost.js +151 -0
- package/dist/watchers/cost.js.map +1 -0
- package/dist/watchers/cron.d.ts +7 -0
- package/dist/watchers/cron.d.ts.map +1 -0
- package/dist/watchers/cron.js +79 -0
- package/dist/watchers/cron.js.map +1 -0
- package/dist/watchers/gateway.d.ts +7 -0
- package/dist/watchers/gateway.d.ts.map +1 -0
- package/dist/watchers/gateway.js +33 -0
- package/dist/watchers/gateway.js.map +1 -0
- package/dist/watchers/session.d.ts +7 -0
- package/dist/watchers/session.d.ts.map +1 -0
- package/dist/watchers/session.js +112 -0
- package/dist/watchers/session.js.map +1 -0
- 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 @@
|
|
|
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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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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"}
|
package/dist/store.d.ts
ADDED
|
@@ -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":";;;;;AAsDA,kCAiBC;AAED,0CAqBC;AAED,wCAMC;AAED,0BAKC;AAED,sCAIC;AAnHD,oEAAsC;AACtC,2CAA2D;AAqB3D,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC,SAAS,KAAK;IACZ,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,IAAA,+BAAmB,GAAE,CAAC;QACtB,GAAG,GAAG,IAAI,wBAAQ,CAAC,mBAAO,CAAC,CAAC;QAC5B,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACjC,UAAU,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,UAAU,CAAC,EAAqB;IACvC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;GAgBP,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,WAAW,CAAC,KAAuC;IACjE,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGvB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;QACxC,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI;KAC3C,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,eAAyB,CAAC;AAC1C,CAAC;AAED,SAAgB,eAAe,CAAC,KAAK,GAAG,EAAE,EAAE,OAAgB,EAAE,QAAmB;IAC/E,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,IAAI,KAAK,GAAG,sBAAsB,CAAC;IACnC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,MAAM,GAAoC,EAAE,KAAK,EAAE,CAAC;IAE1D,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,UAAU,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,IAAI,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,KAAK,IAAI,gCAAgC,CAAC;IAE1C,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAe,CAAC;AACrD,CAAC;AAED,SAAgB,cAAc,CAAC,aAAqB;IAClD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;GAEzB,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAED,SAAgB,OAAO;IACrB,IAAI,GAAG,EAAE,CAAC;QACR,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAgB,aAAa;IAC3B,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAAuB,CAAC;IAC1F,OAAO,GAAG,CAAC,KAAK,CAAC;AACnB,CAAC"}
|
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAwD;AACxD,gEAAwC;AACxC,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,+EAA+E;AAC/E,MAAM,MAAM,GAAG,YAAE,CAAC,WAAW,CAAC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAC1E,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAEpD,IAAA,oBAAQ,EAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,IAAA,iBAAK,EAAC,GAAG,EAAE;QACT,YAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,cAAc,GAAC,CAAC;QACxD,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3C,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3C,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACjD,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5C,gBAAM,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3C,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,cAAc,GAAC,CAAC;QACxD,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3D,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3D,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,gBAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,qCAAqC;QACrC,MAAM,EAAE,cAAc,EAAE,GAAG,wDAAa,cAAc,GAAC,CAAC;QACxD,MAAM,UAAU,GAAG,EAAE,GAAG,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;QAC1E,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClC,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACvC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3B,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,cAAc,GAAC,CAAC;QACtD,2EAA2E;QAC3E,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,gBAAM,CAAC,KAAK,CAAC,OAAO,MAAM,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../src/test/store.test.ts"],"names":[],"mappings":""}
|