wolverine-ai 1.7.0 → 1.7.1
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 +74 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -185,17 +185,19 @@ Most production bugs don't crash the process — Fastify/Express catch them and
|
|
|
185
185
|
```
|
|
186
186
|
Route returns 500 (process still alive)
|
|
187
187
|
→ Error hook reports to parent via IPC (auto-injected, zero user code changes)
|
|
188
|
-
→ ErrorMonitor tracks
|
|
189
|
-
→
|
|
188
|
+
→ ErrorMonitor tracks errors per normalized route (/api/users/:id)
|
|
189
|
+
→ Single error triggers heal pipeline immediately (configurable threshold)
|
|
190
190
|
→ Fix applied → server restarted → route prober verifies fix
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
| Setting | Default | Env Variable |
|
|
194
194
|
|---------|---------|-------------|
|
|
195
|
-
| Failure threshold |
|
|
195
|
+
| Failure threshold | 1 | `WOLVERINE_ERROR_THRESHOLD` |
|
|
196
196
|
| Time window | 30s | `WOLVERINE_ERROR_WINDOW_MS` |
|
|
197
197
|
| Cooldown per route | 60s | `WOLVERINE_ERROR_COOLDOWN_MS` |
|
|
198
198
|
|
|
199
|
+
Routes are auto-normalized: `/api/users/123` and `/api/users/456` aggregate as `/api/users/:id`.
|
|
200
|
+
|
|
199
201
|
The error hook auto-patches Fastify and Express via `--require` preload. No middleware, no code changes to your server.
|
|
200
202
|
|
|
201
203
|
---
|
|
@@ -315,7 +317,7 @@ Reasoning models (`o-series`, `gpt-5-nano`) automatically get 4x token limits to
|
|
|
315
317
|
| **Admin Auth** | Dashboard requires key + IP allowlist. Localhost always allowed. Remote IPs via `WOLVERINE_ADMIN_IPS` env var or `POST /api/admin/add-ip` at runtime. Timing-safe comparison, lockout after 10 failures |
|
|
316
318
|
| **Rate Limiter** | Sliding window, min gap, hourly budget, exponential backoff on error loops |
|
|
317
319
|
| **MCP Security** | Per-server tool allowlists, arg sanitization, result injection scanning |
|
|
318
|
-
| **SQL Skill** | `sqlGuard()`
|
|
320
|
+
| **SQL Skill** | `sqlGuard()` blocks 15 injection pattern families; `idempotencyGuard()` prevents double-fire in cluster mode |
|
|
319
321
|
|
|
320
322
|
---
|
|
321
323
|
|
|
@@ -354,17 +356,35 @@ The `📊 Analytics` dashboard panel shows memory/CPU charts, route health statu
|
|
|
354
356
|
|
|
355
357
|
---
|
|
356
358
|
|
|
357
|
-
##
|
|
359
|
+
## Cluster Mode
|
|
358
360
|
|
|
359
|
-
|
|
361
|
+
The server handles its own clustering. Wolverine is the single process manager — it spawns your server, which forks workers internally.
|
|
360
362
|
|
|
361
363
|
```bash
|
|
362
|
-
|
|
363
|
-
wolverine server/index.js
|
|
364
|
-
|
|
365
|
-
|
|
364
|
+
# Enable cluster mode
|
|
365
|
+
WOLVERINE_CLUSTER=true wolverine server/index.js
|
|
366
|
+
|
|
367
|
+
# System info (cores, RAM, recommended workers)
|
|
368
|
+
wolverine --info
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**How it works:**
|
|
372
|
+
```
|
|
373
|
+
Wolverine (single process manager)
|
|
374
|
+
└── spawns server/index.js
|
|
375
|
+
├── WOLVERINE_CLUSTER=false → single server (default)
|
|
376
|
+
└── WOLVERINE_CLUSTER=true → master forks N workers
|
|
377
|
+
├── Worker 1 (port 3000, reusePort)
|
|
378
|
+
├── Worker 2 (port 3000, reusePort)
|
|
379
|
+
└── Worker N (port 3000, reusePort)
|
|
366
380
|
```
|
|
367
381
|
|
|
382
|
+
- **`WOLVERINE_RECOMMENDED_WORKERS`** auto-set based on CPU cores/RAM
|
|
383
|
+
- Workers share port 3000 via `reusePort` — OS handles load balancing
|
|
384
|
+
- Dead workers auto-respawn by the master process
|
|
385
|
+
- Wolverine kills the **entire process tree** on restart (no orphaned workers)
|
|
386
|
+
- **Idempotency protection** prevents double-fire across workers (see below)
|
|
387
|
+
|
|
368
388
|
**System detection:**
|
|
369
389
|
- CPU cores, model, speed
|
|
370
390
|
- Total/free RAM, disk space
|
|
@@ -372,18 +392,6 @@ wolverine --info # show system capabilities
|
|
|
372
392
|
- Container environment (Docker, Kubernetes)
|
|
373
393
|
- Cloud provider (AWS, GCP, Azure, Railway, Fly, Render, Heroku)
|
|
374
394
|
|
|
375
|
-
**Scaling rules:**
|
|
376
|
-
|
|
377
|
-
| Cores | Workers |
|
|
378
|
-
|-------|---------|
|
|
379
|
-
| 1 | 1 (no clustering) |
|
|
380
|
-
| 2 | 2 |
|
|
381
|
-
| 3-4 | cores - 1 |
|
|
382
|
-
| 5-8 | cores - 1, cap 6 |
|
|
383
|
-
| 9+ | cores / 2, cap 16 |
|
|
384
|
-
|
|
385
|
-
Workers auto-respawn on crash with exponential backoff (1s → 30s). Max 5 restarts per worker.
|
|
386
|
-
|
|
387
395
|
---
|
|
388
396
|
|
|
389
397
|
## Configuration
|
|
@@ -412,8 +420,8 @@ Startup:
|
|
|
412
420
|
- Auto-registers on first run, retries every 60s until platform responds
|
|
413
421
|
- Saves key to `.wolverine/platform-key` (survives restarts)
|
|
414
422
|
- Sends one ~2KB JSON POST every 60 seconds (5s timeout, non-blocking)
|
|
415
|
-
- Payload
|
|
416
|
-
- Platform
|
|
423
|
+
- Payload: `instanceId`, `server`, `process`, `routes`, `repairs`, `usage` (tokens/cost/calls + `byCategory` + `byModel` + `byTool`), `brain`, `backups`
|
|
424
|
+
- Platform aggregates across all servers: total tokens/cost by category, model, tool
|
|
417
425
|
- Secrets redacted before sending
|
|
418
426
|
- Offline-resilient: queues up to 1440 heartbeats locally, drains on reconnect
|
|
419
427
|
|
|
@@ -422,7 +430,7 @@ Startup:
|
|
|
422
430
|
**Override:** `WOLVERINE_PLATFORM_URL=https://your-own-platform.com`
|
|
423
431
|
**Opt out:** `WOLVERINE_TELEMETRY=false`
|
|
424
432
|
|
|
425
|
-
|
|
433
|
+
Telemetry payload includes: `instanceId`, `server`, `process`, `routes`, `repairs`, `usage` (by category/model/tool), `brain`, `backups`.
|
|
426
434
|
|
|
427
435
|
---
|
|
428
436
|
|
|
@@ -478,14 +486,53 @@ Full `server/` directory snapshots with lifecycle management:
|
|
|
478
486
|
Auto-discovered from `src/skills/`. Each skill exports metadata for the registry:
|
|
479
487
|
|
|
480
488
|
### SQL Skill (`src/skills/sql.js`)
|
|
481
|
-
- **sqlGuard()** — Express middleware blocking SQL injection (UNION, stacked queries, tautologies, timing attacks,
|
|
482
|
-
- **SafeDB** —
|
|
489
|
+
- **sqlGuard()** — Fastify/Express middleware blocking SQL injection (UNION, stacked queries, tautologies, timing attacks, 15 pattern families)
|
|
490
|
+
- **SafeDB** — Cluster-safe database with split read/write connections, FIFO write queue, WAL mode
|
|
491
|
+
- **idempotencyGuard()** — Prevents double-fire of write requests in cluster mode (see below)
|
|
492
|
+
- **db.idempotent(key, fn)** — Database-level dedup for critical writes (payments, orders)
|
|
483
493
|
- Auto-injected into agent prompts when building database features
|
|
484
494
|
|
|
485
495
|
Add new skills by creating a file in `src/skills/` with `SKILL_NAME`, `SKILL_DESCRIPTION`, `SKILL_KEYWORDS`, `SKILL_USAGE` exports.
|
|
486
496
|
|
|
487
497
|
---
|
|
488
498
|
|
|
499
|
+
## Idempotency (Double-Fire Protection)
|
|
500
|
+
|
|
501
|
+
In cluster mode, a retry or duplicate request can land on a different worker and execute twice. Two layers prevent this:
|
|
502
|
+
|
|
503
|
+
### Layer 1: HTTP Middleware
|
|
504
|
+
|
|
505
|
+
```javascript
|
|
506
|
+
const { idempotencyGuard, idempotencyAfterHook } = require("wolverine-ai");
|
|
507
|
+
|
|
508
|
+
fastify.addHook("preHandler", idempotencyGuard({ db, logger }));
|
|
509
|
+
fastify.addHook("onSend", idempotencyAfterHook(db));
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
- Client sends `X-Idempotency-Key: order-abc-123` header
|
|
513
|
+
- Without header: auto-generates key from `sha256(method + url + body)`
|
|
514
|
+
- First request: executes handler, caches response in shared SQLite table
|
|
515
|
+
- Duplicate: returns cached response with `X-Idempotency-Cached: true` header
|
|
516
|
+
- Safe methods (GET/HEAD/OPTIONS) always pass through
|
|
517
|
+
- Keys expire after 24h (configurable)
|
|
518
|
+
|
|
519
|
+
### Layer 2: Database-Level
|
|
520
|
+
|
|
521
|
+
```javascript
|
|
522
|
+
const result = await db.idempotent("charge-abc-123", (tx) => {
|
|
523
|
+
tx.run("INSERT INTO charges (id, amount) VALUES (?, ?)", ["abc-123", 99.99]);
|
|
524
|
+
tx.run("UPDATE balance SET amount = amount - ? WHERE user_id = ?", [99.99, 1]);
|
|
525
|
+
return { charged: true };
|
|
526
|
+
});
|
|
527
|
+
// result.executed = true (first time) or false (duplicate)
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
- Wraps `fn` in a transaction with idempotency key check
|
|
531
|
+
- All workers share the `_idempotency` table via WAL mode — globally consistent
|
|
532
|
+
- Auto-created on `db.connect()`, pruned via `db.pruneIdempotency()`
|
|
533
|
+
|
|
534
|
+
---
|
|
535
|
+
|
|
489
536
|
## MCP Integration
|
|
490
537
|
|
|
491
538
|
Connect external tools via [Model Context Protocol](https://modelcontextprotocol.io):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
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": {
|