craftclose 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/LICENSE +21 -0
- package/README.md +176 -0
- package/SKILL.md +139 -0
- package/craftclose.example.yml +84 -0
- package/dist/ai-analyzer.d.ts +96 -0
- package/dist/ai-analyzer.d.ts.map +1 -0
- package/dist/ai-analyzer.js +275 -0
- package/dist/ai-analyzer.js.map +1 -0
- package/dist/alerts/discord.d.ts +23 -0
- package/dist/alerts/discord.d.ts.map +1 -0
- package/dist/alerts/discord.js +95 -0
- package/dist/alerts/discord.js.map +1 -0
- package/dist/alerts/index.d.ts +5 -0
- package/dist/alerts/index.d.ts.map +1 -0
- package/dist/alerts/index.js +8 -0
- package/dist/alerts/index.js.map +1 -0
- package/dist/alerts/telegram.d.ts +25 -0
- package/dist/alerts/telegram.d.ts.map +1 -0
- package/dist/alerts/telegram.js +72 -0
- package/dist/alerts/telegram.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +410 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/connectors/index.d.ts +8 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +14 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/parsers.d.ts +24 -0
- package/dist/connectors/parsers.d.ts.map +1 -0
- package/dist/connectors/parsers.js +64 -0
- package/dist/connectors/parsers.js.map +1 -0
- package/dist/connectors/pterodactyl.d.ts +90 -0
- package/dist/connectors/pterodactyl.d.ts.map +1 -0
- package/dist/connectors/pterodactyl.js +221 -0
- package/dist/connectors/pterodactyl.js.map +1 -0
- package/dist/connectors/rcon.d.ts +51 -0
- package/dist/connectors/rcon.d.ts.map +1 -0
- package/dist/connectors/rcon.js +95 -0
- package/dist/connectors/rcon.js.map +1 -0
- package/dist/connectors/ssh.d.ts +65 -0
- package/dist/connectors/ssh.d.ts.map +1 -0
- package/dist/connectors/ssh.js +273 -0
- package/dist/connectors/ssh.js.map +1 -0
- package/dist/craft-close-skill.d.ts +106 -0
- package/dist/craft-close-skill.d.ts.map +1 -0
- package/dist/craft-close-skill.js +604 -0
- package/dist/craft-close-skill.js.map +1 -0
- package/dist/history.d.ts +32 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +194 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/openclaw-entry.d.ts +29 -0
- package/dist/openclaw-entry.d.ts.map +1 -0
- package/dist/openclaw-entry.js +45 -0
- package/dist/openclaw-entry.js.map +1 -0
- package/dist/patterns/index.d.ts +32 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +248 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/security/action-allowlist.d.ts +21 -0
- package/dist/security/action-allowlist.d.ts.map +1 -0
- package/dist/security/action-allowlist.js +54 -0
- package/dist/security/action-allowlist.js.map +1 -0
- package/dist/security/audit-log.d.ts +22 -0
- package/dist/security/audit-log.d.ts.map +1 -0
- package/dist/security/audit-log.js +49 -0
- package/dist/security/audit-log.js.map +1 -0
- package/dist/security/index.d.ts +10 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +20 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/input-sanitizer.d.ts +32 -0
- package/dist/security/input-sanitizer.d.ts.map +1 -0
- package/dist/security/input-sanitizer.js +81 -0
- package/dist/security/input-sanitizer.js.map +1 -0
- package/dist/security/path-jail.d.ts +25 -0
- package/dist/security/path-jail.d.ts.map +1 -0
- package/dist/security/path-jail.js +73 -0
- package/dist/security/path-jail.js.map +1 -0
- package/dist/security/rcon-filter.d.ts +24 -0
- package/dist/security/rcon-filter.d.ts.map +1 -0
- package/dist/security/rcon-filter.js +76 -0
- package/dist/security/rcon-filter.js.map +1 -0
- package/dist/types.d.ts +154 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
package/dist/history.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* History Tracker — Store TPS and player count history in SQLite.
|
|
4
|
+
*
|
|
5
|
+
* Uses better-sqlite3 with graceful fallback — if the native module
|
|
6
|
+
* fails to load, history tracking is disabled but monitoring continues.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.HistoryTracker = void 0;
|
|
10
|
+
class HistoryTracker {
|
|
11
|
+
db = null;
|
|
12
|
+
constructor(dbPath) {
|
|
13
|
+
try {
|
|
14
|
+
// Dynamic require to handle native build failures gracefully
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
16
|
+
const Sqlite3 = require("better-sqlite3");
|
|
17
|
+
this.db = new Sqlite3(dbPath);
|
|
18
|
+
this.initialize();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const msg = err instanceof Error ? err.message : "unknown error";
|
|
22
|
+
console.warn(`[CraftClose] SQLite unavailable (${msg}). History tracking disabled.`);
|
|
23
|
+
this.db = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
initialize() {
|
|
27
|
+
if (!this.db)
|
|
28
|
+
return;
|
|
29
|
+
this.db.exec(`
|
|
30
|
+
CREATE TABLE IF NOT EXISTS health_history (
|
|
31
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
32
|
+
server TEXT NOT NULL,
|
|
33
|
+
timestamp TEXT NOT NULL,
|
|
34
|
+
online INTEGER NOT NULL,
|
|
35
|
+
cpu REAL,
|
|
36
|
+
ram_used INTEGER,
|
|
37
|
+
ram_total INTEGER,
|
|
38
|
+
disk_used INTEGER,
|
|
39
|
+
disk_total INTEGER,
|
|
40
|
+
tps REAL,
|
|
41
|
+
players_online INTEGER,
|
|
42
|
+
players_max INTEGER,
|
|
43
|
+
uptime TEXT,
|
|
44
|
+
version TEXT
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS crash_events (
|
|
48
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
49
|
+
server TEXT NOT NULL,
|
|
50
|
+
timestamp TEXT NOT NULL,
|
|
51
|
+
type TEXT NOT NULL,
|
|
52
|
+
severity TEXT NOT NULL,
|
|
53
|
+
pattern_id TEXT,
|
|
54
|
+
pattern_title TEXT,
|
|
55
|
+
pattern_cause TEXT,
|
|
56
|
+
pattern_fix TEXT,
|
|
57
|
+
raw_log TEXT,
|
|
58
|
+
ai_analysis TEXT
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_health_server_time ON health_history(server, timestamp);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_crash_server_time ON crash_events(server, timestamp);
|
|
63
|
+
`);
|
|
64
|
+
// Schema migration: add ai_analysis column if missing (upgrade from pre-Phase 4)
|
|
65
|
+
this.migrate();
|
|
66
|
+
}
|
|
67
|
+
migrate() {
|
|
68
|
+
if (!this.db)
|
|
69
|
+
return;
|
|
70
|
+
const columns = this.db.pragma("table_info(crash_events)");
|
|
71
|
+
const hasAiAnalysis = columns.some(c => c.name === "ai_analysis");
|
|
72
|
+
if (!hasAiAnalysis) {
|
|
73
|
+
this.db.exec("ALTER TABLE crash_events ADD COLUMN ai_analysis TEXT");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Whether the database is available for tracking */
|
|
77
|
+
get available() {
|
|
78
|
+
return this.db !== null;
|
|
79
|
+
}
|
|
80
|
+
/** Record a health check result */
|
|
81
|
+
record(result) {
|
|
82
|
+
if (!this.db)
|
|
83
|
+
return;
|
|
84
|
+
const stmt = this.db.prepare(`
|
|
85
|
+
INSERT INTO health_history (server, timestamp, online, cpu, ram_used, ram_total, disk_used, disk_total, tps, players_online, players_max, uptime, version)
|
|
86
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
87
|
+
`);
|
|
88
|
+
stmt.run(result.server, result.timestamp.toISOString(), result.online ? 1 : 0, result.cpu ?? null, result.ram?.used ?? null, result.ram?.total ?? null, result.disk?.used ?? null, result.disk?.total ?? null, result.tps ?? null, result.players?.online ?? null, result.players?.max ?? null, result.uptime ?? null, result.version ?? null);
|
|
89
|
+
}
|
|
90
|
+
/** Record a crash event */
|
|
91
|
+
recordCrash(event) {
|
|
92
|
+
if (!this.db)
|
|
93
|
+
return;
|
|
94
|
+
const stmt = this.db.prepare(`
|
|
95
|
+
INSERT INTO crash_events (server, timestamp, type, severity, pattern_id, pattern_title, pattern_cause, pattern_fix, raw_log, ai_analysis)
|
|
96
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
97
|
+
`);
|
|
98
|
+
stmt.run(event.server, event.timestamp.toISOString(), event.type, event.severity, event.pattern_match?.pattern_id ?? null, event.pattern_match?.title ?? null, event.pattern_match?.cause ?? null, event.pattern_match?.fix ?? null, event.raw_log ?? null, event.ai_analysis ? JSON.stringify(event.ai_analysis) : null);
|
|
99
|
+
}
|
|
100
|
+
/** Get recent health history for a server */
|
|
101
|
+
getHistory(server, limit = 60) {
|
|
102
|
+
if (!this.db)
|
|
103
|
+
return [];
|
|
104
|
+
const rows = this.db.prepare("SELECT * FROM health_history WHERE server = ? ORDER BY timestamp DESC LIMIT ?").all(server, limit);
|
|
105
|
+
return rows.map(row => this.mapRowToResult(row));
|
|
106
|
+
}
|
|
107
|
+
mapRowToResult(row) {
|
|
108
|
+
const result = {
|
|
109
|
+
server: row.server,
|
|
110
|
+
timestamp: new Date(row.timestamp),
|
|
111
|
+
online: row.online === 1,
|
|
112
|
+
};
|
|
113
|
+
if (row.cpu !== null && row.cpu !== undefined)
|
|
114
|
+
result.cpu = Number(row.cpu);
|
|
115
|
+
if (row.ram_used !== null && row.ram_used !== undefined) {
|
|
116
|
+
result.ram = { used: Number(row.ram_used), total: Number(row.ram_total), percent: Number(row.ram_used) / Number(row.ram_total) * 100 };
|
|
117
|
+
}
|
|
118
|
+
if (row.disk_used !== null && row.disk_used !== undefined) {
|
|
119
|
+
result.disk = { used: Number(row.disk_used), total: Number(row.disk_total), percent: Number(row.disk_used) / Number(row.disk_total) * 100 };
|
|
120
|
+
}
|
|
121
|
+
if (row.tps !== null && row.tps !== undefined)
|
|
122
|
+
result.tps = Number(row.tps);
|
|
123
|
+
if (row.players_online !== null && row.players_online !== undefined) {
|
|
124
|
+
result.players = { online: Number(row.players_online), max: Number(row.players_max ?? 0) };
|
|
125
|
+
}
|
|
126
|
+
if (row.uptime)
|
|
127
|
+
result.uptime = row.uptime;
|
|
128
|
+
if (row.version)
|
|
129
|
+
result.version = row.version;
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
/** Get crash history for a server (or all servers) */
|
|
133
|
+
getCrashes(server, limit = 50) {
|
|
134
|
+
if (!this.db)
|
|
135
|
+
return [];
|
|
136
|
+
const query = server
|
|
137
|
+
? "SELECT * FROM crash_events WHERE server = ? ORDER BY timestamp DESC LIMIT ?"
|
|
138
|
+
: "SELECT * FROM crash_events ORDER BY timestamp DESC LIMIT ?";
|
|
139
|
+
const params = server ? [server, limit] : [limit];
|
|
140
|
+
const rows = this.db.prepare(query).all(...params);
|
|
141
|
+
return rows.map(row => this.mapRowToCrash(row));
|
|
142
|
+
}
|
|
143
|
+
mapRowToCrash(row) {
|
|
144
|
+
const event = {
|
|
145
|
+
server: row.server,
|
|
146
|
+
timestamp: new Date(row.timestamp),
|
|
147
|
+
type: row.type,
|
|
148
|
+
severity: row.severity,
|
|
149
|
+
};
|
|
150
|
+
if (row.raw_log)
|
|
151
|
+
event.raw_log = row.raw_log;
|
|
152
|
+
if (row.pattern_id) {
|
|
153
|
+
event.pattern_match = {
|
|
154
|
+
pattern_id: row.pattern_id,
|
|
155
|
+
category: "",
|
|
156
|
+
title: row.pattern_title ?? "",
|
|
157
|
+
cause: row.pattern_cause ?? "",
|
|
158
|
+
fix: row.pattern_fix ?? "",
|
|
159
|
+
confidence: 0,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (row.ai_analysis) {
|
|
163
|
+
try {
|
|
164
|
+
event.ai_analysis = JSON.parse(row.ai_analysis);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Ignore malformed JSON
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return event;
|
|
171
|
+
}
|
|
172
|
+
/** Get average TPS over last N checks */
|
|
173
|
+
getAverageTps(server, checks = 10) {
|
|
174
|
+
if (!this.db)
|
|
175
|
+
return null;
|
|
176
|
+
const row = this.db.prepare("SELECT AVG(tps) as avg_tps FROM (SELECT tps FROM health_history WHERE server = ? AND tps IS NOT NULL ORDER BY timestamp DESC LIMIT ?)").get(server, checks);
|
|
177
|
+
return row?.avg_tps ?? null;
|
|
178
|
+
}
|
|
179
|
+
/** Prune old records (keep last N days) */
|
|
180
|
+
prune(days = 7) {
|
|
181
|
+
if (!this.db)
|
|
182
|
+
return;
|
|
183
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
184
|
+
this.db.prepare("DELETE FROM health_history WHERE timestamp < ?").run(cutoff);
|
|
185
|
+
this.db.prepare("DELETE FROM crash_events WHERE timestamp < ?").run(cutoff);
|
|
186
|
+
}
|
|
187
|
+
/** Close the database connection */
|
|
188
|
+
close() {
|
|
189
|
+
this.db?.close();
|
|
190
|
+
this.db = null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.HistoryTracker = HistoryTracker;
|
|
194
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CraftClose — AI-powered Minecraft server monitoring
|
|
3
|
+
*
|
|
4
|
+
* OpenClaw skill entry point.
|
|
5
|
+
* Handles server monitoring, crash detection, auto-restart, and AI-powered analysis.
|
|
6
|
+
*/
|
|
7
|
+
export { CraftCloseSkill } from "./craft-close-skill.js";
|
|
8
|
+
export { loadConfig } from "./config.js";
|
|
9
|
+
export { HistoryTracker } from "./history.js";
|
|
10
|
+
export { AIAnalyzer } from "./ai-analyzer.js";
|
|
11
|
+
export { activate, deactivate, getActiveSkill } from "./openclaw-entry.js";
|
|
12
|
+
export type { CraftCloseConfig, ServerConfig, AlertConfig, AiConfig, AiAnalysis, SecurityConfig } from "./types.js";
|
|
13
|
+
export type { CraftCloseSkillContext } from "./openclaw-entry.js";
|
|
14
|
+
export type { AIAnalyzerOptions } from "./ai-analyzer.js";
|
|
15
|
+
export { PathJail, RconFilter, InputSanitizer, AuditLog, ActionAllowlist } from "./security/index.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3E,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACpH,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CraftClose — AI-powered Minecraft server monitoring
|
|
4
|
+
*
|
|
5
|
+
* OpenClaw skill entry point.
|
|
6
|
+
* Handles server monitoring, crash detection, auto-restart, and AI-powered analysis.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ActionAllowlist = exports.AuditLog = exports.InputSanitizer = exports.RconFilter = exports.PathJail = exports.getActiveSkill = exports.deactivate = exports.activate = exports.AIAnalyzer = exports.HistoryTracker = exports.loadConfig = exports.CraftCloseSkill = void 0;
|
|
10
|
+
var craft_close_skill_js_1 = require("./craft-close-skill.js");
|
|
11
|
+
Object.defineProperty(exports, "CraftCloseSkill", { enumerable: true, get: function () { return craft_close_skill_js_1.CraftCloseSkill; } });
|
|
12
|
+
var config_js_1 = require("./config.js");
|
|
13
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_js_1.loadConfig; } });
|
|
14
|
+
var history_js_1 = require("./history.js");
|
|
15
|
+
Object.defineProperty(exports, "HistoryTracker", { enumerable: true, get: function () { return history_js_1.HistoryTracker; } });
|
|
16
|
+
var ai_analyzer_js_1 = require("./ai-analyzer.js");
|
|
17
|
+
Object.defineProperty(exports, "AIAnalyzer", { enumerable: true, get: function () { return ai_analyzer_js_1.AIAnalyzer; } });
|
|
18
|
+
var openclaw_entry_js_1 = require("./openclaw-entry.js");
|
|
19
|
+
Object.defineProperty(exports, "activate", { enumerable: true, get: function () { return openclaw_entry_js_1.activate; } });
|
|
20
|
+
Object.defineProperty(exports, "deactivate", { enumerable: true, get: function () { return openclaw_entry_js_1.deactivate; } });
|
|
21
|
+
Object.defineProperty(exports, "getActiveSkill", { enumerable: true, get: function () { return openclaw_entry_js_1.getActiveSkill; } });
|
|
22
|
+
var index_js_1 = require("./security/index.js");
|
|
23
|
+
Object.defineProperty(exports, "PathJail", { enumerable: true, get: function () { return index_js_1.PathJail; } });
|
|
24
|
+
Object.defineProperty(exports, "RconFilter", { enumerable: true, get: function () { return index_js_1.RconFilter; } });
|
|
25
|
+
Object.defineProperty(exports, "InputSanitizer", { enumerable: true, get: function () { return index_js_1.InputSanitizer; } });
|
|
26
|
+
Object.defineProperty(exports, "AuditLog", { enumerable: true, get: function () { return index_js_1.AuditLog; } });
|
|
27
|
+
Object.defineProperty(exports, "ActionAllowlist", { enumerable: true, get: function () { return index_js_1.ActionAllowlist; } });
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,+DAAyD;AAAhD,uHAAA,eAAe,OAAA;AACxB,yCAAyC;AAAhC,uGAAA,UAAU,OAAA;AACnB,2CAA8C;AAArC,4GAAA,cAAc,OAAA;AACvB,mDAA8C;AAArC,4GAAA,UAAU,OAAA;AACnB,yDAA2E;AAAlE,6GAAA,QAAQ,OAAA;AAAE,+GAAA,UAAU,OAAA;AAAE,mHAAA,cAAc,OAAA;AAI7C,gDAAsG;AAA7F,oGAAA,QAAQ,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAAE,2GAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CraftClose — OpenClaw Skill Entry Point
|
|
3
|
+
*
|
|
4
|
+
* When installed as an OpenClaw skill, CraftClose monitors servers
|
|
5
|
+
* in the background and uses OpenClaw's messaging tools for alerts.
|
|
6
|
+
*/
|
|
7
|
+
import { CraftCloseSkill } from "./craft-close-skill.js";
|
|
8
|
+
import type { CraftCloseConfig } from "./types.js";
|
|
9
|
+
export interface CraftCloseSkillContext {
|
|
10
|
+
/** Path to craftclose.yml config */
|
|
11
|
+
configPath?: string;
|
|
12
|
+
/** Override config directly (for programmatic use) */
|
|
13
|
+
config?: CraftCloseConfig;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Start CraftClose monitoring.
|
|
17
|
+
* Called by OpenClaw when the skill is activated.
|
|
18
|
+
*/
|
|
19
|
+
export declare function activate(context?: CraftCloseSkillContext): Promise<CraftCloseSkill>;
|
|
20
|
+
/**
|
|
21
|
+
* Stop CraftClose monitoring.
|
|
22
|
+
* Called by OpenClaw when the skill is deactivated.
|
|
23
|
+
*/
|
|
24
|
+
export declare function deactivate(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get the active skill instance (for ad-hoc status checks).
|
|
27
|
+
*/
|
|
28
|
+
export declare function getActiveSkill(): CraftCloseSkill | null;
|
|
29
|
+
//# sourceMappingURL=openclaw-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAID;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC,CAU7F;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,eAAe,GAAG,IAAI,CAEvD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CraftClose — OpenClaw Skill Entry Point
|
|
4
|
+
*
|
|
5
|
+
* When installed as an OpenClaw skill, CraftClose monitors servers
|
|
6
|
+
* in the background and uses OpenClaw's messaging tools for alerts.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.activate = activate;
|
|
10
|
+
exports.deactivate = deactivate;
|
|
11
|
+
exports.getActiveSkill = getActiveSkill;
|
|
12
|
+
const craft_close_skill_js_1 = require("./craft-close-skill.js");
|
|
13
|
+
const config_js_1 = require("./config.js");
|
|
14
|
+
let activeSkill = null;
|
|
15
|
+
/**
|
|
16
|
+
* Start CraftClose monitoring.
|
|
17
|
+
* Called by OpenClaw when the skill is activated.
|
|
18
|
+
*/
|
|
19
|
+
async function activate(context = {}) {
|
|
20
|
+
if (activeSkill) {
|
|
21
|
+
console.log("[CraftClose] Already running. Stop first.");
|
|
22
|
+
return activeSkill;
|
|
23
|
+
}
|
|
24
|
+
const config = context.config ?? (0, config_js_1.loadConfig)(context.configPath);
|
|
25
|
+
activeSkill = new craft_close_skill_js_1.CraftCloseSkill(config);
|
|
26
|
+
await activeSkill.start();
|
|
27
|
+
return activeSkill;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Stop CraftClose monitoring.
|
|
31
|
+
* Called by OpenClaw when the skill is deactivated.
|
|
32
|
+
*/
|
|
33
|
+
function deactivate() {
|
|
34
|
+
if (activeSkill) {
|
|
35
|
+
activeSkill.stop();
|
|
36
|
+
activeSkill = null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the active skill instance (for ad-hoc status checks).
|
|
41
|
+
*/
|
|
42
|
+
function getActiveSkill() {
|
|
43
|
+
return activeSkill;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=openclaw-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-entry.js","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAmBH,4BAUC;AAMD,gCAKC;AAKD,wCAEC;AA7CD,iEAAyD;AACzD,2CAAyC;AAUzC,IAAI,WAAW,GAA2B,IAAI,CAAC;AAE/C;;;GAGG;AACI,KAAK,UAAU,QAAQ,CAAC,UAAkC,EAAE;IACjE,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAA,sBAAU,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE,WAAW,GAAG,IAAI,sCAAe,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;IAC1B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU;IACxB,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,EAAE,CAAC;QACnB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CraftClose — Crash Pattern Library
|
|
3
|
+
*
|
|
4
|
+
* Built-in patterns for instant, offline crash diagnosis.
|
|
5
|
+
* Each pattern is matched against server log output.
|
|
6
|
+
* Community contributions welcome — see CONTRIBUTING.md.
|
|
7
|
+
*/
|
|
8
|
+
export interface CrashPattern {
|
|
9
|
+
id: string;
|
|
10
|
+
category: "memory" | "plugin" | "network" | "world" | "java" | "performance" | "config" | "database";
|
|
11
|
+
severity: "critical" | "warning" | "info";
|
|
12
|
+
regex: RegExp;
|
|
13
|
+
title: string;
|
|
14
|
+
cause: string;
|
|
15
|
+
fix: string;
|
|
16
|
+
confidence: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Master pattern list.
|
|
20
|
+
* Ordered by frequency — most common patterns first for fast matching.
|
|
21
|
+
*/
|
|
22
|
+
export declare const CRASH_PATTERNS: CrashPattern[];
|
|
23
|
+
/**
|
|
24
|
+
* Match log text against the pattern library.
|
|
25
|
+
* Returns the best match (highest confidence) or null.
|
|
26
|
+
*/
|
|
27
|
+
export declare function matchPattern(logText: string): CrashPattern | null;
|
|
28
|
+
/**
|
|
29
|
+
* Match ALL patterns that apply to a log (for comprehensive analysis).
|
|
30
|
+
*/
|
|
31
|
+
export declare function matchAllPatterns(logText: string): CrashPattern[];
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;IACrG,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAwNxC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAYjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAEhE"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CraftClose — Crash Pattern Library
|
|
4
|
+
*
|
|
5
|
+
* Built-in patterns for instant, offline crash diagnosis.
|
|
6
|
+
* Each pattern is matched against server log output.
|
|
7
|
+
* Community contributions welcome — see CONTRIBUTING.md.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CRASH_PATTERNS = void 0;
|
|
11
|
+
exports.matchPattern = matchPattern;
|
|
12
|
+
exports.matchAllPatterns = matchAllPatterns;
|
|
13
|
+
/**
|
|
14
|
+
* Master pattern list.
|
|
15
|
+
* Ordered by frequency — most common patterns first for fast matching.
|
|
16
|
+
*/
|
|
17
|
+
exports.CRASH_PATTERNS = [
|
|
18
|
+
// ─── MEMORY ────────────────────────────────────────────
|
|
19
|
+
{
|
|
20
|
+
id: "oom-heap",
|
|
21
|
+
category: "memory",
|
|
22
|
+
severity: "critical",
|
|
23
|
+
regex: /java\.lang\.OutOfMemoryError:\s*Java heap space/i,
|
|
24
|
+
title: "Out of Memory — Heap Space",
|
|
25
|
+
cause: "Server ran out of allocated heap memory. Common causes: too many loaded chunks, large WorldEdit operations, entity accumulation, or memory leaks in plugins.",
|
|
26
|
+
fix: "Increase -Xmx in your startup script. Use Aikar's flags for optimal GC. Check for plugins with known memory leaks. Reduce view-distance or simulation-distance.",
|
|
27
|
+
confidence: 0.98,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "oom-metaspace",
|
|
31
|
+
category: "memory",
|
|
32
|
+
severity: "critical",
|
|
33
|
+
regex: /java\.lang\.OutOfMemoryError:\s*Metaspace/i,
|
|
34
|
+
title: "Out of Memory — Metaspace",
|
|
35
|
+
cause: "Java Metaspace exhausted. Usually caused by too many plugins loading too many classes, or plugins that dynamically generate classes (e.g., scripting engines, bytecode manipulation).",
|
|
36
|
+
fix: "Add -XX:MaxMetaspaceSize=512m to startup flags. Remove unused plugins. Check for Skript/script plugins loading excessive scripts.",
|
|
37
|
+
confidence: 0.95,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "oom-gc-overhead",
|
|
41
|
+
category: "memory",
|
|
42
|
+
severity: "critical",
|
|
43
|
+
regex: /java\.lang\.OutOfMemoryError:\s*GC overhead limit exceeded/i,
|
|
44
|
+
title: "Out of Memory — GC Overhead",
|
|
45
|
+
cause: "Garbage collector is spending >98% of time collecting and recovering <2% of heap. The server is essentially stuck trying to free memory.",
|
|
46
|
+
fix: "Increase heap size (-Xmx). Switch to Aikar's G1GC flags. Identify the memory hog: check timings report for plugins allocating excessive objects.",
|
|
47
|
+
confidence: 0.97,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "oom-worldedit",
|
|
51
|
+
category: "memory",
|
|
52
|
+
severity: "critical",
|
|
53
|
+
regex: /java\.lang\.OutOfMemoryError[\s\S]{0,500}(WorldEdit|worldedit|fawe|FastAsyncWorldEdit)/i,
|
|
54
|
+
title: "Out of Memory — WorldEdit/FAWE Operation",
|
|
55
|
+
cause: "A WorldEdit or FAWE operation tried to load too many blocks into memory at once. Large //paste, //fill, //replace, or //copy operations are the usual culprit.",
|
|
56
|
+
fix: "Use FAWE instead of WorldEdit for large operations. Set //limit to cap block changes. Increase RAM if operations are necessary. Split large operations into smaller chunks.",
|
|
57
|
+
confidence: 0.95,
|
|
58
|
+
},
|
|
59
|
+
// ─── PLUGIN ERRORS ─────────────────────────────────────
|
|
60
|
+
{
|
|
61
|
+
id: "plugin-class-not-found",
|
|
62
|
+
category: "plugin",
|
|
63
|
+
severity: "warning",
|
|
64
|
+
regex: /java\.lang\.ClassNotFoundException:\s*(\S+)/i,
|
|
65
|
+
title: "Plugin Class Not Found",
|
|
66
|
+
cause: "A plugin is trying to use a class that doesn't exist. Usually means a dependency plugin is missing or the wrong version is installed.",
|
|
67
|
+
fix: "Check which plugin threw the error (look at the stack trace). Install missing dependencies. Ensure all plugins are compatible with your server version.",
|
|
68
|
+
confidence: 0.90,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "plugin-no-such-method",
|
|
72
|
+
category: "plugin",
|
|
73
|
+
severity: "warning",
|
|
74
|
+
regex: /java\.lang\.NoSuchMethodError:\s*(\S+)/i,
|
|
75
|
+
title: "Plugin Method Not Found",
|
|
76
|
+
cause: "A plugin is calling a method that doesn't exist in the current API version. Typically means the plugin was compiled for a different server version.",
|
|
77
|
+
fix: "Update the plugin to a version compatible with your server. Check the plugin's SpigotMC/Modrinth page for version compatibility notes.",
|
|
78
|
+
confidence: 0.88,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: "plugin-event-handler-error",
|
|
82
|
+
category: "plugin",
|
|
83
|
+
severity: "warning",
|
|
84
|
+
regex: /Could not pass event (\w+) to (\S+)/i,
|
|
85
|
+
title: "Plugin Event Handler Error",
|
|
86
|
+
cause: "A plugin's event handler threw an exception. The plugin failed to process a game event (player join, block break, etc.).",
|
|
87
|
+
fix: "Check the full stack trace below the error to identify the plugin. Update the plugin, or report the bug to the plugin developer with the stack trace.",
|
|
88
|
+
confidence: 0.92,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "plugin-duplicate",
|
|
92
|
+
category: "plugin",
|
|
93
|
+
severity: "warning",
|
|
94
|
+
regex: /Ambiguous plugin name.*for files (.*) and (.*)/i,
|
|
95
|
+
title: "Duplicate Plugin",
|
|
96
|
+
cause: "Two copies of the same plugin (or plugins with the same name) exist in the plugins folder.",
|
|
97
|
+
fix: "Remove the duplicate .jar file from your plugins/ folder. Keep only the version you want.",
|
|
98
|
+
confidence: 0.95,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "plugin-yaml-missing",
|
|
102
|
+
category: "plugin",
|
|
103
|
+
severity: "warning",
|
|
104
|
+
regex: /Cannot find main class.*plugin\.yml/i,
|
|
105
|
+
title: "Plugin Missing plugin.yml",
|
|
106
|
+
cause: "A .jar file in the plugins folder is not a valid Bukkit/Paper plugin — it's missing the required plugin.yml descriptor.",
|
|
107
|
+
fix: "Remove the invalid .jar. It might be a library that was accidentally placed in plugins/ instead of the correct location.",
|
|
108
|
+
confidence: 0.93,
|
|
109
|
+
},
|
|
110
|
+
// ─── NETWORK ───────────────────────────────────────────
|
|
111
|
+
{
|
|
112
|
+
id: "port-conflict",
|
|
113
|
+
category: "network",
|
|
114
|
+
severity: "critical",
|
|
115
|
+
regex: /FAILED TO BIND TO PORT|Address already in use/i,
|
|
116
|
+
title: "Port Already in Use",
|
|
117
|
+
cause: "Another process is already using the port your server is trying to bind to. Another MC server instance, or a different application, is occupying the port.",
|
|
118
|
+
fix: "Check what's using the port: `netstat -tlnp | grep <port>` or `lsof -i :<port>`. Stop the conflicting process, or change your server port in server.properties.",
|
|
119
|
+
confidence: 0.98,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "ipv6-binding",
|
|
123
|
+
category: "network",
|
|
124
|
+
severity: "critical",
|
|
125
|
+
regex: /java\.net\.SocketException.*Protocol family unavailable/i,
|
|
126
|
+
title: "IPv6 Binding Failed",
|
|
127
|
+
cause: "Server is trying to bind to IPv6 but the host doesn't support it.",
|
|
128
|
+
fix: "Set server-ip= (empty) in server.properties to bind to all interfaces, or explicitly set to 0.0.0.0 for IPv4 only.",
|
|
129
|
+
confidence: 0.92,
|
|
130
|
+
},
|
|
131
|
+
// ─── WORLD/DATA ────────────────────────────────────────
|
|
132
|
+
{
|
|
133
|
+
id: "chunk-corruption",
|
|
134
|
+
category: "world",
|
|
135
|
+
severity: "critical",
|
|
136
|
+
regex: /ChunkLoadError|Failed to load chunk|region file.*corrupt/i,
|
|
137
|
+
title: "Chunk/Region File Corruption",
|
|
138
|
+
cause: "A region file is corrupted, usually from a hard crash during world save. The affected chunk cannot be loaded.",
|
|
139
|
+
fix: "Identify the corrupted region file from the error coordinates. Use a tool like MCASelector to delete or regenerate the affected chunks. Always keep backups.",
|
|
140
|
+
confidence: 0.90,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: "nbt-malformed",
|
|
144
|
+
category: "world",
|
|
145
|
+
severity: "critical",
|
|
146
|
+
regex: /NBT.*malformed|Corrupt.*NBT|CompressedStreamTools/i,
|
|
147
|
+
title: "Corrupted NBT Data",
|
|
148
|
+
cause: "Player data, entity data, or chunk NBT is corrupted. Usually from a crash during save or disk full conditions.",
|
|
149
|
+
fix: "Identify the corrupted file from the log (playerdata/, entities/, level.dat). Restore from backup or delete the file (player will lose inventory/position).",
|
|
150
|
+
confidence: 0.85,
|
|
151
|
+
},
|
|
152
|
+
// ─── JAVA ──────────────────────────────────────────────
|
|
153
|
+
{
|
|
154
|
+
id: "java-version-mismatch",
|
|
155
|
+
category: "java",
|
|
156
|
+
severity: "critical",
|
|
157
|
+
regex: /UnsupportedClassVersionError|class file version \d+\.\d+/i,
|
|
158
|
+
title: "Java Version Mismatch",
|
|
159
|
+
cause: "A plugin or the server itself was compiled for a newer Java version than what's currently running.",
|
|
160
|
+
fix: "Check your Java version: `java -version`. Paper 1.20.5+ requires Java 21. Update Java to the version required by your server.",
|
|
161
|
+
confidence: 0.97,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: "stackoverflow",
|
|
165
|
+
category: "java",
|
|
166
|
+
severity: "critical",
|
|
167
|
+
regex: /java\.lang\.StackOverflowError/i,
|
|
168
|
+
title: "Stack Overflow",
|
|
169
|
+
cause: "Infinite recursion detected — a method is calling itself endlessly. Usually a plugin bug: recursive event listeners, circular dependencies, or infinite command chains.",
|
|
170
|
+
fix: "Check the stack trace for the repeating method pattern. The plugin whose methods repeat is the culprit. Report to the plugin developer or disable the plugin.",
|
|
171
|
+
confidence: 0.93,
|
|
172
|
+
},
|
|
173
|
+
// ─── PERFORMANCE ───────────────────────────────────────
|
|
174
|
+
{
|
|
175
|
+
id: "watchdog-timeout",
|
|
176
|
+
category: "performance",
|
|
177
|
+
severity: "critical",
|
|
178
|
+
regex: /-----\s*Watchdog.*-----/i,
|
|
179
|
+
title: "Server Watchdog — Thread Crash",
|
|
180
|
+
cause: "The main server thread was unresponsive for too long (default: 60s). Something blocked the main thread — a slow plugin, disk I/O, or massive world operation.",
|
|
181
|
+
fix: "Check the thread dump below the watchdog message. Look for plugins in the stack trace. Increase max-tick-time in spigot.yml (or set to -1 to disable watchdog, not recommended).",
|
|
182
|
+
confidence: 0.95,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "entity-overload",
|
|
186
|
+
category: "performance",
|
|
187
|
+
severity: "warning",
|
|
188
|
+
regex: /Too many entities.*loaded|entity.*tick.*took.*\d{4,}ms/i,
|
|
189
|
+
title: "Entity Overload",
|
|
190
|
+
cause: "Too many entities in loaded chunks are causing severe lag. Common sources: mob farms, item drops, minecarts, armor stands.",
|
|
191
|
+
fix: "Use `/kill @e[type=!player]` to clear entities. Set entity limits in bukkit.yml or paper-global.yml. Use a plugin like ClearLag for automatic cleanup.",
|
|
192
|
+
confidence: 0.85,
|
|
193
|
+
},
|
|
194
|
+
// ─── CONFIG ────────────────────────────────────────────
|
|
195
|
+
{
|
|
196
|
+
id: "yaml-parse-error",
|
|
197
|
+
category: "config",
|
|
198
|
+
severity: "warning",
|
|
199
|
+
regex: /YAMLException|could not determine.*value|found character.*that cannot/i,
|
|
200
|
+
title: "YAML Configuration Error",
|
|
201
|
+
cause: "A configuration file has invalid YAML syntax. Common causes: tabs instead of spaces, missing quotes around special characters, incorrect indentation.",
|
|
202
|
+
fix: "Check the file mentioned in the error. Use a YAML validator (yamllint.com). Common fixes: replace tabs with spaces, quote strings containing special chars (: { } [ ] , & * # ? | - < > = ! % @).",
|
|
203
|
+
confidence: 0.93,
|
|
204
|
+
},
|
|
205
|
+
// ─── DATABASE ──────────────────────────────────────────
|
|
206
|
+
{
|
|
207
|
+
id: "mysql-connection-refused",
|
|
208
|
+
category: "database",
|
|
209
|
+
severity: "critical",
|
|
210
|
+
regex: /Communications link failure|Connection refused.*3306|Access denied for user/i,
|
|
211
|
+
title: "MySQL Connection Failed",
|
|
212
|
+
cause: "Server can't connect to MySQL database. Either MySQL is down, credentials are wrong, or the host/port is incorrect.",
|
|
213
|
+
fix: "Check MySQL is running: `systemctl status mysql`. Verify credentials in the plugin config. Ensure the MySQL user has proper permissions and the host is allowed to connect.",
|
|
214
|
+
confidence: 0.90,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
id: "sqlite-locked",
|
|
218
|
+
category: "database",
|
|
219
|
+
severity: "warning",
|
|
220
|
+
regex: /database is locked|SQLITE_BUSY/i,
|
|
221
|
+
title: "SQLite Database Locked",
|
|
222
|
+
cause: "Multiple plugins or threads are trying to write to the same SQLite file simultaneously. SQLite doesn't handle concurrent writes well.",
|
|
223
|
+
fix: "Identify which plugins share the database file. Consider switching those plugins to MySQL for better concurrency. Or configure WAL mode if the plugin supports it.",
|
|
224
|
+
confidence: 0.88,
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
/**
|
|
228
|
+
* Match log text against the pattern library.
|
|
229
|
+
* Returns the best match (highest confidence) or null.
|
|
230
|
+
*/
|
|
231
|
+
function matchPattern(logText) {
|
|
232
|
+
let bestMatch = null;
|
|
233
|
+
let bestConfidence = 0;
|
|
234
|
+
for (const pattern of exports.CRASH_PATTERNS) {
|
|
235
|
+
if (pattern.regex.test(logText) && pattern.confidence > bestConfidence) {
|
|
236
|
+
bestMatch = pattern;
|
|
237
|
+
bestConfidence = pattern.confidence;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return bestMatch;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Match ALL patterns that apply to a log (for comprehensive analysis).
|
|
244
|
+
*/
|
|
245
|
+
function matchAllPatterns(logText) {
|
|
246
|
+
return exports.CRASH_PATTERNS.filter((pattern) => pattern.regex.test(logText));
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"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"}
|