[Windows] Three `detached: true` spawns missing `windowsHide` — telemetry flushSync opens a console window on nearly every CLI exit
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 78/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 冷清
- 技术栈
- node.js, typescript
- 领域
- cli
调研方向
Inspect the detached spawns in src/telemetry/transport.ts, src/utils/openBrowser.ts, and src/commands/previewLifecycle.ts, comparing their options with the existing windowsHide handling in src/utils/autoUpdate.ts. Verify on Windows that telemetry flushes, background preview, and browser launches no longer open console windows while preserving their existing detached behavior.
由索引模型根据 Issue 内容生成。
描述
Describe the bug
On Windows, console windows pop up during ordinary CLI use — not just during renders. This is a follow-up to #3379 (ffmpeg, fixed) and is distinct from #3430 (chrome-headless-shell, still open): those two cover console-subsystem binaries, whereas this one is about detached: true spawns of Node itself.
Node's docs are explicit about the mechanism:
On Windows, setting
options.detachedtotruemakes it possible for the child process to continue running after the parent exits. The child will have its own console window.
child_process.spawn() defaults windowsHide to false, so any detached: true spawn opens a visible console window on Windows unless windowsHide: true is passed.
Root cause
packages/cli v0.8.13 has four detached: true spawns. Three are missing windowsHide: true:
| Source | What it spawns | windowsHide |
|---|---|---|
src/telemetry/transport.ts (flushSync) |
node -e "fetch(...)" → PostHog |
❌ missing |
src/utils/openBrowser.ts (openBrowser) |
user's browser | ❌ missing |
src/commands/previewLifecycle.ts |
background preview server | ❌ missing |
src/utils/autoUpdate.ts |
update check | ✅ present |
autoUpdate.ts already gets this right, which makes the other three look like oversights rather than intent.
The worst offender: telemetry flushSync
flushSync() is the process-exit flush path. Because it can't await an HTTP POST during shutdown, it hands the payload to a detached Node process to deliver after the parent dies:
function flushSync() {
const payload = buildPayload(eventQueue);
if (payload == null) return;
eventQueue = [];
try {
const child = spawn(
process.execPath,
["-e", `fetch(${JSON.stringify(`${POSTHOG_HOST}/batch/`)},{...})`],
{ detached: true, stdio: "ignore" } // <-- no windowsHide
);
child.unref();
} catch {}
}
The strategy itself is sound — the only thing missing is windowsHide: true.
Impact is amplified by how the CLI is actually used. Agent-driven workflows invoke many short-lived commands (check, lint, keyframes, capture, snapshot, beats, preview), and each invocation that exits with queued events opens its own console window. My ~/.hyperframes/config.json shows commandCount: 1350, which is a lot of windows. Unlike #3430 this isn't render-only — it fires on nearly every command, including read-only ones.
Steps to reproduce
- On Windows, ensure telemetry is on (default):
telemetryEnabled: truein~/.hyperframes/config.json - Run any short command, e.g.
npx hyperframes check .ornpx hyperframes lint . - Watch the desktop/taskbar as the command exits — a console window flashes open
- Run several commands in sequence; you get one window per exit
Setting HYPERFRAMES_NO_TELEMETRY=1 (or DO_NOT_TRACK=1) makes the flashing stop, which isolates the telemetry spawn as the cause.
For the other two sites: hyperframes preview without --foreground spawns the detached background server (one window), and without --no-open spawns the browser via options.browserPath (one more).
Expected behavior
No console window appears for any of these background spawns.
Actual behavior
A console window opens per detached spawn — in the telemetry case, on nearly every CLI invocation.
Suggested fix
Add windowsHide: true at the three call sites, matching what autoUpdate.ts already does:
// src/telemetry/transport.ts
const child = spawn(process.execPath, ["-e", script], {
detached: true,
stdio: "ignore",
windowsHide: true,
});
// src/utils/openBrowser.ts
const child = spawn7(options.browserPath, args, {
detached: true,
stdio: "ignore",
windowsHide: true,
});
// src/commands/previewLifecycle.ts
child = spawn17(execPath, args, {
detached: true,
stdio: ["ignore", logFd, logFd],
env: process.env,
windowsHide: true,
});
windowsHide is a no-op on macOS/Linux, so it's safe to apply unconditionally — same rationale as the #3379 fix.
Given that #3379, #3430, and this issue are all the same class of defect, it may be worth a small shared spawn helper that applies windowsHide: true by default, plus a lint rule that flags a bare detached: true without it.
Environment
hyperframes 0.8.13 (latest)
Node.js v24.15.0 (win32 x64)
OS Microsoft Windows 10 Home 10.0.19045 (build 19045)
Install npx (_npx cache)
Additional context
Verified by static analysis of the shipped dist/cli.js in [email protected] — all four detached: true sites were inspected directly, along with every windowsHide occurrence. All ffmpeg/ffprobe spawns correctly carry windowsHide: true with the explanatory comment added by the #3379 fix, so that regression has not returned.
Related: #3379 (ffmpeg, closed/fixed) · #3430 (chrome-headless-shell, open)
- 主要语言
- TypeScript
- 星标
- 54.1k
- 派生
- 4.9k
- 平均合并
- 7 小时 2 分钟
- 30 天内合并 PR
- 782
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
heygen-com/hyperframes 的其他 Issue
-
难度 1/5 1 小时以内 新手友好度 84/100
heygen-com/hyperframes#5117 ·
维护者通常 1 天内回复
-
Docs: clarify that "Enable auto-update" is only available in the Claude Code terminal (CLI) /plugin UI可能已有人在做 @rumi7911 于 1 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 85/100
heygen-com/hyperframes#5027 ·
维护者通常 1 天内回复
-
fix(producer): propagate useGpu to HDR layered streaming encoder可能已有人在做 @Monster-GM 于 3 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 87/100
heygen-com/hyperframes#5002 ·
维护者通常 1 天内回复
-
skills: remoteHeadSha() can open a Git Credential Manager dialog on Windows (GIT_TERMINAL_PROMPT does not cover GUI helpers; slug unvalidated)可能已有人在做 @RaphaelFakhri 于 8 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
heygen-com/hyperframes#4702 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
Studio catalog prompt editor has no accessible name可能已有人在做 @lorenzozanee 于 14 天前认领。 未关闭bug difficulty/easy triage/ready
难度 2/5 1-3 小时 新手友好度 78/100
heygen-com/hyperframes#4384 ·
维护者通常 1 天内回复
查看 heygen-com/hyperframes 的全部 Issue
相似的 Issue
-
Tenant
难度 2/5 1-3 小时 新手友好度 66/100
MTES-MCT/Dossier-Facile-Frontend#2061 ·
维护者通常 1 天内回复
-
area:frontend
难度 2/5 1-3 小时 新手友好度 65/100
interledger/publisher-tools#905 ·
维护者通常 1 天内回复
-
approved check:passed streams:add
难度 2/5 1-3 小时 新手友好度 65/100
维护者通常 1 天内回复
-
DB-plane provider_chat_options.* is accepted by config set but never merged into the loaded config未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
area:web
难度 2/5 1-3 小时 新手友好度 82/100
praetorianer777/GoTome#178 ·
维护者通常 1 天内回复