Added
- Dynamic PWA manifest naming.
/manifest.jsonnow varies by origin. Default label derives fromHostheader →os.hostname()→"Pi-Dash"fallback, formatted asPi-Dash · <source>. OptionaldashboardNameconfig field + Settings → General → "PWA Display Name" input for user override. Distinguishes home-screen icons across multi-machine / tunnel installs. iOS Safari requires uninstall + re-add to pick up new name; Chrome/Edge/Android refresh within ~24h. (change:add-dynamic-pwa-manifest-naming) - Runtime bootstrap-install eliminated in all arms (Electron, standalone, bridge). pi/openspec/tsx are now regular dependencies of
@blackbelt-technology/pi-dashboard-server. Standalonenpm install -g @blackbelt-technology/pi-agent-dashboardbrings them in via npm itself — no first-run install delay, no~/.pi-dashboard/writes, noinstallable.json, nobootstrap_status_updateWS events. Electron ships them inside the immutable app bundle at<resourcesPath>/server/node_modules/; updates land via electron-updater whole-app replacement.jitiremains a direct dep of pi-dashboard-server; the bin wrapper resolves it from ownnode_modules. Servercli.tslogs[bootstrap] ready (pi resolved via <source>)on success and throws hard on failure. Pre-R3 modules removed:bootstrap-state,bootstrap-queue,bootstrap-install,bootstrap-install-from-list,installable-list,managed-workspace-materialize,managed-package-whitelist,BootstrapBanner,useBootstrapStatus,/api/bootstrap/*. Legacy~/.pi-dashboard/left untouched;detectLegacyManagedDir()surfaces a Doctor advisory only. The/api/pi-core/updatepath is retained for the standalone + bridge arms (where it has a writable target) and hidden under Electron via/api/health.launchSource === "electron". (change:eliminate-electron-runtime-install) - Mid-turn prompt queue. Typed-during-streaming messages now visibly queue above the input as chips (one per send), with a single "Clear all" affordance and a count badge on each session card. The bridge owns the queue per-session and drains it via
pi.sendUserMessageonagent_end. The 30-secondpendingPromptsafety timer is now queue-aware: it pauses while the prompt is observed in the queue, eliminating the false-positive "the prompt may not have been received" error that fired during long streaming turns. The input stays enabled while the agent is streaming so further sends accumulate naturally. Cancel actually cancels: clicking "Clear all" drops the bridge queue before pi ever sees the messages. (change:surface-mid-turn-prompt-queue) - Roles UI in Settings. Built-in plugin
@blackbelt-technology/pi-dashboard-builtins-plugincontributes asettings-sectionclaim under Settings → General → Roles. Edit per-session role-to-model maps, save/load/delete presets. Replaces the inline roles dropdown inside ModelSelector. Existing protocol untouched (role_set/role_preset_*). Third-party plugins can contribute additional roles UI via the same slot. (change:fix-pi-flows-end-to-end) - Plugin staleness banner.
/api/healthnow returnsbundleHash(sha256 of discovered plugin set). Client compares to embeddedPLUGIN_REGISTRY_HASH. Amber banner with Refresh button surfaces when hashes differ — remote browsers / zrok clients learn when their cached bundle is out of sync. Dismiss persists in sessionStorage. No new REST route or WS message. (change:fix-pi-flows-end-to-end) /api/health.plugins[]diagnostic fields. Each plugin entry gainsbridgeLoadedFrom: "packages[]" | "dashboardPluginBridges" | "none"(computed by re-reading~/.pi/agent/settings.json) and optionallastProbe: { status, peers, at }(from forwardedflows-anthropic-bridge:statusevents). Onecurl /api/healthnow diagnoses bridge load failures end-to-end. (change:fix-pi-flows-end-to-end)
Changed
- Subagent inspector now ships with
pi-dashboard-subagentsas the recommended producer. The dashboard drops specialized support for@tintinweb/pi-subagents— itsAgenttool calls now render via the generic tool renderer, and theget_subagent_result/steer_subagentspecialized renderers have been removed.pi-dashboard-subagentsis foreground-only, streams a full per-step timeline (tool calls, reasoning, assistant text), and is now bundled in the Electron installer for first-run availability. The companionsubagents-pluginprovides inline-expand and popout views for inspecting subagent runs. (change:add-subagent-inspector) - Plugin bridge registration dual-writes
packages[].registerPluginBridge/deregisterPluginBridgenow manage bothdashboardPluginBridges[dashboard-<id>](forward-compat) ANDpackages[]+ a_dashboardManagedPackagesownership map. pi-coding-agent 0.74 ignoresdashboardPluginBridgesand only loads extensions frompackages[]; previously this meant every bundled bridge plugin (notablyflows-anthropic-bridge) was effectively dead. One-shot reconciliation at server start heals pre-existing installs. Env escape hatch:PI_DASHBOARD_DISABLE_PLUGIN_BRIDGE_PACKAGES_WRITE=1. BREAKING for plugin authors who relied on the old write being a no-op. (change:fix-pi-flows-end-to-end) - Dashboard no longer claims
/flows*slash commands. Flow operations surface through buttons only (SessionFlowActionsRun/New/Edit/Delete,FlowDashboardAbort). pi-flows continues to register the slash commands for TUI users — no behavioral change for TUI hosts. (change:fix-pi-flows-end-to-end) useSelectedSessionIdplugin context hook. Plugins rendering in global surfaces (e.g.settings-section) can now reactively scope to the currently viewed session. (change:fix-pi-flows-end-to-end)
Fixed
- Electron cold-launch probe cascade. Four bugs broke packaged-Electron first-launch on machines without a system pi install, producing a silent splash-hang with no on-disk trace. (change:
fix-electron-cold-launch-probe-cascade)- piExtension probe always returned null.
probePiExtensioninpackages/electron/src/lib/launch-source.tsreadsettings.extensions— a non-existent field in pi's settings schema. Fixed: probe now walkssettings.packages[]via newlistPiPackages(opts)export in@blackbelt-technology/pi-dashboard-shared/pi-package-resolver.js, returningResolvedPiPackage[]deduped bypackageDiracross user + project scopes. pi-dashboard --versionrequired jiti.packages/server/bin/pi-dashboard.mjspreviously resolved jiti even for--version, breaking version probes when managed dir was empty. Fixed:--version/-v/versionshort-circuit reads siblingpackage.jsonand exits 0 without resolving jiti.- Launch-source diagnostics lost on
.desktoplaunch.console.warn/console.errorfrom probes went to stderr, which packaged-Electron.desktoplaunches discard, leaving no post-mortem trail. Fixed: newlogLaunchSource()+appendDashboardLog()helpers dual-write to~/.pi/dashboard/server.logwith[<ts>] [launch-source] ...prefix; all 8 console-write sites routed through the helper. extractBundleselective-wipe silently disabled.buildExtractedSourcepassed anextractFswith no-op overrides formkdirSync/readdirSync/rmSync/statSync, so the selective-wipe step insideextractBundlenever ran. Stale absolute symlinks under~/.pi-dashboard/node_modules/.../node_modules/.bin/Xpointing back at a vanished<resourcesPath>/server/producedERR_FS_CP_EINVALon every cold launch. Fixed:extractFsshape narrowed toPartial<ExtractFs>, no-op overrides dropped;buildFsnow fills real-fs defaults for destructive operations. Self-healing for any user's corrupt managed dir.
- piExtension probe always returned null.
@pi/anthropic-messages0.3.0 widens the gate. Activation no longer requires the model id to match/claude/i. Anymodel.api === "anthropic-messages"session opens the gate — covers OAuth + API-key + proxy providers (9Router, custom OpenAI-compatible bases) that route to Anthropic but report non-Claude model ids.PI_ANTHROPIC_MESSAGES_FORCE_CANONICALnow overridesmodel.apitoo.isClaudeAnthropicMessageskept as deprecated alias for one minor. (change:fix-pi-flows-end-to-endGroup 4)- pi-flows 0.2.0 abort race.
flow-execution.tsparallel agent batch now wrapsPromise.allwithraceWithAbort. Parent flow unwinds within ~10 ms of AbortSignal firing instead of waiting for every in-flight child to observe the signal at its own iteration boundary. Pending children still callsession.abort()on themselves; cancelled results synthesized so observers (TUI, dashboard) render accurate per-agent state. Repo-lint forbids newspawnAgentcalls without explicitsignal:. (change:fix-pi-flows-end-to-endGroup 3) - Linux x64 AppImage maker fixed. Three bugs blocked every linux-x64 Electron release.
@pengx17/electron-forge-maker-appimage@1.2.1calledexecSyncwithoutstdio: 'inherit'—patch-apprun.sh's stdout (every file from--appimage-extractpluswget+appimagetool) overflowed Node's 1 MB default stdio buffer, throwingspawnSync /bin/sh ENOBUFS. Patched viapatch-packageto stream child output instead of buffering. Newerappimagetoolbuilds also requireARCH=<uname-m>explicitly;packages/electron/scripts/patch-appimage-fix.shnow passesARCH="$SYSTEM_ARCH"alongsideAPPIMAGE_EXTRACT_AND_RUN=1. Linux-x64 AppImage and DEB artifacts now publish reliably from the Release workflow. - Standalone
npm installpostinstall guard.patch-packageis wired into the rootpostinstallbut it's a devDep — end-users runningnpm install --omit=devagainst the published tarball had neitherpatch-packagenor apatches/directory, producingsh: 1: patch-package: not found(exit 127). Fix: tiny CJS wrapperscripts/maybe-patch-package.cjsno-ops unless bothpatches/and a resolvablepatch-packagepackage.json exist; included in the published root tarball viafiles[]. Cross-platform (Linux / Windows / macOS) viarequire.resolve+spawnSync, no shell tooling. - Windows standalone-install spawn bugs (3).
jitiURL handling,.cmdEFTYPEon shell-less spawn, and missingnodeprefix in spawn argv all brokenpm install -g @blackbelt-technology/pi-agent-dashboardon Windows. CI gained astandalone-install-smoke-windowsmatrix leg covering Node 22/24/25 to keep regressions from hiding again. (change:fix-windows-standalone-install-spawn-bugs) - Windows System32 PATH ensurance + bundled-Node dir resolution. Electron child-process spawns on Windows sometimes saw a
PATHmissing System32 / Wbem / WindowsApps when launched from File Explorer (launchctl-equivalent context), breakingwhere,cmd /c, and bundled-Node resolution. New shared helperensureWindowsSystemPathprepends the canonical Windows system dirs when missing; resolved bundled-Node directory is now stable across launch contexts. POSIX is a no-op. (change:fix-windows-path-system32-missing) - Wizard occluded by splash on Windows first-run. On Windows, the Electron splash window covered the welcome wizard on first launch, freezing the user behind an undismissible splash. Splash now closes before the wizard is shown; wizard receives focus and is brought to front. (change:
fix-wizard-occluded-by-splash) node-ptybumped to 1.2.0-beta.13. Adds Linux prebuilds (x64 + arm64) so@blackbelt-technology/pi-dashboard-serverno longer falls back to source-compile on Linux installs that lack a C++ toolchain. Companion jiti hygiene fixes for the bin wrapper.- Recovery HTTP server on missing top-level deps. When the bundled server can't resolve a critical top-level dependency at startup, the launcher now degrades to a minimal HTTP server that serves a diagnostic page +
/api/doctorinstead of silently failing. Pi sessions are unavailable but the user can see what's wrong and reinstall. (change:add-startup-recovery-server) - CI Electron on-demand build workflow. New
CI Electron (on-demand)workflow (.github/workflows/ci-electron.yml) builds the full 6-leg Electron installer matrix (darwin arm64/x64, linux arm64/x64, win32 arm64/x64) without publishing to npm or creating a GitHub Release. Use to smoke-test packaging changes on feature branches without burning a SemVer slot. Version slug shape:<base>-ci.<UTC-stamp>.<branch-slug>.<sha7>, ranked below the base stable so accidental releases don't reach electron-updater clients with defaultallowPrerelease: false. (change:add-ci-electron-on-demand-build)
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:
- Click More info.
- Click Run anyway.
Option B — pre-clear the Mark-of-the-Web:
- Right-click the downloaded
.exe(or the.zip) → Properties. - At the bottom of the General tab, tick Unblock next to
"This file came from another computer...". - 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:
- Open the DMG and drag PI Dashboard to Applications.
- In Applications, right-click (or Control-click) PI Dashboard →
Open. - 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"