v1.79.1

EvoMap/evolverv1.79.1May 6, 2026by autogame-17

AI Summary

Fixes Windows cmd-popup loop during daemon suicide-respawn by consolidating spawn sites.

Key Highlights

  • Consolidated in-process spawn sites to eliminate Windows cmd popups during suicide-respawn.
  • Daemon now exits on Windows instead of spawning a detached process.
  • Added `EVOLVER_SUICIDE_WINDOWS` environment variable to opt-in to the old behavior.

Full Release Notes

## What's fixed

### Windows cmd-popup loop on suicide-respawn (Issue #528)

On Windows, `child_process.spawn(detached: true, windowsHide: true)` opens a fresh conhost (cmd) window every time -- `windowsHide` is silently ignored in detached mode (this is a long-standing Node.js limitation, [documented in the child_process docs](https://nodejs.org/api/child_process.html#optionsdetached)).

So whenever the daemon hit `EVOLVER_MAX_CYCLES` (default 100) or `EVOLVER_MAX_RSS_MB` (default 500) and ran the in-process suicide-respawn, Windows users saw a new cmd popup. v1.79.0 made this worse by adding a third spawn site for the cycle hard-timeout, copying the same buggy options.

The two in-process spawn sites are now consolidated into one helper `spawnReplacementProcess()` that, on Windows, defaults to **not** spawning. Instead the daemon `process.exit(1)`s and an external supervisor restarts it. No popup. macOS/Linux behavior is unchanged.

### Recommended Windows supervisors

- **`feishu-evolver-wrapper` >= 1.10.0** (recommended; auto-restart with backoff + already detects inner stuck cycles since v1.79.0)
- NSSM (Non-Sucking Service Manager)
- pm2-windows-startup
- Windows Task Scheduler with "On failure: restart"

### Escape hatch

Users who explicitly want the in-process respawn (and accept the cmd popups) can opt back in:

```bash
EVOLVER_SUICIDE_WINDOWS=true
```

This is only honored on Windows; it is a no-op everywhere else.

### A note on the original report

The reporter's auto-generated diagnosis attributed a separate symptom -- "`evolver buy/orders/publish` subcommands break the daemon" -- to lock contention on `evolver.pid`. That hypothesis is incorrect: subcommands do not call `acquireLock()`; only `--loop` does. What the reporter observed was the same suicide-respawn cycle ending exactly when a subcommand happened to run, and the new conhost popup made it look like the subcommand caused it. Fixing the popup also fixes the perceived "daemon got killed" symptom.

## Install

### npm

```bash
npm install -g @evomap/evolver@1.79.1
```

### Standalone binary (no Node required)

| Platform | Asset |
|---|---|
| macOS (Apple Silicon) | `evolver-darwin-arm64` |
| macOS (Intel) | `evolver-darwin-x64` |
| Linux (x86_64) | `evolver-linux-x64` |
| Linux (ARM64) | `evolver-linux-arm64` |
| Windows (x86_64) | `evolver-windows-x64.exe` |

Verify (Linux/macOS):

```bash
sha256sum -c SHA256SUMS.txt --ignore-missing
chmod +x evolver-linux-x64
./evolver-linux-x64 --help
```

## Tests

- `test/spawnReplacementProcess.test.js` (10 cases covering Windows default, Windows with EVOLVER_SUICIDE_WINDOWS=true, non-Windows, and source-level guards)
- Full suite: 1178 / 1178 passing.

Closes EvoMap/evolver#528.