@aiassesstech/mighty-mark 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/agent/AGENTS.md +61 -0
- package/agent/IDENTITY.md +18 -0
- package/agent/SOUL.md +56 -0
- package/dist/checks/agent-verify.d.ts +15 -0
- package/dist/checks/agent-verify.d.ts.map +1 -0
- package/dist/checks/agent-verify.js +100 -0
- package/dist/checks/agent-verify.js.map +1 -0
- package/dist/checks/api-connectivity.d.ts +14 -0
- package/dist/checks/api-connectivity.d.ts.map +1 -0
- package/dist/checks/api-connectivity.js +77 -0
- package/dist/checks/api-connectivity.js.map +1 -0
- package/dist/checks/check-context.d.ts +36 -0
- package/dist/checks/check-context.d.ts.map +1 -0
- package/dist/checks/check-context.js +42 -0
- package/dist/checks/check-context.js.map +1 -0
- package/dist/checks/check-runner.d.ts +18 -0
- package/dist/checks/check-runner.d.ts.map +1 -0
- package/dist/checks/check-runner.js +109 -0
- package/dist/checks/check-runner.js.map +1 -0
- package/dist/checks/data-integrity.d.ts +16 -0
- package/dist/checks/data-integrity.d.ts.map +1 -0
- package/dist/checks/data-integrity.js +152 -0
- package/dist/checks/data-integrity.js.map +1 -0
- package/dist/checks/gateway-health.d.ts +17 -0
- package/dist/checks/gateway-health.d.ts.map +1 -0
- package/dist/checks/gateway-health.js +208 -0
- package/dist/checks/gateway-health.js.map +1 -0
- package/dist/checks/system-resources.d.ts +21 -0
- package/dist/checks/system-resources.d.ts.map +1 -0
- package/dist/checks/system-resources.js +136 -0
- package/dist/checks/system-resources.js.map +1 -0
- package/dist/cli/bin.d.ts +8 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +12 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/runner.d.ts +11 -0
- package/dist/cli/runner.d.ts.map +1 -0
- package/dist/cli/runner.js +99 -0
- package/dist/cli/runner.js.map +1 -0
- package/dist/cli/setup.d.ts +28 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +238 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/config/config-schema.d.ts +56 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +34 -0
- package/dist/config/config-schema.js.map +1 -0
- package/dist/config/defaults.d.ts +31 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +31 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/fleet-topology.d.ts +22 -0
- package/dist/config/fleet-topology.d.ts.map +1 -0
- package/dist/config/fleet-topology.js +81 -0
- package/dist/config/fleet-topology.js.map +1 -0
- package/dist/history/incident-log.d.ts +19 -0
- package/dist/history/incident-log.d.ts.map +1 -0
- package/dist/history/incident-log.js +50 -0
- package/dist/history/incident-log.js.map +1 -0
- package/dist/history/trend-analyzer.d.ts +18 -0
- package/dist/history/trend-analyzer.d.ts.map +1 -0
- package/dist/history/trend-analyzer.js +80 -0
- package/dist/history/trend-analyzer.js.map +1 -0
- package/dist/history/uptime-tracker.d.ts +15 -0
- package/dist/history/uptime-tracker.d.ts.map +1 -0
- package/dist/history/uptime-tracker.js +56 -0
- package/dist/history/uptime-tracker.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/dist/notify/alert-classifier.d.ts +19 -0
- package/dist/notify/alert-classifier.d.ts.map +1 -0
- package/dist/notify/alert-classifier.js +45 -0
- package/dist/notify/alert-classifier.js.map +1 -0
- package/dist/notify/report-formatter.d.ts +21 -0
- package/dist/notify/report-formatter.d.ts.map +1 -0
- package/dist/notify/report-formatter.js +139 -0
- package/dist/notify/report-formatter.js.map +1 -0
- package/dist/notify/telegram-notifier.d.ts +28 -0
- package/dist/notify/telegram-notifier.d.ts.map +1 -0
- package/dist/notify/telegram-notifier.js +69 -0
- package/dist/notify/telegram-notifier.js.map +1 -0
- package/dist/plugin.d.ts +18 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +289 -0
- package/dist/plugin.js.map +1 -0
- package/dist/store/json-store.d.ts +22 -0
- package/dist/store/json-store.d.ts.map +1 -0
- package/dist/store/json-store.js +128 -0
- package/dist/store/json-store.js.map +1 -0
- package/dist/store/types.d.ts +19 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +5 -0
- package/dist/store/types.js.map +1 -0
- package/dist/types/events.d.ts +33 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +5 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/fleet.d.ts +27 -0
- package/dist/types/fleet.d.ts.map +1 -0
- package/dist/types/fleet.js +6 -0
- package/dist/types/fleet.js.map +1 -0
- package/dist/types/health.d.ts +58 -0
- package/dist/types/health.d.ts.map +1 -0
- package/dist/types/health.js +5 -0
- package/dist/types/health.js.map +1 -0
- package/dist/types/incident.d.ts +35 -0
- package/dist/types/incident.d.ts.map +1 -0
- package/dist/types/incident.js +5 -0
- package/dist/types/incident.js.map +1 -0
- package/openclaw.plugin.json +56 -0
- package/package.json +71 -0
- package/src/watchdog/README.md +123 -0
- package/src/watchdog/install.sh +244 -0
- package/src/watchdog/lib/config.sh +44 -0
- package/src/watchdog/lib/logging.sh +29 -0
- package/src/watchdog/lib/notify.sh +46 -0
- package/src/watchdog/morning-check.sh +107 -0
- package/src/watchdog/openclaw-gateway.service +43 -0
- package/src/watchdog/watchdog.sh +124 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON file-based store for Mighty Mark — Phase 1 persistence.
|
|
3
|
+
* Same proven pattern used by Grillo and Noah.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
export class JsonStore {
|
|
8
|
+
dataDir;
|
|
9
|
+
constructor(dataDir) {
|
|
10
|
+
this.dataDir = dataDir;
|
|
11
|
+
}
|
|
12
|
+
async initialize() {
|
|
13
|
+
const dirs = [
|
|
14
|
+
this.dataDir,
|
|
15
|
+
path.join(this.dataDir, 'state'),
|
|
16
|
+
path.join(this.dataDir, 'history', 'daily'),
|
|
17
|
+
path.join(this.dataDir, 'incidents'),
|
|
18
|
+
path.join(this.dataDir, 'config'),
|
|
19
|
+
];
|
|
20
|
+
for (const dir of dirs) {
|
|
21
|
+
if (!fs.existsSync(dir)) {
|
|
22
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async isWritable() {
|
|
27
|
+
const testFile = path.join(this.dataDir, '.write-test');
|
|
28
|
+
try {
|
|
29
|
+
fs.writeFileSync(testFile, 'mark-self-check');
|
|
30
|
+
fs.unlinkSync(testFile);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// ── Last Check ──
|
|
38
|
+
async saveLastCheck(report) {
|
|
39
|
+
const filePath = path.join(this.dataDir, 'state', 'last-check.json');
|
|
40
|
+
fs.writeFileSync(filePath, JSON.stringify(report, null, 2) + '\n');
|
|
41
|
+
}
|
|
42
|
+
async getLastCheck() {
|
|
43
|
+
const filePath = path.join(this.dataDir, 'state', 'last-check.json');
|
|
44
|
+
if (!fs.existsSync(filePath))
|
|
45
|
+
return null;
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// ── Daily History ──
|
|
54
|
+
async saveDailyHealth(entry) {
|
|
55
|
+
const filePath = path.join(this.dataDir, 'history', 'daily', `${entry.date}.json`);
|
|
56
|
+
fs.writeFileSync(filePath, JSON.stringify(entry, null, 2) + '\n');
|
|
57
|
+
}
|
|
58
|
+
async getDailyHistory(days) {
|
|
59
|
+
const dir = path.join(this.dataDir, 'history', 'daily');
|
|
60
|
+
if (!fs.existsSync(dir))
|
|
61
|
+
return [];
|
|
62
|
+
const cutoff = new Date();
|
|
63
|
+
cutoff.setDate(cutoff.getDate() - days);
|
|
64
|
+
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
65
|
+
const files = fs.readdirSync(dir)
|
|
66
|
+
.filter(f => f.endsWith('.json'))
|
|
67
|
+
.filter(f => f.replace('.json', '') >= cutoffStr)
|
|
68
|
+
.sort();
|
|
69
|
+
const results = [];
|
|
70
|
+
for (const file of files) {
|
|
71
|
+
try {
|
|
72
|
+
const data = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf-8'));
|
|
73
|
+
results.push(data);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Skip corrupted files
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
// ── Incidents ──
|
|
82
|
+
async saveIncident(incident) {
|
|
83
|
+
const filePath = path.join(this.dataDir, 'incidents', `${incident.id}.json`);
|
|
84
|
+
fs.writeFileSync(filePath, JSON.stringify(incident, null, 2) + '\n');
|
|
85
|
+
}
|
|
86
|
+
async getIncident(id) {
|
|
87
|
+
const filePath = path.join(this.dataDir, 'incidents', `${id}.json`);
|
|
88
|
+
if (!fs.existsSync(filePath))
|
|
89
|
+
return null;
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async getIncidents(days) {
|
|
98
|
+
const dir = path.join(this.dataDir, 'incidents');
|
|
99
|
+
if (!fs.existsSync(dir))
|
|
100
|
+
return [];
|
|
101
|
+
const cutoff = new Date();
|
|
102
|
+
cutoff.setDate(cutoff.getDate() - days);
|
|
103
|
+
const files = fs.readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
104
|
+
const results = [];
|
|
105
|
+
for (const file of files) {
|
|
106
|
+
try {
|
|
107
|
+
const data = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf-8'));
|
|
108
|
+
if (new Date(data.timestamp) >= cutoff) {
|
|
109
|
+
results.push(data);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Skip corrupted files
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return results.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
117
|
+
}
|
|
118
|
+
async resolveIncident(id, resolution) {
|
|
119
|
+
const incident = await this.getIncident(id);
|
|
120
|
+
if (!incident)
|
|
121
|
+
return;
|
|
122
|
+
incident.resolved = true;
|
|
123
|
+
incident.resolvedAt = new Date().toISOString();
|
|
124
|
+
incident.resolution = resolution;
|
|
125
|
+
await this.saveIncident(incident);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=json-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-store.js","sourceRoot":"","sources":["../../src/store/json-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store interface types for Mighty Mark persistence.
|
|
3
|
+
*/
|
|
4
|
+
import type { MorningReport } from '../types/health.js';
|
|
5
|
+
import type { Incident, DailyHealth } from '../types/incident.js';
|
|
6
|
+
/** Abstract store interface — Phase 1 uses JSON files, Phase 2 could use Postgres. */
|
|
7
|
+
export interface MarkStore {
|
|
8
|
+
saveLastCheck(report: MorningReport): Promise<void>;
|
|
9
|
+
getLastCheck(): Promise<MorningReport | null>;
|
|
10
|
+
saveDailyHealth(entry: DailyHealth): Promise<void>;
|
|
11
|
+
getDailyHistory(days: number): Promise<DailyHealth[]>;
|
|
12
|
+
saveIncident(incident: Incident): Promise<void>;
|
|
13
|
+
getIncident(id: string): Promise<Incident | null>;
|
|
14
|
+
getIncidents(days: number): Promise<Incident[]>;
|
|
15
|
+
resolveIncident(id: string, resolution: string): Promise<void>;
|
|
16
|
+
initialize(): Promise<void>;
|
|
17
|
+
isWritable(): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAElE,sFAAsF;AACtF,MAAM,WAAW,SAAS;IAExB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,YAAY,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAG9C,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAGtD,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAClD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChD,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG/D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event types emitted by Mighty Mark during health checks.
|
|
3
|
+
*/
|
|
4
|
+
import type { HealthStatus, CheckResult } from './health.js';
|
|
5
|
+
import type { Incident } from './incident.js';
|
|
6
|
+
/** Emitted after a full health check completes. */
|
|
7
|
+
export interface HealthCheckEvent {
|
|
8
|
+
type: 'health-check-complete';
|
|
9
|
+
timestamp: string;
|
|
10
|
+
status: HealthStatus;
|
|
11
|
+
passedChecks: number;
|
|
12
|
+
totalChecks: number;
|
|
13
|
+
failures: CheckResult[];
|
|
14
|
+
}
|
|
15
|
+
/** Emitted when a new incident is created. */
|
|
16
|
+
export interface IncidentEvent {
|
|
17
|
+
type: 'incident-created';
|
|
18
|
+
incident: Incident;
|
|
19
|
+
}
|
|
20
|
+
/** Emitted when an incident is resolved. */
|
|
21
|
+
export interface IncidentResolvedEvent {
|
|
22
|
+
type: 'incident-resolved';
|
|
23
|
+
incidentId: string;
|
|
24
|
+
resolution: string;
|
|
25
|
+
resolvedAt: string;
|
|
26
|
+
}
|
|
27
|
+
/** Emitted when the watchdog restarts the gateway. */
|
|
28
|
+
export interface WatchdogRecoveryEvent {
|
|
29
|
+
type: 'watchdog-recovery';
|
|
30
|
+
timestamp: string;
|
|
31
|
+
restartCount: number;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAiB,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fleet topology types for Mighty Mark.
|
|
3
|
+
* The fleet topology is loaded from an external JSON file (BB-editable, no rebuild).
|
|
4
|
+
*/
|
|
5
|
+
/** Definition of a single agent in the fleet. */
|
|
6
|
+
export interface FleetAgent {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
role: string;
|
|
10
|
+
model: string;
|
|
11
|
+
hasPlugin: boolean;
|
|
12
|
+
pluginId?: string;
|
|
13
|
+
requiredPromptFiles: string[];
|
|
14
|
+
requiredKnowledge: boolean;
|
|
15
|
+
dataChecks: string[];
|
|
16
|
+
}
|
|
17
|
+
/** The full fleet topology — loaded from fleet-topology.json at runtime. */
|
|
18
|
+
export interface FleetTopology {
|
|
19
|
+
version: string;
|
|
20
|
+
lastUpdated?: string;
|
|
21
|
+
updatedBy?: string;
|
|
22
|
+
agents: FleetAgent[];
|
|
23
|
+
plugins: string[];
|
|
24
|
+
expectedMinToolCount: number;
|
|
25
|
+
notes?: string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=fleet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet.d.ts","sourceRoot":"","sources":["../../src/types/fleet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet.js","sourceRoot":"","sources":["../../src/types/fleet.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core health status types for Mighty Mark.
|
|
3
|
+
*/
|
|
4
|
+
/** Overall system health classification. */
|
|
5
|
+
export type HealthStatus = 'GREEN' | 'YELLOW' | 'RED';
|
|
6
|
+
/** Check category — the five pillars of health monitoring. */
|
|
7
|
+
export type CheckCategory = 'gateway' | 'agents' | 'system' | 'api' | 'data';
|
|
8
|
+
/** Severity level for individual checks and incidents. */
|
|
9
|
+
export type Severity = 'critical' | 'high' | 'medium' | 'low';
|
|
10
|
+
/** Status of an individual check. */
|
|
11
|
+
export type CheckStatus = 'pass' | 'fail' | 'warn';
|
|
12
|
+
/** Result of a single health check. */
|
|
13
|
+
export interface CheckResult {
|
|
14
|
+
name: string;
|
|
15
|
+
category: CheckCategory;
|
|
16
|
+
status: CheckStatus;
|
|
17
|
+
message?: string;
|
|
18
|
+
timestamp: string;
|
|
19
|
+
durationMs: number;
|
|
20
|
+
}
|
|
21
|
+
/** Aggregated morning report. */
|
|
22
|
+
export interface MorningReport {
|
|
23
|
+
timestamp: string;
|
|
24
|
+
status: HealthStatus;
|
|
25
|
+
summary: {
|
|
26
|
+
total: number;
|
|
27
|
+
passed: number;
|
|
28
|
+
failed: number;
|
|
29
|
+
warnings: number;
|
|
30
|
+
};
|
|
31
|
+
checks: CheckResult[];
|
|
32
|
+
hostname: string;
|
|
33
|
+
uptime: string;
|
|
34
|
+
durationMs: number;
|
|
35
|
+
}
|
|
36
|
+
/** Quick status snapshot (returned by mark_status). */
|
|
37
|
+
export interface StatusSnapshot {
|
|
38
|
+
status: HealthStatus;
|
|
39
|
+
lastCheck: string | null;
|
|
40
|
+
lastCheckStatus: HealthStatus | null;
|
|
41
|
+
activeIncidents: number;
|
|
42
|
+
uptimePercent7d: number | null;
|
|
43
|
+
hostname: string;
|
|
44
|
+
}
|
|
45
|
+
/** Category-scoped check results (returned by mark_check). */
|
|
46
|
+
export interface CategoryResults {
|
|
47
|
+
category: CheckCategory;
|
|
48
|
+
checks: CheckResult[];
|
|
49
|
+
summary: {
|
|
50
|
+
total: number;
|
|
51
|
+
passed: number;
|
|
52
|
+
failed: number;
|
|
53
|
+
warnings: number;
|
|
54
|
+
};
|
|
55
|
+
timestamp: string;
|
|
56
|
+
durationMs: number;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/types/health.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,4CAA4C;AAC5C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7E,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9D,qCAAqC;AACrC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD,uCAAuC;AACvC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,YAAY,GAAG,IAAI,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/types/health.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incident types for Mighty Mark.
|
|
3
|
+
*/
|
|
4
|
+
import type { CheckCategory, CheckResult, Severity } from './health.js';
|
|
5
|
+
/** A recorded incident — created when checks fail. */
|
|
6
|
+
export interface Incident {
|
|
7
|
+
id: string;
|
|
8
|
+
timestamp: string;
|
|
9
|
+
severity: Severity;
|
|
10
|
+
category: CheckCategory;
|
|
11
|
+
description: string;
|
|
12
|
+
checkResults: CheckResult[];
|
|
13
|
+
resolved: boolean;
|
|
14
|
+
resolvedAt?: string;
|
|
15
|
+
resolution?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Daily health summary for uptime tracking. */
|
|
18
|
+
export interface DailyHealth {
|
|
19
|
+
date: string;
|
|
20
|
+
status: 'GREEN' | 'YELLOW' | 'RED';
|
|
21
|
+
passedChecks: number;
|
|
22
|
+
totalChecks: number;
|
|
23
|
+
incidents: number;
|
|
24
|
+
}
|
|
25
|
+
/** Uptime data (returned by mark_uptime). */
|
|
26
|
+
export interface UptimeData {
|
|
27
|
+
days: number;
|
|
28
|
+
percentage: number;
|
|
29
|
+
totalChecks: number;
|
|
30
|
+
greenDays: number;
|
|
31
|
+
yellowDays: number;
|
|
32
|
+
redDays: number;
|
|
33
|
+
history: DailyHealth[];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=incident.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incident.d.ts","sourceRoot":"","sources":["../../src/types/incident.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAExE,sDAAsD;AACtD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incident.js","sourceRoot":"","sources":["../../src/types/incident.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "mighty-mark",
|
|
3
|
+
"name": "Mighty Mark — System Health Sentinel",
|
|
4
|
+
"description": "System health monitoring for the AI Assess Tech fleet. Runs 26 health checks across 5 categories (gateway, agents, system, api, data), sends daily morning reports via Telegram, tracks uptime SLA, and logs incidents.",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"healthCheckKey": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "CompSi Health Check Key from AI Assess platform (hck_...)"
|
|
12
|
+
},
|
|
13
|
+
"telegramToken": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "@MightyMarkBot Telegram bot token"
|
|
16
|
+
},
|
|
17
|
+
"telegramChatId": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Telegram chat ID for morning reports and alerts"
|
|
20
|
+
},
|
|
21
|
+
"morningCheckHourCt": {
|
|
22
|
+
"type": "number",
|
|
23
|
+
"description": "Hour (0-23) for the morning check in America/Chicago time (default: 6 for 6 AM CT)",
|
|
24
|
+
"default": 6
|
|
25
|
+
},
|
|
26
|
+
"diskThresholdPercent": {
|
|
27
|
+
"type": "number",
|
|
28
|
+
"description": "Minimum % disk space free before warning (default: 20)",
|
|
29
|
+
"default": 20
|
|
30
|
+
},
|
|
31
|
+
"memoryThresholdMb": {
|
|
32
|
+
"type": "number",
|
|
33
|
+
"description": "Minimum MB memory available before warning (default: 256)",
|
|
34
|
+
"default": 256
|
|
35
|
+
},
|
|
36
|
+
"cpuThreshold": {
|
|
37
|
+
"type": "number",
|
|
38
|
+
"description": "Maximum 5-min CPU load average before warning (default: 3.0)",
|
|
39
|
+
"default": 3.0
|
|
40
|
+
},
|
|
41
|
+
"dataDir": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Directory for Mark's data storage (default: .mighty-mark-data)",
|
|
44
|
+
"default": ".mighty-mark-data"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": []
|
|
48
|
+
},
|
|
49
|
+
"uiHints": {
|
|
50
|
+
"healthCheckKey": { "label": "Health Check Key", "sensitive": true },
|
|
51
|
+
"telegramToken": { "label": "Telegram Bot Token", "sensitive": true },
|
|
52
|
+
"telegramChatId": { "label": "Telegram Chat ID" },
|
|
53
|
+
"morningCheckHourCt": { "label": "Morning Check Hour (CT)", "placeholder": "6" },
|
|
54
|
+
"dataDir": { "label": "Data Directory", "placeholder": ".mighty-mark-data" }
|
|
55
|
+
}
|
|
56
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aiassesstech/mighty-mark",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "System Health Sentinel for AI Assess Tech Fleet — autonomous monitoring, watchdog recovery, and fleet infrastructure oversight.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"openclaw": {
|
|
9
|
+
"extensions": [
|
|
10
|
+
"./dist/plugin.js"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"mighty-mark": "./dist/cli/bin.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"agent",
|
|
19
|
+
"openclaw.plugin.json",
|
|
20
|
+
"src/watchdog",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "tsc --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"typecheck": "tsc --noEmit",
|
|
32
|
+
"lint": "tsc --noEmit",
|
|
33
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mighty-mark",
|
|
37
|
+
"system-health",
|
|
38
|
+
"watchdog",
|
|
39
|
+
"monitoring",
|
|
40
|
+
"ai-fleet",
|
|
41
|
+
"openclaw-plugin",
|
|
42
|
+
"health-check",
|
|
43
|
+
"telegram-alerts",
|
|
44
|
+
"infrastructure"
|
|
45
|
+
],
|
|
46
|
+
"author": "GiDanc AI LLC",
|
|
47
|
+
"license": "Proprietary",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/spar65/compsi.git",
|
|
51
|
+
"directory": "packages/mighty-mark"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://www.aiassesstech.com",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/spar65/compsi/issues"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"zod": "^3.22.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^20.0.0",
|
|
62
|
+
"typescript": "^5.3.3",
|
|
63
|
+
"vitest": "^1.2.0"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=18.0.0"
|
|
67
|
+
},
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Mighty Mark — Watchdog Deployment
|
|
2
|
+
|
|
3
|
+
Pure bash watchdog and morning check scripts for the Hetzner VPS.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Ubuntu 24 on Hetzner VPS
|
|
8
|
+
- OpenClaw gateway installed and configured
|
|
9
|
+
- `@MightyMarkBot` created on Telegram (token required)
|
|
10
|
+
- `jq` installed (`apt install jq`)
|
|
11
|
+
- `curl` installed (usually pre-installed)
|
|
12
|
+
|
|
13
|
+
## Quick Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# After npm install of @aiassesstech/mighty-mark:
|
|
17
|
+
npx @aiassesstech/mighty-mark install-watchdog \
|
|
18
|
+
--telegram-token "YOUR_BOT_TOKEN" \
|
|
19
|
+
--telegram-chat-id "YOUR_CHAT_ID"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or run the installer directly:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
sudo bash src/watchdog/install.sh \
|
|
26
|
+
--telegram-token "YOUR_BOT_TOKEN" \
|
|
27
|
+
--telegram-chat-id "YOUR_CHAT_ID"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## What Gets Installed
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
/opt/mighty-mark/
|
|
34
|
+
├── watchdog.sh # Cron: every 5 min — gateway heartbeat
|
|
35
|
+
├── morning-check.sh # Cron: daily 6:00 AM CT — full health check
|
|
36
|
+
├── lib/
|
|
37
|
+
│ ├── config.sh # Shared configuration
|
|
38
|
+
│ ├── logging.sh # Structured logging functions
|
|
39
|
+
│ └── notify.sh # Telegram notification functions
|
|
40
|
+
├── logs/
|
|
41
|
+
│ ├── watchdog.log # Watchdog heartbeats + incidents
|
|
42
|
+
│ ├── morning-check.log # Daily check results
|
|
43
|
+
│ ├── watchdog-cron.log # Cron stdout/stderr capture
|
|
44
|
+
│ └── morning-cron.log # Cron stdout/stderr capture
|
|
45
|
+
├── state/
|
|
46
|
+
│ └── incident-count.json # Daily restart counter
|
|
47
|
+
└── .env # Telegram credentials (chmod 600)
|
|
48
|
+
|
|
49
|
+
/etc/cron.d/mighty-mark # Cron schedule (CRON_TZ=America/Chicago)
|
|
50
|
+
/etc/logrotate.d/mighty-mark # 14-day log rotation
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Cron Schedule
|
|
54
|
+
|
|
55
|
+
```cron
|
|
56
|
+
CRON_TZ=America/Chicago
|
|
57
|
+
|
|
58
|
+
# Watchdog: every 5 minutes
|
|
59
|
+
*/5 * * * * root /opt/mighty-mark/watchdog.sh
|
|
60
|
+
|
|
61
|
+
# Morning Check: daily at 6:00 AM CT (auto-adjusts for CDT/CST)
|
|
62
|
+
0 6 * * * root /opt/mighty-mark/morning-check.sh
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`CRON_TZ=America/Chicago` ensures 6:00 AM stays 6:00 AM regardless of Daylight Saving Time.
|
|
66
|
+
|
|
67
|
+
## Watchdog Behavior
|
|
68
|
+
|
|
69
|
+
1. Runs every 5 minutes via cron
|
|
70
|
+
2. Checks `pgrep -f openclaw-gateway`
|
|
71
|
+
3. **Alive**: Log heartbeat, exit
|
|
72
|
+
4. **Dead**: Attempt restart via `systemctl restart openclaw-gateway`
|
|
73
|
+
5. **Restart succeeds**: Notify Greg via Telegram, log recovery
|
|
74
|
+
6. **Restart fails**: Notify Greg with escalation alert
|
|
75
|
+
7. **Max 3 restarts/day**: After that, manual intervention required
|
|
76
|
+
|
|
77
|
+
## Systemd Service (Optional)
|
|
78
|
+
|
|
79
|
+
Belt-and-suspenders with the watchdog:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
sudo cp src/watchdog/openclaw-gateway.service /etc/systemd/system/
|
|
83
|
+
sudo systemctl daemon-reload
|
|
84
|
+
sudo systemctl enable openclaw-gateway
|
|
85
|
+
sudo systemctl start openclaw-gateway
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Systemd handles fast restarts (30s). The watchdog handles the case where systemd gives up after 5 failures.
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
Edit `/opt/mighty-mark/.env`:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
MIGHTY_MARK_TELEGRAM_TOKEN="your-bot-token"
|
|
96
|
+
MIGHTY_MARK_TELEGRAM_CHAT_ID="your-chat-id"
|
|
97
|
+
MAX_RESTART_ATTEMPTS=3
|
|
98
|
+
DISK_WARN_PERCENT=20
|
|
99
|
+
MEMORY_WARN_MB=256
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Manual Testing
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Test watchdog
|
|
106
|
+
bash /opt/mighty-mark/watchdog.sh
|
|
107
|
+
|
|
108
|
+
# Test morning check
|
|
109
|
+
bash /opt/mighty-mark/morning-check.sh
|
|
110
|
+
|
|
111
|
+
# View logs
|
|
112
|
+
tail -f /opt/mighty-mark/logs/watchdog.log
|
|
113
|
+
tail -f /opt/mighty-mark/logs/morning-check.log
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Troubleshooting
|
|
117
|
+
|
|
118
|
+
| Symptom | Cause | Fix |
|
|
119
|
+
|---------|-------|-----|
|
|
120
|
+
| No Telegram alerts | Token/chat ID not set | Edit `.env` |
|
|
121
|
+
| Watchdog not running | Cron not installed | Check `/etc/cron.d/mighty-mark` |
|
|
122
|
+
| Morning check fails | Node.js not in PATH | Falls back to bash-only checks |
|
|
123
|
+
| Max restarts reached | Gateway keeps crashing | Check `journalctl -u openclaw-gateway` |
|