Skip to content

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 08 May 19:48

Added

  • Spawn correlation token: kill-fork-doesn't-kill-parent + auto-select after fork. Server now mints a UUIDv4 spawnToken per spawnPiSession() invocation, injects it as PI_DASHBOARD_SPAWN_TOKEN into the spawned pi's environment, and the bridge echoes it back in the first session_register. The headlessPidRegistry exposes a three-tier link — linkByToken (strong identity) → linkByPid (works for any bridge that sends pid) → linkSession (legacy cwd-FIFO fallback) — used by event-wiring.ts to resolve sessionId↔pid mappings deterministically. The pendingForkRegistry is keyed by token, eliminating the race where two same-cwd forks would mis-attribute parents. spawn-register-watchdog adds a third byToken index alongside byCwd and byPid. The browser protocol gains optional requestId (spawn_session, resume_session) echoed in spawn_result / resume_result, plus optional spawnRequestId on session_added so the client auto-selects the new session for both spawn AND fork — closing the long-standing UX gap where forks did not auto-navigate. All new fields are optional; old bridges, old clients, and old servers continue to work via the lower-tier matching fallbacks. (change: spawn-correlation-token)

Changed

Fixed

  • Killing a forked session no longer occasionally kills its parent. Pre-fix, headlessPidRegistry.linkSession(sessionId, cwd) resolved by first-unsessioned-in-cwd FIFO order, which could swap parent and fork sessionIds when the bridge connect order didn't match the dashboard's spawn order. The new three-tier link (token → pid → cwd-FIFO) makes the mapping race-free for any bridge that sends a pid in session_register (all current bridges do). (change: spawn-correlation-token)
  • Forking an empty session no longer hangs for 30 seconds with a generic timeout. Previously, forking a session whose .jsonl had not been written yet (e.g., a freshly spawned session before any message) caused pi --fork <missing-path> to crash silently — the wrapper sh -c "tail -f /dev/null | pi …" kept the parent process alive, so spawn-detached's 300ms crash check passed and the dashboard reported success: true. The bridge inside the dead pi never registered, so the spawn-register watchdog took 30 seconds to fire a generic "Pi started but never connected" banner. The dashboard now performs an existsSync preflight before fork. When the source has no persisted JSONL, the server silently degrades to a fresh spawn in the same cwd (inheriting the parent's attachedProposal if any) and surfaces the substitution via code: "FORK_DEGRADED_TO_NEW" plus a non-blocking toast ("Started a fresh session — the source had no persisted history to fork from."). For empty sources, fork's user-meaningful semantic is identical to a new session, so honoring intent beats refusing. Both the WS handler and the /api/session/:id/resume REST handler share the same logic. (change: fix-fork-empty-session-silent-timeout)

First-launch unblocking (unsigned binaries)

The Windows installers and macOS DMGs are not yet code-signed / notarized.
Both OSes will block first-launch with a security warning. These are not
malware — the artifacts are the exact ones produced by
.github/workflows/publish.yml
against this tag. Pick whichever workaround fits your workflow.

Tracking: Authenticode signing → change windows-authenticode-signing;
macOS notarization → change macos-notarization (planned). This section
will shrink and eventually disappear as each lands.

Windows — SmartScreen warning

SmartScreen will show "Windows protected your PC" the first time you
run any .exe artifact (Setup, portable, or any .exe extracted from a
ZIP).

Option A — at the SmartScreen dialog:

  1. Click More info.
  2. Click Run anyway.

Option B — pre-clear the Mark-of-the-Web:

  1. Right-click the downloaded .exe (or the .zip) → Properties.
  2. At the bottom of the General tab, tick Unblock next to
    "This file came from another computer...".
  3. Click OK and run as normal.

For ZIP archives, unblock the archive itself before extracting so
the contained .exes inherit the cleared zone.

macOS — Gatekeeper / quarantine

macOS will refuse to launch the app on first run with "PI Dashboard
cannot be opened because the developer cannot be verified"
or silently
quarantine it.

Option A — control-click the app:

  1. Open the DMG and drag PI Dashboard to Applications.
  2. In Applications, right-click (or Control-click) PI Dashboard →
    Open
    .
  3. Click Open in the confirmation dialog. Subsequent launches are
    unrestricted.

Option B — clear the quarantine attribute from the terminal:

xattr -d com.apple.quarantine "/Applications/PI Dashboard.app"

If the DMG itself is being blocked, clear it on the mounted volume
before copying:

xattr -d com.apple.quarantine "/Volumes/PI Dashboard/PI Dashboard.app"