wolverine-ai 2.4.1 → 2.4.3
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/package.json +1 -1
- package/src/core/config.js +45 -0
- package/src/core/runner.js +7 -4
- package/src/platform/auto-update.js +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.3",
|
|
4
4
|
"description": "Self-healing Node.js server framework powered by AI. Catches crashes, diagnoses errors, generates fixes, verifies, and restarts — automatically.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/core/config.js
CHANGED
|
@@ -76,8 +76,22 @@ function loadConfig() {
|
|
|
76
76
|
dashboard: {
|
|
77
77
|
port: parseInt(process.env.WOLVERINE_DASHBOARD_PORT, 10) || fileConfig.dashboard?.port || null,
|
|
78
78
|
},
|
|
79
|
+
|
|
80
|
+
autoUpdate: {
|
|
81
|
+
enabled: process.env.WOLVERINE_AUTO_UPDATE !== "false" && (fileConfig.autoUpdate?.enabled !== false),
|
|
82
|
+
intervalMs: parseInt(process.env.WOLVERINE_UPDATE_INTERVAL_MS, 10) || fileConfig.autoUpdate?.intervalMs || 3600000,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
errorMonitor: {
|
|
86
|
+
threshold: parseInt(process.env.WOLVERINE_ERROR_THRESHOLD, 10) || fileConfig.errorMonitor?.defaultThreshold || 1,
|
|
87
|
+
windowMs: parseInt(process.env.WOLVERINE_ERROR_WINDOW_MS, 10) || fileConfig.errorMonitor?.windowMs || 30000,
|
|
88
|
+
cooldownMs: parseInt(process.env.WOLVERINE_ERROR_COOLDOWN_MS, 10) || fileConfig.errorMonitor?.cooldownMs || 60000,
|
|
89
|
+
},
|
|
79
90
|
};
|
|
80
91
|
|
|
92
|
+
// Merge any missing defaults into the live settings.json
|
|
93
|
+
_ensureDefaults(fileConfig, configPath);
|
|
94
|
+
|
|
81
95
|
return _config;
|
|
82
96
|
}
|
|
83
97
|
|
|
@@ -94,4 +108,35 @@ function getConfig(dotPath) {
|
|
|
94
108
|
*/
|
|
95
109
|
function resetConfig() { _config = null; }
|
|
96
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Ensure the live settings.json has all required sections.
|
|
113
|
+
* If a section is missing, add it with defaults. Never overwrites existing values.
|
|
114
|
+
*/
|
|
115
|
+
function _ensureDefaults(fileConfig, configPath) {
|
|
116
|
+
const DEFAULTS = {
|
|
117
|
+
autoUpdate: { enabled: true, intervalMs: 3600000 },
|
|
118
|
+
errorMonitor: { defaultThreshold: 1, windowMs: 30000, cooldownMs: 60000 },
|
|
119
|
+
healthCheck: { intervalMs: 15000, timeoutMs: 5000, failThreshold: 3, startDelayMs: 10000 },
|
|
120
|
+
rateLimiting: { maxCallsPerWindow: 32, windowMs: 100000, minGapMs: 5000, maxTokensPerHour: 1000000 },
|
|
121
|
+
telemetry: { enabled: true, heartbeatIntervalMs: 60000 },
|
|
122
|
+
cluster: { enabled: false, workers: 0 },
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
let needsWrite = false;
|
|
126
|
+
for (const [key, defaults] of Object.entries(DEFAULTS)) {
|
|
127
|
+
if (!fileConfig[key]) {
|
|
128
|
+
fileConfig[key] = defaults;
|
|
129
|
+
needsWrite = true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (needsWrite && configPath) {
|
|
134
|
+
try {
|
|
135
|
+
const tmpPath = configPath + ".tmp";
|
|
136
|
+
fs.writeFileSync(tmpPath, JSON.stringify(fileConfig, null, 2), "utf-8");
|
|
137
|
+
fs.renameSync(tmpPath, configPath);
|
|
138
|
+
} catch { /* non-fatal — config still works from defaults in memory */ }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
97
142
|
module.exports = { loadConfig, getConfig, resetConfig };
|
package/src/core/runner.js
CHANGED
|
@@ -20,6 +20,7 @@ const { ProcessMonitor } = require("../monitor/process-monitor");
|
|
|
20
20
|
const { RouteProber } = require("../monitor/route-prober");
|
|
21
21
|
const { startHeartbeat, stopHeartbeat } = require("../platform/heartbeat");
|
|
22
22
|
const { Notifier } = require("../notifications/notifier");
|
|
23
|
+
const { loadConfig } = require("./config");
|
|
23
24
|
const { ErrorMonitor } = require("../monitor/error-monitor");
|
|
24
25
|
const { startAutoUpdate, stopAutoUpdate } = require("../platform/auto-update");
|
|
25
26
|
|
|
@@ -215,20 +216,22 @@ class WolverineRunner {
|
|
|
215
216
|
});
|
|
216
217
|
|
|
217
218
|
// Auto-update: check for new wolverine-ai versions
|
|
218
|
-
const
|
|
219
|
-
const autoUpdateEnabled =
|
|
219
|
+
const autoUpdateCfg = loadConfig().autoUpdate || {};
|
|
220
|
+
const autoUpdateEnabled = process.env.WOLVERINE_AUTO_UPDATE !== "false" && autoUpdateCfg.enabled !== false;
|
|
220
221
|
if (autoUpdateEnabled) {
|
|
222
|
+
const { getCurrentVersion } = require("../platform/auto-update");
|
|
223
|
+
const updateInterval = autoUpdateCfg.intervalMs || 3600000;
|
|
221
224
|
startAutoUpdate({
|
|
222
225
|
cwd: this.cwd,
|
|
223
226
|
logger: this.logger,
|
|
224
|
-
intervalMs:
|
|
227
|
+
intervalMs: updateInterval,
|
|
225
228
|
onUpdate: (result) => {
|
|
226
229
|
console.log(chalk.blue(` 🔄 Wolverine updated ${result.from} → ${result.to}, restarting...`));
|
|
227
230
|
this.logger.info("update.restart", `Restarting after update ${result.from} → ${result.to}`);
|
|
228
231
|
this.restart();
|
|
229
232
|
},
|
|
230
233
|
});
|
|
231
|
-
console.log(chalk.gray(
|
|
234
|
+
console.log(chalk.gray(` 🔄 Auto-update: enabled (v${getCurrentVersion()}, checks every ${Math.round(updateInterval / 60000)}min)`));
|
|
232
235
|
} else {
|
|
233
236
|
console.log(chalk.gray(" 🔄 Auto-update: disabled"));
|
|
234
237
|
}
|
|
@@ -181,7 +181,9 @@ function startAutoUpdate({ cwd, logger, onUpdate, intervalMs }) {
|
|
|
181
181
|
const interval = intervalMs || CHECK_INTERVAL_MS;
|
|
182
182
|
|
|
183
183
|
// Check on startup (delayed 30s to not block boot)
|
|
184
|
+
console.log(chalk.gray(` 🔄 Auto-update scheduled: first check in 30s, then every ${Math.round(interval / 60000)}min`));
|
|
184
185
|
setTimeout(() => {
|
|
186
|
+
console.log(chalk.gray(` 🔄 Checking for updates (v${getCurrentVersion()})...`));
|
|
185
187
|
const result = checkForUpdate();
|
|
186
188
|
if (result?.available) {
|
|
187
189
|
const upgraded = upgrade(cwd, logger);
|
|
@@ -189,6 +191,10 @@ function startAutoUpdate({ cwd, logger, onUpdate, intervalMs }) {
|
|
|
189
191
|
console.log(chalk.blue(" 🔄 Restarting with new version..."));
|
|
190
192
|
onUpdate(upgraded);
|
|
191
193
|
}
|
|
194
|
+
} else if (result) {
|
|
195
|
+
console.log(chalk.gray(` 🔄 Up to date (v${result.current}${result.latest ? ", npm: " + result.latest : ""})`));
|
|
196
|
+
} else {
|
|
197
|
+
console.log(chalk.yellow(" 🔄 Update check failed (npm unreachable?)"));
|
|
192
198
|
}
|
|
193
199
|
}, 30000);
|
|
194
200
|
|