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.
Files changed (2) hide show
  1. package/README.md +74 -27
  2. 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 consecutive 500s per route
189
- 3 failures in 30s → triggers heal pipeline (same as crash healing)
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 | 3 | `WOLVERINE_ERROR_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()` middleware blocks 15 injection pattern families on all endpoints |
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
- ## Auto-Clustering
359
+ ## Cluster Mode
358
360
 
359
- Wolverine detects your machine and forks the optimal number of workers:
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
- wolverine server/index.js # auto-detect: 20 cores → 10 workers
363
- wolverine server/index.js --single # force single worker (dev mode)
364
- wolverine server/index.js --workers 4 # force 4 workers
365
- wolverine --info # show system capabilities
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 matches [PLATFORM.md](PLATFORM.md) spec: `instanceId`, `server`, `process`, `routes`, `repairs`, `usage` (tokens/cost/calls + `byCategory` + `byModel` + `byTool`), `brain`, `backups`
416
- - Platform analytics aggregates across all servers: total tokens/cost, breakdown by category (heal/chat/develop/security/classify/research/brain), by model, by tool
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
- See [PLATFORM.md](PLATFORM.md) for the backend spec and [TELEMETRY.md](TELEMETRY.md) for the protocol.
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, etc.)
482
- - **SafeDB** — Parameterized-only database wrapper (blocks string concatenation in queries)
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.0",
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": {