Skip to content

Control plane CLI opens a persistent "next-server" console window on Windows #6076

Closed

Description

@hashtafak

Use Case

I run hindsight-api (v1.1.0) as a long-lived background service on Windows 10, managed by PM2, and use @vectorize-io/hindsight-control-plane (v1.1.0) for the web UI:

pm2 start C:\...\node_modules\@vectorize-io\hindsight-control-plane\bin\cli.js --name hindsight-ui -- --port 9999 --api-url http://localhost:8888

The goal is a fully headless setup — API + UI running quietly in the background, logs captured by the process manager.

Problem Statement

On Windows, the control plane CLI spawns the Next.js standalone server as a child process, and that child opens a visible console window titled next-server that stays open for as long as the UI runs. No window flashes at PM2 start; the window is created by the app itself at runtime.

Root cause is in bin/cli.js (~line 93):

const server = spawn('node', [serverPath], {
  cwd: standaloneDir,
  env,
  stdio: 'inherit',
});

The spawn options don't include windowsHide: true. Since the parent process tree (PM2 daemon) has no console to inherit, Windows allocates a new console for the child node next-server process — that's the visible window.

How This Feature Would Help

A headless option would let the control plane run under process managers (PM2, NSSM, Task Scheduler, Windows services) on Windows without spawning stray console windows — matching how it already behaves on Linux/macOS. Right now every PM2 restart/crash-recovery leaves a console window on the desktop unless the package is manually patched.

Proposed Solution

Add a --headless flag that suppresses any windowed child processes:

const server = spawn('node', [serverPath], {
  cwd: standaloneDir,
  env,
  stdio: 'inherit',
  windowsHide: true,   // always safe: stdio is 'inherit', so logs still flow
});

Honestly, windowsHide: true could also just be unconditional — the CLI already uses stdio: 'inherit' so there's no reason for the child to own a console. The flag would additionally make the intent explicit and cover any future child processes.

Alternatives Considered

  • Manually patching bin/cli.js in the global install to add windowsHide: true — this is my current workaround; it works perfectly, but gets wiped on every npm update -g / reinstall.
  • Running the PM2 daemon as a hidden Windows service (pm2-installer) — does not help, because the window is created by the app's own grandchild process, not by PM2's children.

Priority

Important - affects my workflow

Additional Context

  • Environment: Windows 10 19045, Node v22.22.2, PM2 6.0.14, @vectorize-io/hindsight-control-plane 1.1.0, hindsight-api 1.1.0
  • Everything else about the CLI works great under PM2 on Windows (signal handling, log piping, restart recovery) — this is the only rough edge.
  • Happy to send a PR if the one-line fix (or the flag) is acceptable.

Checklist

  • I would be willing to contribute this feature

Activity

  1. added a commit that references this issue on Oct 26, 2026
    35539b0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions