Skip to content

feat: Windows desktop support (window config, no console flashes, cross-platform paths) - #158

Merged
RealZST merged 15 commits into
RealZST:mainfrom
XiaoLrrr:windows-desktop
Oct 24, 2026
Merged

RealZST merged 15 commits into
RealZST:mainfrom
XiaoLrrr:windows-desktop

Conversation

@XiaoLrrr

@XiaoLrrr XiaoLrrr commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds first-class Windows desktop support plus Windows compatibility fixes across the core, desktop and web crates. Rebased onto current upstream main (v1.14.0).

Changes (4 commits)

  1. fix: suppress console window flashes on Windows subprocess spawns

    • New hk_core::command() sets CREATE_NO_WINDOW on Windows.
    • Route all subprocess spawns (git / where / npm probing) through it, so no conhost.exe windows flash when the GUI probes for CLIs.
  2. feat: add Windows desktop support (window config + close behavior)

    • crates/hk-desktop/tauri.windows.conf.json so Windows builds don't inherit the macOS-only transparent window / vibrancy styling.
    • Platform-aware close behavior: macOS keeps hide-on-close, Windows/Linux quit on close.
    • Add Tauri CLI devDependency for local desktop builds.
  3. fix(windows): resolve home dir via HARNESSKIT_HOME + cross-platform path/test fixes

    • Add hk_core::home_dir() honoring HARNESSKIT_HOME (falls back to dirs::home_dir()), enabling home isolation in Windows tests.
    • Route adapters, sanitize, scanner, skills_cli through crate::home_dir().
    • openclaw: treat root-relative paths (e.g. /srv/claw) as resolved on Windows.
    • Cross-platform path assertions and cmd /c launcher shims; fix the hk-web path-allowlist test on Windows.
  4. fix(windows): route remaining git spawns and data dir through hk_core helpers

    • hk-web install handlers: use hk_core::command(git) (CREATE_NO_WINDOW) for clone/probe instead of std::process::Command.
    • hk-desktop / hk-web / hk-cli: resolve ~/.harnesskit via hk_core::home_dir().
    • Kits test compares against crate::home_dir() so HARNESSKIT_HOME isolation works.

Testing

  • cargo check for hk-core, hk-web, hk-desktop, hk-cli — pass (warnings only)
  • cargo test -p hk-core --lib — 728 passed
  • cargo test -p hk-web — 12 passed (incl. previously failing allowlist test)
  • Windows desktop app built/run locally: standard title bar, no transparent overlap, no console flashes

…ath/test fixes

- add hk_core::home_dir() honoring HARNESSKIT_HOME (falls back to dirs::home_dir)

- route adapters, sanitize, scanner, skills_cli through crate::home_dir()

- openclaw: treat root-relative paths as resolved on Windows

- make path assertions and launcher shims cross-platform; fix hk-web allowlist test
@XiaoLrrr XiaoLrrr changed the title feat: Windows desktop support + no console flashes feat: Windows desktop support (window config, no console flashes, cross-platform paths) Oct 19, 2026
… helpers

- hk-web install handlers: use hk_core::command(git) (CREATE_NO_WINDOW) for clone/probe
- hk-desktop/hk-web/hk-cli: resolve ~/.harnesskit via hk_core::home_dir()
- kits test: compare against crate::home_dir() for HARNESSKIT_HOME isolation
@XiaoLrrr

Copy link
Copy Markdown
Contributor Author

@RealZST 你好,这个 PR 已基于最新上游 main(v1.14.0,9098728)重新构建并做了实机验证,麻烦帮忙 review 一下,谢谢 🙏

  • 分支 windows-desktop @ 79a7b4c,共 4 个提交(基于 9098728)
  • CI 全绿:test / CodeQL / analyze (javascript-typescript) 均通过
  • 本机实机验证:Windows 桌面版构建成功、正常启动运行;cargo test --workspace 778 passed,前端 vitest 358 passed
  • NSIS 安装包(含 WebView2Loader.dll)已在本机静默安装并启动验证通过

主要变更:Windows 桌面窗口配置与关窗行为、子进程加 CREATE_NO_WINDOW 消除控制台闪窗、home_dir 统一走 HARNESSKIT_HOME 及跨平台路径/测试修复。

@RealZST

RealZST commented Oct 19, 2026

Copy link
Copy Markdown
Owner

@RealZST 你好,这个 PR 已基于最新上游 main(v1.14.0,9098728)重新构建并做了实机验证,麻烦帮忙 review 一下,谢谢 🙏

  • 分支 windows-desktop @ 79a7b4c,共 4 个提交(基于 9098728)
  • CI 全绿:test / CodeQL / analyze (javascript-typescript) 均通过
  • 本机实机验证:Windows 桌面版构建成功、正常启动运行;cargo test --workspace 778 passed,前端 vitest 358 passed
  • NSIS 安装包(含 WebView2Loader.dll)已在本机静默安装并启动验证通过

主要变更:Windows 桌面窗口配置与关窗行为、子进程加 CREATE_NO_WINDOW 消除控制台闪窗、home_dir 统一走 HARNESSKIT_HOME 及跨平台路径/测试修复。

感谢PR!我会尽快处理,之前手边没有Windows,这周末我会review,实机测试和release。再次感谢!

RealZST and others added 8 commits October 24, 2026 13:35
The repository drives Tauri through `cargo tauri` (CONTRIBUTING.md and
release.yml both `cargo install tauri-cli`), so the npm CLI added with the
Windows window config is never invoked. Restore package.json and
package-lock.json to their state on main.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`CREATE_NO_WINDOW` gives the child no console at all (Win32 docs: "the
console handle for the application is not set"), so under the `hk` CLI or
`hk serve` a child that needs the terminal, such as `git` prompting for
credentials or `ssh` confirming a host key, could no longer prompt and would
fail. Those console programs never flashed a window in the first place: their
children inherit the existing console.

Keep the shared `hk_core::command()` entry point but make the flag an opt-in
(`hk_core::process::hide_console_windows()`) that the Tauri desktop app, the
one GUI process, calls at startup.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… end

The guard that undoes the test home put the *original HOME* back into
`HARNESSKIT_HOME` (and `USERPROFILE`) instead of each variable's own previous
value, so after the first kit test the override stayed set for the rest of
the process. The two end_to_end tests still set only `HOME`, which
`dirs::home_dir()` ignores on Windows, so they wrote kit zips into the real
`~/.harnesskit/kits/` there.

`RestoreHome` now records and restores `HOME` and `HARNESSKIT_HOME`
separately, every kit test goes through `set_test_home`, and the
`USERPROFILE` handling is dropped: dirs-sys resolves the Windows home via
`SHGetKnownFolderPath(FOLDERID_Profile)` and never reads that variable.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`list_skill_files_rejects_file_outside_allowed_roots` set `HARNESSKIT_HOME`
from inside a test binary whose other tests run on parallel threads and
construct adapters (which read that variable), and never unset it. Rust 2024
marks `set_var` unsafe for exactly this reason.

Carry the home directory in `WebState` (`hk_core::home_dir()` in `serve`,
a fixture sibling in tests) and pass it to `is_path_allowed`. The test keeps
its Windows coverage, where the OS temp dir sits under the user profile,
without touching the process environment.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`Some(x).unwrap_or_else(...)` left over from replacing `dirs::home_dir()`
(which returned an Option) with the infallible `crate::home_dir()`; extra
blank lines in scanner.rs, copilot.rs and skills_cli.rs; missing final
newline in lib.rs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Same steps as the macOS job on a windows-2025 runner, so the cross-platform
path, process and home-directory handling added for the Windows desktop
build is exercised on every pull request rather than only on a
contributor's machine.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…verride

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`kits_dir_is_under_home` and the two `~` expansion tests in sanitize.rs read
the home twice per run while the kit tests, on other threads, swap it out
and back. They already raced on `HOME` on Unix; with `HARNESSKIT_HOME` in
play on every platform, take the same `kit_env` lock.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
RealZST and others added 3 commits October 24, 2026 16:17
…ktop

The page keeps html/body transparent and lays a 25% sidebar tint over it,
which only looks right when the OS paints vibrancy behind the window. The
Windows window is opaque (`tauri.windows.conf.json`), so in dark mode the
tint sat on a white canvas and the sidebar came out washed out. The web
build already paints the canvas via a `data-web` attribute; generalize it
to `data-no-vibrancy`, set whenever the build is not the macOS desktop
(`isDesktop() && isMac()`, with `isMac()` new in transport.ts).

Also set `overscroll-behavior: none` on the root: the page never scrolls
as a whole, and WebView2 otherwise rubber-bands the entire window on a
horizontal trackpad swipe.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`set_app_icon` swaps the Dock icon through AppKit; on every other platform
the command is a no-op that still reports success, so the Windows desktop
showed a picker that did nothing. Windows has no runtime equivalent (the
Start menu and shortcut icons come from the executable), so hide the
setting, and the startup restore, outside the macOS desktop instead of
pretending.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With "Transparency effects" on, Windows 11 paints every window's caption
with Mica, a tint derived from the desktop wallpaper, which clashes with
the app's palette (a blue bar over a warm theme). An explicit caption color
(`DWMWA_CAPTION_COLOR` / `DWMWA_TEXT_COLOR`, Windows 11 build 22000+) opts
the window out of that tint whatever the user's transparency setting.

New `set_title_bar_color` command (no-op outside Windows); the frontend
calls it from the theme effect with the sidebar color as it actually
renders (`bg-sidebar/25` over the canvas) and the sidebar foreground, so
the title bar reads as part of the sidebar and follows theme changes.
Windows 10 rejects the attributes and has no Mica either; the result is
ignored.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@RealZST
RealZST merged commit 348ca97 into RealZST:main Oct 24, 2026
4 checks passed
@RealZST

RealZST commented Oct 24, 2026

Copy link
Copy Markdown
Owner

感谢 PR!代码我过了一遍,也在 Windows 11 上安装实测了,在你的 4 个 commit 之上又推了下面这些:

  • e3ad10e:删掉 package.json 里的 @tauri-apps/cli。仓库用的是 Rust 版的 cargo tauri,这个 npm 版装了没有用到。
  • c18ba31:CREATE_NO_WINDOW 改成只在桌面版启动时开启,命令行版 hk 保持原来的行为。命令行在终端里运行没有黑框问题,而且加上这个标记后 git 无法弹出用户名密码的提示。
  • 1f249be:调整了 kits 测试里恢复环境变量的方式。之前 HARNESSKIT_HOME 恢复的是 HOME 的旧值,测试跑完后会留在进程里;end_to_end 里两个测试也顺手改成同样的写法,这样 Windows 上也不会碰到真实的 ~/.harnesskit。
  • fa5bec6:hk-web 的路径检查测试改成把目录当参数传进去,不再修改环境变量。测试是并行的,改环境变量会互相影响。
  • fa2dc41:清理几处多余的代码和空行。
  • a4b4df7:PR 检查增加 Windows 环境,以后每个 PR 都会在 Windows 上编译并跑完整测试。
  • 513810e:更新 CONTRIBUTING,桌面开发不再标注 macOS only,并注明 HARNESSKIT_HOME 仅用于测试。
  • fcbb2d6:另外三个测试改为和 kits 测试串行执行。它们会读两次 home 目录,并行时可能读到不一致的值而偶发失败。
  • c90a204:修复深色模式下左侧栏发白的问题,以及触控板横向滑动时整个页面晃动回弹的问题。
  • c1c6b06:Windows 桌面端的设置里去掉了「应用图标」这一项,这一项之前换的是 macOS 的 Dock 图标,Windows 没有对应的机制,点了会没有效果。
  • 12c6ddf:Windows 11 开启「透明效果」后标题栏会被系统染成壁纸的颜色,和应用主题不协调。现在标题栏使用侧栏的颜色,并随主题切换。

Windows 11 上的效果,两套主题light和dark:
image
image
image
image

如果你那边运行时有和预期不一致的地方,欢迎再提issue

Merged. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants