What happened?
Running an agent task inside the desktop app periodically restarts the desktop (and on v0.19.2 it crashed/hung the app). The trigger is the agent's own tool calls that invoke the packaged Open Design CLI via $env:OD_BIN (e.g. tools live-artifacts list, tools live-artifacts create, export template.html). Each CLI invocation launches a new Open Design.exe instance, which enters the launcher's single-instance gate (inspectExistingDesktopForLauncher). When the already-running desktop reports windowVisible: false, the gate classifies it as headless-owner and kills + restarts the desktop (action=restart reason=headless-owner). When the window happens to be visible it just focuses (focus=accepted) — so the behavior alternates between "app randomly restarts" and "harmless focus flash" depending on window visibility at the moment of each agent tool call.
On v0.19.2 the same restart path hit the EPIPE: broken pipe, write fatal-uncaught-exception bug and the app hung (WER AppHangB1). On v0.20.0 the EPIPE issue is fixed but the self-restart behavior remains.
Steps to reproduce
- On Windows, install Open Design (reproduced on 0.19.2 and 0.20.0), open a project with a
template.html + data.json + artifact.json (a "live artifact").
- In a conversation, send an agent task whose prompt makes the agent register/verify/export the live artifact (e.g. "注册可刷新 artifact 并验证预览" / "register refreshable artifact and verify preview").
- Watch the agent run: it executes commands like:
& $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts list --format compact
& $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts create --input artifact.json
& $env:OD_NODE_BIN $env:OD_BIN export template.html --project ...
- When the desktop window is not visible at that instant (minimized/hidden/still starting), the desktop is shut down and restarted (
headless-owner). With the window visible, only a focus handoff happens.
Expected behavior
Agent-internal CLI calls ($env:OD_BIN tools ..., $env:OD_BIN export ...) should run in a pure CLI/headless mode and must not re-enter the desktop single-instance gate, so they never shut down or restart the running desktop. The single-instance "headless-owner" restart should not be triggered by the app's own agent tooling.
OpenDesign version
0.20.0 (stable, Windows; reproduced on 0.19.2 as a hang). Electron 41.3.0, packaged payload under %APPDATA%\Open Design\launcher\channels\stable\namespaces\release-stable-win\versions\0.20.0.
Platform
Windows (Win64, zh-CN)
Logs (evidence)
Launcher gate log …\logs\launcher\after-quit.log — every restart/focus event aligns within ~0.2 s of an agent OD_BIN call:
2026-08-20T03:17:57.461Z inspect-found-existing namespace=release-stable-win action=restart reason=headless-owner pid=23496
2026-08-20T03:18:01.684Z inspect-found-existing namespace=release-stable-win shutdown=exited reason=headless-owner pid=23496
2026-08-20T03:22:09.855Z inspect-found-existing namespace=release-stable-win action=restart reason=headless-owner pid=41904
2026-08-20T03:22:14.876Z inspect-found-existing namespace=release-stable-win shutdown=timed-out reason=headless-owner pid=41904
2026-08-20T03:22:14.885Z force-stop headless-owner pid=41904 outcome=sigterm
2026-08-20T03:27:22.993Z inspect-found-existing namespace=release-stable-win focus=accepted
2026-08-20T03:27:28.927Z inspect-found-existing namespace=release-stable-win focus=accepted
2026-08-20T03:27:44.026Z inspect-found-existing namespace=release-stable-win focus=accepted
Agent run events …\data\runs\<runId>\events.jsonl — the tool calls at the same instants:
[11:17:57.282] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts list --format compact → restart at 11:17:57.461
[11:22:09.665] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts list --format compact → restart at 11:22:09.855
[11:27:22.704] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts create --input artifact.json → focus at 11:27:22.993
[11:27:28.627] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts list --format compact → focus at 11:27:28.927
[11:27:43.732] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN tools live-artifacts create --input artifact.json → focus at 11:27:44.026
[11:28:05.161] tool_use Bash: & $env:OD_NODE_BIN $env:OD_BIN export template.html --project ... → further launches
On 0.19.2 the same restart path produced a fatal hang — …\logs\desktop\latest.log:
{"level":"error","message":"packaged desktop fatal uncaught exception","timestamp":"2026-08-20T03:05:20.342Z","meta":{"error":{"message":"EPIPE: broken pipe, write", ... "at console.info (file:///.../packaged-main.mjs:29766:31)"}}}
Additional context / suspected root cause
- Gate logic:
apps/packaged/src/launcher-after-quit.ts — inspectExistingDesktopForLauncher() restarts when status.windowVisible === false (line 263-282, reason: "headless-owner").
- Every packaged entry runs this gate:
apps/packaged/src/index.ts (main) calls waitForLauncherAfterQuit + inspectExistingDesktopForLauncher (lines 142-161) before dispatching to CLI/headless mode — CLI invocations of the same executable are not distinguished from a user double-launch.
- Desktop status visibility:
apps/desktop/src/main/runtime.ts status() → windowVisible: !window.isDestroyed() && window.isVisible().
- Agent env includes
OD_BIN / OD_NODE_BIN / OD_DAEMON_URL / OD_TOOL_TOKEN (see shell_environment_policy.include_only in the agent spawn), and the agent calls the CLI to register/refresh/export live artifacts — a core workflow for the built-in agent.
Suggested fix directions: route agent-internal CLI calls to the daemon/web IPC instead of spawning the packaged executable; or have the launcher gate treat argv without a desktop/stamp marker (pure CLI invocations) as action=continue without the headless-owner restart; or make the CLI entry bypass the desktop single-instance gate entirely.
Timeline note: restarts occurred at 11:05 (0.19.2, EPIPE hang), 11:17:57, 11:22:09 (0.20.0, clean restart), 11:27:22/28/44 (0.20.0, focus only) — each correlated 1:1 with an agent run (data/runs/*).
What happened?
Running an agent task inside the desktop app periodically restarts the desktop (and on v0.19.2 it crashed/hung the app). The trigger is the agent's own tool calls that invoke the packaged Open Design CLI via
$env:OD_BIN(e.g.tools live-artifacts list,tools live-artifacts create,export template.html). Each CLI invocation launches a newOpen Design.exeinstance, which enters the launcher's single-instance gate (inspectExistingDesktopForLauncher). When the already-running desktop reportswindowVisible: false, the gate classifies it asheadless-ownerand kills + restarts the desktop (action=restart reason=headless-owner). When the window happens to be visible it just focuses (focus=accepted) — so the behavior alternates between "app randomly restarts" and "harmless focus flash" depending on window visibility at the moment of each agent tool call.On v0.19.2 the same restart path hit the
EPIPE: broken pipe, writefatal-uncaught-exception bug and the app hung (WERAppHangB1). On v0.20.0 the EPIPE issue is fixed but the self-restart behavior remains.Steps to reproduce
template.html+data.json+artifact.json(a "live artifact").headless-owner). With the window visible, only a focus handoff happens.Expected behavior
Agent-internal CLI calls (
$env:OD_BIN tools ...,$env:OD_BIN export ...) should run in a pure CLI/headless mode and must not re-enter the desktop single-instance gate, so they never shut down or restart the running desktop. The single-instance "headless-owner" restart should not be triggered by the app's own agent tooling.OpenDesign version
0.20.0 (stable, Windows; reproduced on 0.19.2 as a hang). Electron 41.3.0, packaged payload under
%APPDATA%\Open Design\launcher\channels\stable\namespaces\release-stable-win\versions\0.20.0.Platform
Windows (Win64, zh-CN)
Logs (evidence)
Launcher gate log
…\logs\launcher\after-quit.log— every restart/focus event aligns within ~0.2 s of an agentOD_BINcall:Agent run events
…\data\runs\<runId>\events.jsonl— the tool calls at the same instants:On 0.19.2 the same restart path produced a fatal hang —
…\logs\desktop\latest.log:Additional context / suspected root cause
apps/packaged/src/launcher-after-quit.ts—inspectExistingDesktopForLauncher()restarts whenstatus.windowVisible === false(line 263-282,reason: "headless-owner").apps/packaged/src/index.ts(main) callswaitForLauncherAfterQuit+inspectExistingDesktopForLauncher(lines 142-161) before dispatching to CLI/headless mode — CLI invocations of the same executable are not distinguished from a user double-launch.apps/desktop/src/main/runtime.tsstatus()→windowVisible: !window.isDestroyed() && window.isVisible().OD_BIN/OD_NODE_BIN/OD_DAEMON_URL/OD_TOOL_TOKEN(seeshell_environment_policy.include_onlyin the agent spawn), and the agent calls the CLI to register/refresh/export live artifacts — a core workflow for the built-in agent.Suggested fix directions: route agent-internal CLI calls to the daemon/web IPC instead of spawning the packaged executable; or have the launcher gate treat argv without a desktop/stamp marker (pure CLI invocations) as
action=continuewithout the headless-owner restart; or make the CLI entry bypass the desktop single-instance gate entirely.Timeline note: restarts occurred at 11:05 (0.19.2, EPIPE hang), 11:17:57, 11:22:09 (0.20.0, clean restart), 11:27:22/28/44 (0.20.0, focus only) — each correlated 1:1 with an agent run (
data/runs/*).